mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
Bug 1529345 - Part 2: Add Gecko infrastructure for receiving notifications about debugger-related events. r=jimb,smaug
Differential Revision: https://phabricator.services.mozilla.com/D30565 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
6edbe83c24
commit
a1de03c27b
@ -44,6 +44,8 @@ auto MAXBYTE;
|
||||
auto MAXWORD;
|
||||
auto MAXDWORD;
|
||||
|
||||
auto ERROR;
|
||||
|
||||
auto DELETE;
|
||||
auto READ_CONTROL;
|
||||
auto WRITE_DAC;
|
||||
|
@ -17,8 +17,10 @@
|
||||
#include "nsHistory.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
#include "nsIDOMStorageManager.h"
|
||||
#include "mozilla/dom/CallbackDebuggerNotification.h"
|
||||
#include "mozilla/dom/ContentFrameMessageManager.h"
|
||||
#include "mozilla/dom/CSPEvalChecker.h"
|
||||
#include "mozilla/dom/DebuggerNotification.h"
|
||||
#include "mozilla/dom/DocumentInlines.h"
|
||||
#include "mozilla/dom/DOMJSProxyHandler.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
@ -1370,6 +1372,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindowInner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVRDisplays)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)
|
||||
|
||||
// Traverse stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChromeEventHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParentTarget)
|
||||
@ -1468,6 +1472,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindowInner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVRDisplays)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)
|
||||
|
||||
// Unlink stuff from nsPIDOMWindow
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChromeEventHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParentTarget)
|
||||
@ -3289,6 +3295,9 @@ int32_t nsGlobalWindowInner::RequestAnimationFrame(
|
||||
js::NotifyAnimationActivity(GetWrapperPreserveColor());
|
||||
}
|
||||
|
||||
DebuggerNotificationDispatch(this,
|
||||
DebuggerNotificationType::RequestAnimationFrame);
|
||||
|
||||
int32_t handle;
|
||||
aError = mDoc->ScheduleFrameRequestCallback(aCallback, &handle);
|
||||
return handle;
|
||||
@ -3300,6 +3309,9 @@ void nsGlobalWindowInner::CancelAnimationFrame(int32_t aHandle,
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerNotificationDispatch(this,
|
||||
DebuggerNotificationType::CancelAnimationFrame);
|
||||
|
||||
mDoc->CancelFrameRequestCallback(aHandle);
|
||||
}
|
||||
|
||||
@ -3730,12 +3742,16 @@ void nsGlobalWindowInner::MozScrollSnap() {
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::ClearTimeout(int32_t aHandle) {
|
||||
DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout);
|
||||
|
||||
if (aHandle > 0) {
|
||||
mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::ClearInterval(int32_t aHandle) {
|
||||
DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval);
|
||||
|
||||
if (aHandle > 0) {
|
||||
mTimeoutManager->ClearTimeout(aHandle, Timeout::Reason::eTimeoutOrInterval);
|
||||
}
|
||||
@ -4003,6 +4019,20 @@ EventListenerManager* nsGlobalWindowInner::GetExistingListenerManager() const {
|
||||
return mListenerManager;
|
||||
}
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
nsGlobalWindowInner::GetOrCreateDebuggerNotificationManager() {
|
||||
if (!mDebuggerNotificationManager) {
|
||||
mDebuggerNotificationManager = new DebuggerNotificationManager(this);
|
||||
}
|
||||
|
||||
return mDebuggerNotificationManager;
|
||||
}
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
nsGlobalWindowInner::GetExistingDebuggerNotificationManager() {
|
||||
return mDebuggerNotificationManager;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsGlobalWindowInner::nsPIDOMWindow
|
||||
//*****************************************************************************
|
||||
@ -5758,10 +5788,15 @@ int32_t nsGlobalWindowInner::SetTimeoutOrInterval(
|
||||
}
|
||||
|
||||
if (inner != this) {
|
||||
return inner->SetTimeoutOrInterval(aCx, aFunction, aTimeout, aArguments,
|
||||
aIsInterval, aError);
|
||||
RefPtr<nsGlobalWindowInner> innerRef(inner);
|
||||
return innerRef->SetTimeoutOrInterval(aCx, aFunction, aTimeout, aArguments,
|
||||
aIsInterval, aError);
|
||||
}
|
||||
|
||||
DebuggerNotificationDispatch(
|
||||
this, aIsInterval ? DebuggerNotificationType::SetInterval
|
||||
: DebuggerNotificationType::SetTimeout);
|
||||
|
||||
if (!GetContextInternal() || !HasJSGlobal()) {
|
||||
// This window was already closed, or never properly initialized,
|
||||
// don't let a timer be scheduled on such a window.
|
||||
@ -5796,10 +5831,15 @@ int32_t nsGlobalWindowInner::SetTimeoutOrInterval(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (inner != this) {
|
||||
return inner->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aIsInterval,
|
||||
aError);
|
||||
RefPtr<nsGlobalWindowInner> innerRef(inner);
|
||||
return innerRef->SetTimeoutOrInterval(aCx, aHandler, aTimeout, aIsInterval,
|
||||
aError);
|
||||
}
|
||||
|
||||
DebuggerNotificationDispatch(
|
||||
this, aIsInterval ? DebuggerNotificationType::SetInterval
|
||||
: DebuggerNotificationType::SetTimeout);
|
||||
|
||||
if (!GetContextInternal() || !HasJSGlobal()) {
|
||||
// This window was already closed, or never properly initialized,
|
||||
// don't let a timer be scheduled on such a window.
|
||||
@ -5857,8 +5897,17 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
|
||||
reason = "setTimeout handler";
|
||||
}
|
||||
|
||||
RefPtr<TimeoutHandler> handler(timeout->mScriptHandler);
|
||||
bool abortIntervalHandler = !handler->Call(reason);
|
||||
bool abortIntervalHandler;
|
||||
{
|
||||
RefPtr<TimeoutHandler> handler(timeout->mScriptHandler);
|
||||
|
||||
CallbackDebuggerNotificationGuard guard(
|
||||
this, timeout->mIsInterval
|
||||
? DebuggerNotificationType::SetIntervalCallback
|
||||
: DebuggerNotificationType::SetTimeoutCallback);
|
||||
abortIntervalHandler = !handler->Call(reason);
|
||||
}
|
||||
|
||||
// If we received an uncatchable exception, do not schedule the timeout again.
|
||||
// This allows the slow script dialog to break easy DoS attacks like
|
||||
// setInterval(function() { while(1); }, 100);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "prclist.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ChromeMessageBroadcaster.h"
|
||||
#include "mozilla/dom/DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/NavigatorBinding.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/StorageEventBinding.h"
|
||||
@ -284,6 +285,12 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
|
||||
virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
|
||||
|
||||
mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
|
||||
GetDebuggerNotificationType() const override {
|
||||
return mozilla::Some(
|
||||
mozilla::dom::EventCallbackDebuggerNotificationType::Global);
|
||||
}
|
||||
|
||||
bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
|
||||
|
||||
virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override;
|
||||
@ -317,6 +324,12 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
virtual bool IsFrozen() const override;
|
||||
void SyncStateFromParentWindow();
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
GetOrCreateDebuggerNotificationManager() override;
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
GetExistingDebuggerNotificationManager() override;
|
||||
|
||||
mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const override;
|
||||
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
|
||||
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController()
|
||||
@ -681,23 +694,35 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
const mozilla::dom::WindowPostMessageOptions& aOptions,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
|
||||
int32_t aTimeout,
|
||||
const mozilla::dom::Sequence<JS::Value>& aArguments,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
|
||||
int32_t aTimeout,
|
||||
const mozilla::dom::Sequence<JS::Value>& /* unused */,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ClearTimeout(int32_t aHandle);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
|
||||
const int32_t aTimeout,
|
||||
const mozilla::dom::Sequence<JS::Value>& aArguments,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
|
||||
const int32_t aTimeout,
|
||||
const mozilla::dom::Sequence<JS::Value>& /* unused */,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ClearInterval(int32_t aHandle);
|
||||
void GetOrigin(nsAString& aOrigin);
|
||||
void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData,
|
||||
@ -794,8 +819,12 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
void SetOuterHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
mozilla::dom::CallerType aCallerType,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
|
||||
|
||||
uint32_t RequestIdleCallback(JSContext* aCx,
|
||||
@ -1059,10 +1088,13 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
public:
|
||||
// Timeout Functions
|
||||
// |interval| is in milliseconds.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeoutOrInterval(
|
||||
JSContext* aCx, mozilla::dom::Function& aFunction, int32_t aTimeout,
|
||||
const mozilla::dom::Sequence<JS::Value>& aArguments, bool aIsInterval,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
|
||||
int32_t aTimeout, bool aIsInterval,
|
||||
mozilla::ErrorResult& aError);
|
||||
@ -1317,6 +1349,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
nsCOMPtr<nsIPrincipal> mDocumentStoragePrincipal;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mDocumentCsp;
|
||||
|
||||
RefPtr<mozilla::dom::DebuggerNotificationManager>
|
||||
mDebuggerNotificationManager;
|
||||
|
||||
// mBrowserChild is only ever populated in the content process.
|
||||
nsCOMPtr<nsIBrowserChild> mBrowserChild;
|
||||
|
||||
|
@ -35,6 +35,7 @@ namespace mozilla {
|
||||
class DOMEventTargetHelper;
|
||||
namespace dom {
|
||||
class VoidFunction;
|
||||
class DebuggerNotificationManager;
|
||||
class ServiceWorker;
|
||||
class ServiceWorkerRegistration;
|
||||
class ServiceWorkerRegistrationDescriptor;
|
||||
@ -131,6 +132,16 @@ class nsIGlobalObject : public nsISupports,
|
||||
|
||||
virtual bool IsInSyncOperation() { return false; }
|
||||
|
||||
virtual mozilla::dom::DebuggerNotificationManager*
|
||||
GetOrCreateDebuggerNotificationManager() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual mozilla::dom::DebuggerNotificationManager*
|
||||
GetExistingDebuggerNotificationManager() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const;
|
||||
|
||||
virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController()
|
||||
|
@ -940,6 +940,12 @@ class nsINode : public mozilla::dom::EventTarget {
|
||||
const override;
|
||||
virtual mozilla::EventListenerManager* GetOrCreateListenerManager() override;
|
||||
|
||||
mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
|
||||
GetDebuggerNotificationType() const override {
|
||||
return mozilla::Some(
|
||||
mozilla::dom::EventCallbackDebuggerNotificationType::Node);
|
||||
}
|
||||
|
||||
bool ComputeDefaultWantsUntrusted(mozilla::ErrorResult& aRv) final;
|
||||
|
||||
virtual bool IsApzAware() const override;
|
||||
|
@ -201,6 +201,13 @@ DOMInterfaces = {
|
||||
'implicitJSContext': ['define'],
|
||||
},
|
||||
|
||||
'DebuggerNotification': {
|
||||
'concrete': True,
|
||||
},
|
||||
'CallbackDebuggerNotification': {
|
||||
'concrete': True,
|
||||
},
|
||||
|
||||
'DedicatedWorkerGlobalScope': {
|
||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||
},
|
||||
|
57
dom/chrome-webidl/DebuggerNotification.webidl
Normal file
57
dom/chrome-webidl/DebuggerNotification.webidl
Normal file
@ -0,0 +1,57 @@
|
||||
/* 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/. */
|
||||
|
||||
enum DebuggerNotificationType {
|
||||
// DebuggerNotification
|
||||
"setTimeout",
|
||||
"clearTimeout",
|
||||
"setInterval",
|
||||
"clearInterval",
|
||||
"requestAnimationFrame",
|
||||
"cancelAnimationFrame",
|
||||
|
||||
// CallbackDebuggerNotification
|
||||
"setTimeoutCallback",
|
||||
"setIntervalCallback",
|
||||
"requestAnimationFrameCallback",
|
||||
|
||||
// EventCallbackDebuggerNotification
|
||||
"domEvent",
|
||||
};
|
||||
|
||||
[ChromeOnly]
|
||||
interface DebuggerNotification {
|
||||
readonly attribute DebuggerNotificationType type;
|
||||
|
||||
// The global object that has triggered the notification.
|
||||
readonly attribute object global;
|
||||
};
|
||||
|
||||
// For DOM events, we send notifications just before, and just after the
|
||||
// event handler has been dispatched so that listeners
|
||||
enum CallbackDebuggerNotificationPhase {
|
||||
"pre",
|
||||
"post",
|
||||
};
|
||||
|
||||
// A base notification type for notifications that are dispatched as pairs with
|
||||
// a before and after notification.
|
||||
[ChromeOnly]
|
||||
interface CallbackDebuggerNotification : DebuggerNotification {
|
||||
readonly attribute CallbackDebuggerNotificationPhase phase;
|
||||
};
|
||||
|
||||
enum EventCallbackDebuggerNotificationType {
|
||||
"global",
|
||||
"node",
|
||||
"xhr",
|
||||
"worker",
|
||||
};
|
||||
|
||||
// A notification that about the engine calling a DOM event handler.
|
||||
[ChromeOnly]
|
||||
interface EventCallbackDebuggerNotification : CallbackDebuggerNotification {
|
||||
readonly attribute Event event;
|
||||
readonly attribute EventCallbackDebuggerNotificationType targetType;
|
||||
};
|
28
dom/chrome-webidl/DebuggerNotificationObserver.webidl
Normal file
28
dom/chrome-webidl/DebuggerNotificationObserver.webidl
Normal file
@ -0,0 +1,28 @@
|
||||
/* -*- 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/.
|
||||
*/
|
||||
|
||||
callback DebuggerNotificationCallback = void (DebuggerNotification n);
|
||||
|
||||
[ChromeOnly, Constructor, Exposed=(Window, Worker)]
|
||||
interface DebuggerNotificationObserver {
|
||||
// Throws if the object is not a browser global or does not support
|
||||
// debugger notifications.
|
||||
// Returns false if already connected to this global.
|
||||
[Throws]
|
||||
boolean connect(object global);
|
||||
|
||||
// Throws if the object is not a browser global or does not support
|
||||
// debugger notifications.
|
||||
// Returns false if not connected to this global.
|
||||
[Throws]
|
||||
boolean disconnect(object global);
|
||||
|
||||
// Returns false if listener already added.
|
||||
boolean addListener(DebuggerNotificationCallback handler);
|
||||
|
||||
// Returns false if listener was not found.
|
||||
boolean removeListener(DebuggerNotificationCallback handler);
|
||||
};
|
@ -35,6 +35,8 @@ PREPROCESSED_WEBIDL_FILES = [
|
||||
WEBIDL_FILES = [
|
||||
'BrowsingContext.webidl',
|
||||
'ChannelWrapper.webidl',
|
||||
'DebuggerNotification.webidl',
|
||||
'DebuggerNotificationObserver.webidl',
|
||||
'DocumentL10n.webidl',
|
||||
'DominatorTree.webidl',
|
||||
'DOMLocalization.webidl',
|
||||
|
35
dom/debugger/CallbackDebuggerNotification.cpp
Normal file
35
dom/debugger/CallbackDebuggerNotification.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- 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 "CallbackDebuggerNotification.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(CallbackDebuggerNotification,
|
||||
DebuggerNotification)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(CallbackDebuggerNotification, DebuggerNotification)
|
||||
NS_IMPL_RELEASE_INHERITED(CallbackDebuggerNotification, DebuggerNotification)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CallbackDebuggerNotification)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DebuggerNotification)
|
||||
|
||||
JSObject* CallbackDebuggerNotification::WrapObject(
|
||||
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
|
||||
return CallbackDebuggerNotification_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<DebuggerNotification> CallbackDebuggerNotification::CloneInto(
|
||||
nsIGlobalObject* aNewOwner) const {
|
||||
RefPtr<CallbackDebuggerNotification> notification(
|
||||
new CallbackDebuggerNotification(mDebuggeeGlobal, mType, mPhase,
|
||||
aNewOwner));
|
||||
return notification.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
79
dom/debugger/CallbackDebuggerNotification.h
Normal file
79
dom/debugger/CallbackDebuggerNotification.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_CallbackDebuggerNotification_h
|
||||
#define mozilla_dom_CallbackDebuggerNotification_h
|
||||
|
||||
#include "DebuggerNotification.h"
|
||||
#include "DebuggerNotificationManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CallbackDebuggerNotification : public DebuggerNotification {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CallbackDebuggerNotification,
|
||||
DebuggerNotification)
|
||||
|
||||
CallbackDebuggerNotification(nsIGlobalObject* aDebuggeeGlobal,
|
||||
DebuggerNotificationType aType,
|
||||
CallbackDebuggerNotificationPhase aPhase,
|
||||
nsIGlobalObject* aOwnerGlobal = nullptr)
|
||||
: DebuggerNotification(aDebuggeeGlobal, aType, aOwnerGlobal),
|
||||
mPhase(aPhase) {}
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
already_AddRefed<DebuggerNotification> CloneInto(
|
||||
nsIGlobalObject* aNewOwner) const override;
|
||||
|
||||
CallbackDebuggerNotificationPhase Phase() const { return mPhase; }
|
||||
|
||||
protected:
|
||||
~CallbackDebuggerNotification() = default;
|
||||
|
||||
CallbackDebuggerNotificationPhase mPhase;
|
||||
};
|
||||
|
||||
class MOZ_RAII CallbackDebuggerNotificationGuard final {
|
||||
public:
|
||||
MOZ_CAN_RUN_SCRIPT CallbackDebuggerNotificationGuard(
|
||||
nsIGlobalObject* aDebuggeeGlobal, DebuggerNotificationType aType)
|
||||
: mDebuggeeGlobal(aDebuggeeGlobal), mType(aType) {
|
||||
Dispatch(CallbackDebuggerNotificationPhase::Pre);
|
||||
}
|
||||
CallbackDebuggerNotificationGuard(const CallbackDebuggerNotificationGuard&) =
|
||||
delete;
|
||||
CallbackDebuggerNotificationGuard(CallbackDebuggerNotificationGuard&&) =
|
||||
delete;
|
||||
CallbackDebuggerNotificationGuard& operator=(
|
||||
const CallbackDebuggerNotificationGuard&) = delete;
|
||||
CallbackDebuggerNotificationGuard& operator=(
|
||||
CallbackDebuggerNotificationGuard&&) = delete;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT ~CallbackDebuggerNotificationGuard() {
|
||||
Dispatch(CallbackDebuggerNotificationPhase::Post);
|
||||
}
|
||||
|
||||
private:
|
||||
MOZ_CAN_RUN_SCRIPT void Dispatch(CallbackDebuggerNotificationPhase aPhase) {
|
||||
auto manager = DebuggerNotificationManager::ForDispatch(mDebuggeeGlobal);
|
||||
if (MOZ_UNLIKELY(manager)) {
|
||||
manager->Dispatch<CallbackDebuggerNotification>(mType, aPhase);
|
||||
}
|
||||
}
|
||||
|
||||
nsIGlobalObject* mDebuggeeGlobal;
|
||||
DebuggerNotificationType mType;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_CallbackDebuggerNotification_h
|
38
dom/debugger/DebuggerNotification.cpp
Normal file
38
dom/debugger/DebuggerNotification.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- 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 "DebuggerNotification.h"
|
||||
|
||||
#include "DebuggerNotificationManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DebuggerNotification, mDebuggeeGlobal,
|
||||
mOwnerGlobal)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DebuggerNotification)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DebuggerNotification)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DebuggerNotification)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
JSObject* DebuggerNotification::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return DebuggerNotification_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<DebuggerNotification> DebuggerNotification::CloneInto(
|
||||
nsIGlobalObject* aNewOwner) const {
|
||||
RefPtr<DebuggerNotification> notification(
|
||||
new DebuggerNotification(mDebuggeeGlobal, mType, aNewOwner));
|
||||
return notification.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
72
dom/debugger/DebuggerNotification.h
Normal file
72
dom/debugger/DebuggerNotification.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_DebuggerNotification_h
|
||||
#define mozilla_dom_DebuggerNotification_h
|
||||
|
||||
#include "DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/DebuggerNotificationBinding.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DebuggerNotification : public nsISupports, public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DebuggerNotification)
|
||||
|
||||
DebuggerNotification(nsIGlobalObject* aDebuggeeGlobal,
|
||||
DebuggerNotificationType aType,
|
||||
nsIGlobalObject* aOwnerGlobal = nullptr)
|
||||
: mType(aType),
|
||||
mDebuggeeGlobal(aDebuggeeGlobal),
|
||||
mOwnerGlobal(aOwnerGlobal) {}
|
||||
|
||||
nsIGlobalObject* GetParentObject() const {
|
||||
MOZ_ASSERT(mOwnerGlobal,
|
||||
"Notification must be cloned into an observer global before "
|
||||
"being wrapped");
|
||||
return mOwnerGlobal;
|
||||
}
|
||||
|
||||
DebuggerNotificationType Type() const { return mType; }
|
||||
|
||||
void GetGlobal(JSContext* aCx, JS::MutableHandle<JSObject*> aResult) {
|
||||
aResult.set(mDebuggeeGlobal->GetGlobalJSObject());
|
||||
}
|
||||
|
||||
virtual already_AddRefed<DebuggerNotification> CloneInto(
|
||||
nsIGlobalObject* aNewOwner) const;
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
virtual ~DebuggerNotification() = default;
|
||||
|
||||
DebuggerNotificationType mType;
|
||||
nsCOMPtr<nsIGlobalObject> mDebuggeeGlobal;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIGlobalObject> mOwnerGlobal;
|
||||
};
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT inline void DebuggerNotificationDispatch(
|
||||
nsIGlobalObject* aDebuggeeGlobal, DebuggerNotificationType aType) {
|
||||
auto manager = DebuggerNotificationManager::ForDispatch(aDebuggeeGlobal);
|
||||
if (MOZ_UNLIKELY(manager)) {
|
||||
manager->Dispatch<DebuggerNotification>(aType);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_DebuggerNotification_h
|
72
dom/debugger/DebuggerNotificationManager.cpp
Normal file
72
dom/debugger/DebuggerNotificationManager.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* -*- 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 "DebuggerNotificationManager.h"
|
||||
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(DebuggerNotificationManager, mDebuggeeGlobal,
|
||||
mNotificationObservers)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(DebuggerNotificationManager)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(DebuggerNotificationManager)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DebuggerNotificationManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DebuggerNotificationManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
bool DebuggerNotificationManager::Attach(
|
||||
DebuggerNotificationObserver* aObserver) {
|
||||
RefPtr<DebuggerNotificationObserver> ptr(aObserver);
|
||||
|
||||
if (mNotificationObservers.Contains(ptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mNotificationObservers.AppendElement(ptr);
|
||||
return true;
|
||||
}
|
||||
bool DebuggerNotificationManager::Detach(
|
||||
DebuggerNotificationObserver* aObserver) {
|
||||
RefPtr<DebuggerNotificationObserver> ptr(aObserver);
|
||||
|
||||
return mNotificationObservers.RemoveElement(ptr);
|
||||
}
|
||||
|
||||
bool DebuggerNotificationManager::HasListeners() {
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationObserver>>::ForwardIterator iter(
|
||||
mNotificationObservers);
|
||||
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<DebuggerNotificationObserver> observer(iter.GetNext());
|
||||
if (observer->HasListeners()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebuggerNotificationManager::NotifyListeners(
|
||||
DebuggerNotification* aNotification) {
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationObserver>>::ForwardIterator iter(
|
||||
mNotificationObservers);
|
||||
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<DebuggerNotificationObserver> observer(iter.GetNext());
|
||||
observer->NotifyListeners(aNotification);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
63
dom/debugger/DebuggerNotificationManager.h
Normal file
63
dom/debugger/DebuggerNotificationManager.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_DebuggerNotificationManager_h
|
||||
#define mozilla_dom_DebuggerNotificationManager_h
|
||||
|
||||
#include "DebuggerNotificationObserver.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DebuggerNotificationManager final : public nsISupports {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DebuggerNotificationManager)
|
||||
|
||||
static RefPtr<DebuggerNotificationManager> ForDispatch(
|
||||
nsIGlobalObject* aDebuggeeGlobal) {
|
||||
if (MOZ_UNLIKELY(!aDebuggeeGlobal)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto managerPtr = aDebuggeeGlobal->GetExistingDebuggerNotificationManager();
|
||||
if (MOZ_LIKELY(!managerPtr) || !managerPtr->HasListeners()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return managerPtr;
|
||||
}
|
||||
|
||||
explicit DebuggerNotificationManager(nsIGlobalObject* aDebuggeeGlobal)
|
||||
: mDebuggeeGlobal(aDebuggeeGlobal), mNotificationObservers() {}
|
||||
|
||||
bool Attach(DebuggerNotificationObserver* aObserver);
|
||||
bool Detach(DebuggerNotificationObserver* aObserver);
|
||||
|
||||
bool HasListeners();
|
||||
|
||||
template <typename T, typename... Args>
|
||||
MOZ_CAN_RUN_SCRIPT void Dispatch(Args... aArgs) {
|
||||
RefPtr<DebuggerNotification> notification(new T(mDebuggeeGlobal, aArgs...));
|
||||
NotifyListeners(notification);
|
||||
}
|
||||
|
||||
private:
|
||||
~DebuggerNotificationManager() = default;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT void NotifyListeners(DebuggerNotification* aNotification);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mDebuggeeGlobal;
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationObserver>> mNotificationObservers;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_DebuggerNotificationManager_h
|
152
dom/debugger/DebuggerNotificationObserver.cpp
Normal file
152
dom/debugger/DebuggerNotificationObserver.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/* -*- 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 {
|
||||
namespace 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) {
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationCallback>>::ForwardIterator iter(
|
||||
mEventListenerCallbacks);
|
||||
while (iter.HasMore()) {
|
||||
if (*iter.GetNext().get() == aHandlerFn) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<DebuggerNotificationCallback> handlerFn(&aHandlerFn);
|
||||
mEventListenerCallbacks.AppendElement(handlerFn);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DebuggerNotificationObserver::RemoveListener(
|
||||
DebuggerNotificationCallback& aHandlerFn) {
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationCallback>>::ForwardIterator iter(
|
||||
mEventListenerCallbacks);
|
||||
for (uint32_t i = 0; iter.HasMore(); i++) {
|
||||
if (*iter.GetNext().get() == aHandlerFn) {
|
||||
mEventListenerCallbacks.RemoveElementAt(i);
|
||||
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));
|
||||
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationCallback>>::ForwardIterator iter(
|
||||
mEventListenerCallbacks);
|
||||
|
||||
while (iter.HasMore()) {
|
||||
RefPtr<DebuggerNotificationCallback> cb(iter.GetNext());
|
||||
cb->Call(*debuggerNotification);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
62
dom/debugger/DebuggerNotificationObserver.h
Normal file
62
dom/debugger/DebuggerNotificationObserver.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_DebuggerNotificationObserver_h
|
||||
#define mozilla_dom_DebuggerNotificationObserver_h
|
||||
|
||||
#include "DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/DebuggerNotificationObserverBinding.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DebuggerNotification;
|
||||
|
||||
class DebuggerNotificationObserver final : public nsISupports,
|
||||
public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DebuggerNotificationObserver)
|
||||
|
||||
static already_AddRefed<DebuggerNotificationObserver> Constructor(
|
||||
GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
|
||||
nsIGlobalObject* GetParentObject() const { return mOwnerGlobal; }
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool Connect(JSContext* aCx, JS::Handle<JSObject*> aDebuggeeGlobal,
|
||||
ErrorResult& aRv);
|
||||
bool Disconnect(JSContext* aCx, JS::Handle<JSObject*> aDebuggeeGlobal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
bool AddListener(DebuggerNotificationCallback& aHandlerFn);
|
||||
bool RemoveListener(DebuggerNotificationCallback& aHandlerFn);
|
||||
|
||||
bool HasListeners();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT void NotifyListeners(DebuggerNotification* aNotification);
|
||||
|
||||
private:
|
||||
explicit DebuggerNotificationObserver(nsIGlobalObject* aOwnerGlobal);
|
||||
~DebuggerNotificationObserver() = default;
|
||||
|
||||
nsTObserverArray<RefPtr<DebuggerNotificationCallback>>
|
||||
mEventListenerCallbacks;
|
||||
nsCOMPtr<nsIGlobalObject> mOwnerGlobal;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_DebuggerNotificationObserver_h
|
65
dom/debugger/EventCallbackDebuggerNotification.cpp
Normal file
65
dom/debugger/EventCallbackDebuggerNotification.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- 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 "EventCallbackDebuggerNotification.h"
|
||||
|
||||
#include "DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/Worker.h"
|
||||
#include "mozilla/dom/XMLHttpRequestEventTarget.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsQueryObject.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(EventCallbackDebuggerNotification,
|
||||
CallbackDebuggerNotification, mEvent)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(EventCallbackDebuggerNotification,
|
||||
CallbackDebuggerNotification)
|
||||
NS_IMPL_RELEASE_INHERITED(EventCallbackDebuggerNotification,
|
||||
CallbackDebuggerNotification)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(EventCallbackDebuggerNotification)
|
||||
NS_INTERFACE_MAP_END_INHERITING(CallbackDebuggerNotification)
|
||||
|
||||
JSObject* EventCallbackDebuggerNotification::WrapObject(
|
||||
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
|
||||
return EventCallbackDebuggerNotification_Binding::Wrap(aCx, this,
|
||||
aGivenProto);
|
||||
}
|
||||
|
||||
already_AddRefed<DebuggerNotification>
|
||||
EventCallbackDebuggerNotification::CloneInto(nsIGlobalObject* aNewOwner) const {
|
||||
RefPtr<EventCallbackDebuggerNotification> notification(
|
||||
new EventCallbackDebuggerNotification(mDebuggeeGlobal, mType, mEvent,
|
||||
mTargetType, mPhase, aNewOwner));
|
||||
return notification.forget();
|
||||
}
|
||||
|
||||
void EventCallbackDebuggerNotificationGuard::DispatchToManager(
|
||||
const RefPtr<DebuggerNotificationManager>& aManager,
|
||||
CallbackDebuggerNotificationPhase aPhase) {
|
||||
if (!mEventTarget) {
|
||||
MOZ_ASSERT(false, "target should exist");
|
||||
return;
|
||||
}
|
||||
|
||||
Maybe<EventCallbackDebuggerNotificationType> notificationType(
|
||||
mEventTarget->GetDebuggerNotificationType());
|
||||
|
||||
if (notificationType) {
|
||||
aManager->Dispatch<EventCallbackDebuggerNotification>(
|
||||
DebuggerNotificationType::DomEvent,
|
||||
// The DOM event will always be live during event dispatch.
|
||||
MOZ_KnownLive(mEvent), *notificationType, aPhase);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
96
dom/debugger/EventCallbackDebuggerNotification.h
Normal file
96
dom/debugger/EventCallbackDebuggerNotification.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_EventCallbackDebuggerNotification_h
|
||||
#define mozilla_dom_EventCallbackDebuggerNotification_h
|
||||
|
||||
#include "CallbackDebuggerNotification.h"
|
||||
#include "DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class EventCallbackDebuggerNotification : public CallbackDebuggerNotification {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(EventCallbackDebuggerNotification,
|
||||
CallbackDebuggerNotification)
|
||||
|
||||
EventCallbackDebuggerNotification(
|
||||
nsIGlobalObject* aDebuggeeGlobal, DebuggerNotificationType aType,
|
||||
Event* aEvent, EventCallbackDebuggerNotificationType aTargetType,
|
||||
CallbackDebuggerNotificationPhase aPhase,
|
||||
nsIGlobalObject* aOwnerGlobal = nullptr)
|
||||
: CallbackDebuggerNotification(aDebuggeeGlobal, aType, aPhase,
|
||||
aOwnerGlobal),
|
||||
mEvent(aEvent),
|
||||
mTargetType(aTargetType) {}
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
already_AddRefed<DebuggerNotification> CloneInto(
|
||||
nsIGlobalObject* aNewOwner) const override;
|
||||
|
||||
mozilla::dom::Event* Event() const { return mEvent; }
|
||||
EventCallbackDebuggerNotificationType TargetType() const {
|
||||
return mTargetType;
|
||||
}
|
||||
|
||||
private:
|
||||
~EventCallbackDebuggerNotification() = default;
|
||||
|
||||
RefPtr<mozilla::dom::Event> mEvent;
|
||||
EventCallbackDebuggerNotificationType mTargetType;
|
||||
};
|
||||
|
||||
class MOZ_RAII EventCallbackDebuggerNotificationGuard final {
|
||||
public:
|
||||
MOZ_CAN_RUN_SCRIPT explicit EventCallbackDebuggerNotificationGuard(
|
||||
mozilla::dom::EventTarget* aEventTarget, mozilla::dom::Event* aEvent)
|
||||
: mDebuggeeGlobal(aEventTarget ? aEventTarget->GetOwnerGlobal()
|
||||
: nullptr),
|
||||
mEventTarget(aEventTarget),
|
||||
mEvent(aEvent) {
|
||||
Dispatch(CallbackDebuggerNotificationPhase::Pre);
|
||||
}
|
||||
EventCallbackDebuggerNotificationGuard(
|
||||
const EventCallbackDebuggerNotificationGuard&) = delete;
|
||||
EventCallbackDebuggerNotificationGuard(
|
||||
EventCallbackDebuggerNotificationGuard&&) = delete;
|
||||
EventCallbackDebuggerNotificationGuard& operator=(
|
||||
const EventCallbackDebuggerNotificationGuard&) = delete;
|
||||
EventCallbackDebuggerNotificationGuard& operator=(
|
||||
EventCallbackDebuggerNotificationGuard&&) = delete;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT ~EventCallbackDebuggerNotificationGuard() {
|
||||
Dispatch(CallbackDebuggerNotificationPhase::Post);
|
||||
}
|
||||
|
||||
private:
|
||||
MOZ_CAN_RUN_SCRIPT void Dispatch(CallbackDebuggerNotificationPhase aPhase) {
|
||||
auto manager = DebuggerNotificationManager::ForDispatch(mDebuggeeGlobal);
|
||||
if (MOZ_UNLIKELY(manager)) {
|
||||
DispatchToManager(manager, aPhase);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT void DispatchToManager(
|
||||
const RefPtr<DebuggerNotificationManager>& aManager,
|
||||
CallbackDebuggerNotificationPhase aPhase);
|
||||
|
||||
nsIGlobalObject* mDebuggeeGlobal;
|
||||
mozilla::dom::EventTarget* mEventTarget;
|
||||
mozilla::dom::Event* mEvent;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_EventCallbackDebuggerNotification_h
|
26
dom/debugger/moz.build
Normal file
26
dom/debugger/moz.build
Normal file
@ -0,0 +1,26 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("DevTools", "Debugger")
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'CallbackDebuggerNotification.h',
|
||||
'DebuggerNotification.h',
|
||||
'DebuggerNotificationManager.h',
|
||||
'DebuggerNotificationObserver.h',
|
||||
'EventCallbackDebuggerNotification.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'CallbackDebuggerNotification.cpp',
|
||||
'DebuggerNotification.cpp',
|
||||
'DebuggerNotificationManager.cpp',
|
||||
'DebuggerNotificationObserver.cpp',
|
||||
'EventCallbackDebuggerNotification.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
@ -20,6 +20,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/EventCallbackDebuggerNotification.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/EventTargetBinding.h"
|
||||
@ -1014,6 +1015,7 @@ nsresult EventListenerManager::HandleEventSubType(Listener* aListener,
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
EventCallbackDebuggerNotificationGuard dbgGuard(aCurrentTarget, aDOMEvent);
|
||||
nsAutoMicroTask mt;
|
||||
|
||||
// Event::currentTarget is set in EventDispatcher.
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_EventTarget_h_
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/DebuggerNotificationBinding.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsWrapperCache.h"
|
||||
@ -195,6 +196,11 @@ class EventTarget : public nsISupports, public nsWrapperCache {
|
||||
*/
|
||||
virtual EventListenerManager* GetExistingListenerManager() const = 0;
|
||||
|
||||
virtual Maybe<EventCallbackDebuggerNotificationType>
|
||||
GetDebuggerNotificationType() const {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
// Called from AsyncEventDispatcher to notify it is running.
|
||||
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {}
|
||||
|
||||
|
@ -7,10 +7,6 @@
|
||||
#include "mozilla/dom/HTMLTrackElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLMediaElement.h"
|
||||
#ifdef XP_WIN
|
||||
// HTMLTrackElement.webidl defines ERROR, but so does windows.h:
|
||||
# undef ERROR
|
||||
#endif
|
||||
#include "WebVTTListener.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/dom/HTMLTrackElementBinding.h"
|
||||
|
@ -44,6 +44,7 @@ DIRS += [
|
||||
'commandhandler',
|
||||
'credentialmanagement',
|
||||
'crypto',
|
||||
'debugger',
|
||||
'encoding',
|
||||
'events',
|
||||
'fetch',
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "RuntimeService.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/DebuggerNotificationObserverBinding.h"
|
||||
#include "mozilla/dom/RegisterWorkerBindings.h"
|
||||
#include "mozilla/dom/RegisterWorkerDebuggerBindings.h"
|
||||
#include "mozilla/OSFileConstants.h"
|
||||
@ -52,6 +53,10 @@ bool WorkerPrivate::RegisterDebuggerBindings(JSContext* aCx,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!DebuggerNotificationObserver_Binding::GetConstructorObject(aCx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_DefineDebuggerObject(aCx, aGlobal)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_Worker_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/DebuggerNotificationBinding.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
@ -38,6 +39,11 @@ class Worker : public DOMEventTargetHelper, public SupportsWeakPtr<Worker> {
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
Maybe<EventCallbackDebuggerNotificationType> GetDebuggerNotificationType()
|
||||
const override {
|
||||
return Some(EventCallbackDebuggerNotificationType::Worker);
|
||||
}
|
||||
|
||||
void PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/CallbackDebuggerNotification.h"
|
||||
#include "mozilla/dom/ClientManager.h"
|
||||
#include "mozilla/dom/ClientSource.h"
|
||||
#include "mozilla/dom/ClientState.h"
|
||||
@ -4309,6 +4310,12 @@ bool WorkerPrivate::RunExpiredTimeouts(JSContext* aCx) {
|
||||
}
|
||||
|
||||
RefPtr<TimeoutHandler> handler(info->mHandler);
|
||||
|
||||
RefPtr<WorkerGlobalScope> scope(this->GlobalScope());
|
||||
CallbackDebuggerNotificationGuard guard(
|
||||
scope, info->mIsInterval
|
||||
? DebuggerNotificationType::SetIntervalCallback
|
||||
: DebuggerNotificationType::SetTimeoutCallback);
|
||||
if (!handler->Call(reason)) {
|
||||
retval = false;
|
||||
break;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "mozilla/dom/ClientState.h"
|
||||
#include "mozilla/dom/Console.h"
|
||||
#include "mozilla/dom/CSPEvalChecker.h"
|
||||
#include "mozilla/dom/DebuggerNotification.h"
|
||||
#include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
|
||||
#include "mozilla/dom/Fetch.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
@ -140,6 +141,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNavigator)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDebuggerNotificationManager)
|
||||
tmp->TraverseHostObjectURIs(cb);
|
||||
tmp->mWorkerPrivate->TraverseTimeouts(cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
@ -154,6 +156,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNavigator)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDebuggerNotificationManager)
|
||||
tmp->UnlinkHostObjectURIs();
|
||||
tmp->mWorkerPrivate->UnlinkTimeouts();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
@ -303,6 +306,9 @@ int32_t WorkerGlobalScope::SetTimeout(JSContext* aCx, const nsAString& aHandler,
|
||||
|
||||
void WorkerGlobalScope::ClearTimeout(int32_t aHandle) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearTimeout);
|
||||
|
||||
mWorkerPrivate->ClearTimeout(aHandle);
|
||||
}
|
||||
|
||||
@ -323,6 +329,9 @@ int32_t WorkerGlobalScope::SetInterval(JSContext* aCx,
|
||||
|
||||
void WorkerGlobalScope::ClearInterval(int32_t aHandle) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
DebuggerNotificationDispatch(this, DebuggerNotificationType::ClearInterval);
|
||||
|
||||
mWorkerPrivate->ClearTimeout(aHandle);
|
||||
}
|
||||
|
||||
@ -331,6 +340,10 @@ int32_t WorkerGlobalScope::SetTimeoutOrInterval(
|
||||
const Sequence<JS::Value>& aArguments, bool aIsInterval, ErrorResult& aRv) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
DebuggerNotificationDispatch(
|
||||
this, aIsInterval ? DebuggerNotificationType::SetInterval
|
||||
: DebuggerNotificationType::SetTimeout);
|
||||
|
||||
nsTArray<JS::Heap<JS::Value>> args;
|
||||
if (!args.AppendElements(aArguments, fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -350,6 +363,10 @@ int32_t WorkerGlobalScope::SetTimeoutOrInterval(JSContext* aCx,
|
||||
ErrorResult& aRv) {
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
DebuggerNotificationDispatch(
|
||||
this, aIsInterval ? DebuggerNotificationType::SetInterval
|
||||
: DebuggerNotificationType::SetTimeout);
|
||||
|
||||
bool allowEval = false;
|
||||
aRv =
|
||||
CSPEvalChecker::CheckForWorker(aCx, mWorkerPrivate, aHandler, &allowEval);
|
||||
@ -500,6 +517,20 @@ AbstractThread* WorkerGlobalScope::AbstractMainThreadFor(
|
||||
MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
|
||||
}
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
WorkerGlobalScope::GetOrCreateDebuggerNotificationManager() {
|
||||
if (!mDebuggerNotificationManager) {
|
||||
mDebuggerNotificationManager = new DebuggerNotificationManager(this);
|
||||
}
|
||||
|
||||
return mDebuggerNotificationManager;
|
||||
}
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
WorkerGlobalScope::GetExistingDebuggerNotificationManager() {
|
||||
return mDebuggerNotificationManager;
|
||||
}
|
||||
|
||||
Maybe<ClientInfo> WorkerGlobalScope::GetClientInfo() const {
|
||||
return mWorkerPrivate->GetClientInfo();
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/DebuggerNotificationManager.h"
|
||||
#include "mozilla/dom/Headers.h"
|
||||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "nsWeakReference.h"
|
||||
@ -60,6 +61,8 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
|
||||
RefPtr<IDBFactory> mIndexedDB;
|
||||
RefPtr<cache::CacheStorage> mCacheStorage;
|
||||
nsCOMPtr<nsISerialEventTarget> mSerialEventTarget;
|
||||
RefPtr<mozilla::dom::DebuggerNotificationManager>
|
||||
mDebuggerNotificationManager;
|
||||
|
||||
uint32_t mWindowInteractionsAllowed;
|
||||
|
||||
@ -69,10 +72,12 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
|
||||
explicit WorkerGlobalScope(WorkerPrivate* aWorkerPrivate);
|
||||
virtual ~WorkerGlobalScope();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeoutOrInterval(JSContext* aCx, Function& aHandler,
|
||||
const int32_t aTimeout,
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
bool aIsInterval, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
|
||||
const int32_t aTimeout, bool aIsInterval,
|
||||
ErrorResult& aRv);
|
||||
@ -115,19 +120,25 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
|
||||
void ImportScripts(JSContext* aCx, const Sequence<nsString>& aScriptURLs,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeout(JSContext* aCx, Function& aHandler, const int32_t aTimeout,
|
||||
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
|
||||
const int32_t aTimeout,
|
||||
const Sequence<JS::Value>& /* unused */, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ClearTimeout(int32_t aHandle);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetInterval(JSContext* aCx, Function& aHandler,
|
||||
const int32_t aTimeout,
|
||||
const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
|
||||
const int32_t aTimeout,
|
||||
const Sequence<JS::Value>& /* unused */,
|
||||
ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ClearInterval(int32_t aHandle);
|
||||
|
||||
void GetOrigin(nsAString& aOrigin) const;
|
||||
@ -191,6 +202,18 @@ class WorkerGlobalScope : public DOMEventTargetHelper,
|
||||
|
||||
AbstractThread* AbstractMainThreadFor(TaskCategory aCategory) override;
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
GetOrCreateDebuggerNotificationManager() override;
|
||||
|
||||
mozilla::dom::DebuggerNotificationManager*
|
||||
GetExistingDebuggerNotificationManager() override;
|
||||
|
||||
mozilla::Maybe<mozilla::dom::EventCallbackDebuggerNotificationType>
|
||||
GetDebuggerNotificationType() const override {
|
||||
return mozilla::Some(
|
||||
mozilla::dom::EventCallbackDebuggerNotificationType::Global);
|
||||
}
|
||||
|
||||
Maybe<ClientInfo> GetClientInfo() const override;
|
||||
|
||||
Maybe<ClientState> GetClientState() const;
|
||||
|
@ -26,6 +26,11 @@ class XMLHttpRequestEventTarget : public DOMEventTargetHelper {
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XMLHttpRequestEventTarget,
|
||||
DOMEventTargetHelper)
|
||||
|
||||
mozilla::Maybe<EventCallbackDebuggerNotificationType>
|
||||
GetDebuggerNotificationType() const override {
|
||||
return mozilla::Some(EventCallbackDebuggerNotificationType::Xhr);
|
||||
}
|
||||
|
||||
IMPL_EVENT_HANDLER(loadstart)
|
||||
IMPL_EVENT_HANDLER(progress)
|
||||
IMPL_EVENT_HANDLER(abort)
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "nsViewManager.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "mozilla/dom/CallbackDebuggerNotification.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/Performance.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
@ -1695,6 +1696,12 @@ void nsRefreshDriver::RunFrameRequestCallbacks(TimeStamp aNowTime) {
|
||||
callback.mHandle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> global(innerWindow ? innerWindow->AsGlobal()
|
||||
: nullptr);
|
||||
CallbackDebuggerNotificationGuard guard(
|
||||
global, DebuggerNotificationType::RequestAnimationFrameCallback);
|
||||
|
||||
// MOZ_KnownLive is OK, because the stack array frameRequestCallbacks
|
||||
// keeps callback alive and the mCallback strong reference can't be
|
||||
// mutated by the call.
|
||||
|
Loading…
x
Reference in New Issue
Block a user