Bug 1708734 - Part 2: Allow specifying that an actor should not be created when event is fired, r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D114792
This commit is contained in:
Nika Layzell 2021-05-11 17:29:25 +00:00
Родитель 568e5e85df
Коммит 9c17d49cce
4 изменённых файлов: 42 добавлений и 5 удалений

Просмотреть файл

@ -119,6 +119,20 @@ dictionary WindowActorSidedOptions {
required ByteString moduleURI;
};
dictionary WindowActorEventListenerOptions : AddEventListenerOptions {
/**
* If this attribute is set to true (the default), this event will cause the
* actor to be created when it is fired. If the attribute is set false, the
* actor will not receive the event unless it had already been created through
* some other mechanism.
*
* This should be set to `false` for event listeners which are only intended
* to perform cleanup operations, and will have no effect if the actor doesn't
* already exist.
*/
boolean createActor = true;
};
dictionary WindowActorChildOptions : WindowActorSidedOptions {
/**
* Events which this actor wants to be listening to. When these events fire,
@ -129,7 +143,7 @@ dictionary WindowActorChildOptions : WindowActorSidedOptions {
* NOTE: `once` option is not support due to we register listeners in a shared
* location.
*/
record<DOMString, AddEventListenerOptions> events;
record<DOMString, WindowActorEventListenerOptions> events;
/**
* An array of observer topics to listen to. An observer will be added for each

Просмотреть файл

@ -281,6 +281,7 @@ struct JSWindowActorEventDecl
bool systemGroup;
bool allowUntrusted;
bool? passive;
bool createActor;
};
struct JSWindowActorInfo

Просмотреть файл

@ -53,6 +53,7 @@ JSWindowActorProtocol::FromIPC(const JSWindowActorInfo& aInfo) {
if (ipc.passive()) {
event->mPassive.Construct(ipc.passive().value());
}
event->mCreateActor = ipc.createActor();
}
proto->mChild.mObservers = aInfo.observers().Clone();
@ -80,6 +81,7 @@ JSWindowActorInfo JSWindowActorProtocol::ToIPC() {
if (event.mPassive.WasPassed()) {
ipc->passive() = Some(event.mPassive.Value());
}
ipc->createActor() = event.mCreateActor;
}
info.observers() = mChild.mObservers.Clone();
@ -151,6 +153,7 @@ JSWindowActorProtocol::FromWebIDLOptions(const nsACString& aName,
if (entry.mValue.mPassive.WasPassed()) {
evt->mPassive.Construct(entry.mValue.mPassive.Value());
}
evt->mCreateActor = entry.mValue.mCreateActor;
}
}
@ -188,15 +191,33 @@ NS_IMETHODIMP JSWindowActorProtocol::HandleEvent(Event* aEvent) {
}
// Ensure our actor is present.
AutoJSAPI jsapi;
jsapi.Init();
RefPtr<JSActor> actor = wgc->GetActor(jsapi.cx(), mName, IgnoreErrors());
RefPtr<JSActor> actor = wgc->GetExistingActor(mName);
if (!actor) {
// Check if we're supposed to create the actor when this event is fired.
bool createActor = true;
nsAutoString typeStr;
aEvent->GetType(typeStr);
for (auto& event : mChild.mEvents) {
if (event.mName == typeStr) {
createActor = event.mCreateActor;
break;
}
}
// If we're supposed to create the actor, call GetActor to cause it to be
// created.
if (createActor) {
AutoJSAPI jsapi;
jsapi.Init();
actor = wgc->GetActor(jsapi.cx(), mName, IgnoreErrors());
}
}
if (!actor || NS_WARN_IF(!actor->GetWrapperPreserveColor())) {
return NS_OK;
}
// Build our event listener & call it.
JS::Rooted<JSObject*> global(jsapi.cx(),
JS::Rooted<JSObject*> global(RootingCx(),
JS::GetNonCCWObjectGlobal(actor->GetWrapper()));
RefPtr<EventListener> eventListener =
new EventListener(actor->GetWrapper(), global, nullptr, nullptr);

Просмотреть файл

@ -56,6 +56,7 @@ class JSWindowActorProtocol final : public JSActorProtocol,
nsString mName;
EventListenerFlags mFlags;
Optional<bool> mPassive;
bool mCreateActor = true;
};
struct ChildSide : public Sided {