Skip to content

Commit 47a9b98

Browse files
committed
Bug 2002721 - [webdriver-bidi] Make sure that "script.realmCreated" event is sent after a browser element is attached to a browser context. r=jdescottes
Differential Revision: https://phabricator.services.mozilla.com/D274756
1 parent 538edbd commit 47a9b98

File tree

2 files changed

+98
-17
lines changed

2 files changed

+98
-17
lines changed

remote/webdriver-bidi/modules/root/browsingContext.sys.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,15 @@ class BrowsingContextModule extends RootBiDiModule {
19801980
"browsingContext.contextCreated",
19811981
browsingContextInfo
19821982
);
1983+
1984+
// This is an internal event is used by the script module
1985+
// to ensure that "script.realmCreated" event is emitted
1986+
// after "browsingContext.contextCreated".
1987+
this.messageHandler.emitEvent(
1988+
"browsingContext._contextCreatedEmitted",
1989+
{ browsingContext },
1990+
browsingContextInfo
1991+
);
19831992
}
19841993
};
19851994

remote/webdriver-bidi/modules/root/script.sys.mjs

Lines changed: 89 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const lazy = {};
88

99
ChromeUtils.defineESModuleGetters(lazy, {
1010
assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs",
11+
BrowsingContextListener:
12+
"chrome://remote/content/shared/listeners/BrowsingContextListener.sys.mjs",
1113
ContextDescriptorType:
1214
"chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs",
1315
error: "chrome://remote/content/shared/webdriver/Errors.sys.mjs",
@@ -63,22 +65,35 @@ const ScriptEvaluateResultType = {
6365
*/
6466

6567
class ScriptModule extends RootBiDiModule {
68+
#contextListener;
6669
#preloadScriptMap;
70+
#realmInfoMap;
6771
#subscribedEvents;
6872

6973
constructor(messageHandler) {
7074
super(messageHandler);
7175

76+
this.#contextListener = new lazy.BrowsingContextListener();
77+
this.#contextListener.on("attached", this.#onContextAttached);
78+
7279
// Map in which the keys are UUIDs, and the values are structs
7380
// of the type PreloadScript.
7481
this.#preloadScriptMap = new Map();
7582

83+
// Map with browsing contexts as keys and realm info object
84+
// as values.
85+
this.#realmInfoMap = new WeakMap();
86+
7687
// Set of event names which have active subscriptions.
7788
this.#subscribedEvents = new Set();
7889
}
7990

8091
destroy() {
92+
this.#contextListener.off("attached", this.#onContextAttached);
93+
this.#contextListener.destroy();
94+
8195
this.#preloadScriptMap = null;
96+
this.#realmInfoMap = null;
8297
this.#subscribedEvents = null;
8398
}
8499

@@ -903,24 +918,51 @@ class ScriptModule extends RootBiDiModule {
903918
.filter(realm => realm.context !== null);
904919
}
905920

921+
#hasEventSubscriptionToContextCreated(browsingContext) {
922+
const sessionData =
923+
this.messageHandler.sessionData.getSessionDataForContext(
924+
"browsingContext",
925+
"event",
926+
browsingContext
927+
);
928+
929+
return sessionData.some(
930+
item => item.value === "browsingContext.contextCreated"
931+
);
932+
}
933+
934+
#onContextAttached = (eventName, data) => {
935+
const { browsingContext } = data;
936+
// If there is a subscription for "browsingContext.contextCreated" event,
937+
// do not send "script.realmCreated" event yet and
938+
// wait until the "browsingContext.contextCreated" event is submitted
939+
if (
940+
this.#realmInfoMap.has(browsingContext) &&
941+
!this.#hasEventSubscriptionToContextCreated(browsingContext)
942+
) {
943+
this.#sendDelayedRealmCreatedEvent(browsingContext);
944+
}
945+
};
946+
947+
#onContextCreatedSubmitted = (eventName, { browsingContext }) => {
948+
if (this.#realmInfoMap.has(browsingContext)) {
949+
this.#sendDelayedRealmCreatedEvent(browsingContext);
950+
}
951+
};
952+
906953
#onRealmCreated = (eventName, { realmInfo }) => {
907954
// Resolve browsing context to a TabManager id.
908955
const context = lazy.NavigableManager.getIdForBrowsingContext(
909956
realmInfo.context
910957
);
911-
const browsingContextId = realmInfo.context.id;
912958

913-
// Do not emit the event, if the browsing context is gone.
959+
// Do not emit the event, if the browsing context is gone or not created yet.
914960
if (context === null) {
961+
// Save the realm info to send it when the browsing context is ready.
962+
this.#realmInfoMap.set(realmInfo.context, realmInfo);
915963
return;
916964
}
917-
918-
realmInfo.context = context;
919-
this._emitEventForBrowsingContext(
920-
browsingContextId,
921-
"script.realmCreated",
922-
realmInfo
923-
);
965+
this.#sendRealmCreatedEvent(realmInfo, realmInfo.context, context);
924966
};
925967

926968
#onRealmDestroyed = (eventName, { realm, context }) => {
@@ -929,25 +971,55 @@ class ScriptModule extends RootBiDiModule {
929971
});
930972
};
931973

932-
#startListingOnRealmCreated() {
974+
#sendDelayedRealmCreatedEvent(browsingContext) {
975+
const realmInfo = this.#realmInfoMap.get(browsingContext);
976+
// Resolve browsing context to a TabManager id.
977+
const browsingContextId = lazy.NavigableManager.getIdForBrowsingContext(
978+
realmInfo.context
979+
);
980+
this.#sendRealmCreatedEvent(realmInfo, browsingContext, browsingContextId);
981+
this.#realmInfoMap.delete(browsingContext);
982+
}
983+
984+
#sendRealmCreatedEvent(realmInfo, context, browsingContextId) {
985+
realmInfo.context = browsingContextId;
986+
987+
this._emitEventForBrowsingContext(
988+
context.id,
989+
"script.realmCreated",
990+
realmInfo
991+
);
992+
}
993+
994+
#startListeningOnRealmCreated() {
933995
if (!this.#subscribedEvents.has("script.realmCreated")) {
934996
this.messageHandler.on("realm-created", this.#onRealmCreated);
997+
this.messageHandler.on(
998+
"browsingContext._contextCreatedEmitted",
999+
this.#onContextCreatedSubmitted
1000+
);
1001+
this.#contextListener.startListening();
9351002
}
9361003
}
9371004

938-
#stopListingOnRealmCreated() {
1005+
#stopListeningOnRealmCreated() {
9391006
if (this.#subscribedEvents.has("script.realmCreated")) {
9401007
this.messageHandler.off("realm-created", this.#onRealmCreated);
1008+
this.messageHandler.off(
1009+
"browsingContext._contextCreatedEmitted",
1010+
this.#onContextCreatedSubmitted
1011+
);
1012+
this.#contextListener.stopListening();
9411013
}
9421014
}
9431015

944-
#startListingOnRealmDestroyed() {
1016+
#startListeningOnRealmDestroyed() {
9451017
if (!this.#subscribedEvents.has("script.realmDestroyed")) {
9461018
this.messageHandler.on("realm-destroyed", this.#onRealmDestroyed);
9471019
}
9481020
}
9491021

950-
#stopListingOnRealmDestroyed() {
1022+
#stopListeningOnRealmDestroyed() {
9511023
if (this.#subscribedEvents.has("script.realmDestroyed")) {
9521024
this.messageHandler.off("realm-destroyed", this.#onRealmDestroyed);
9531025
}
@@ -956,12 +1028,12 @@ class ScriptModule extends RootBiDiModule {
9561028
#subscribeEvent(event) {
9571029
switch (event) {
9581030
case "script.realmCreated": {
959-
this.#startListingOnRealmCreated();
1031+
this.#startListeningOnRealmCreated();
9601032
this.#subscribedEvents.add(event);
9611033
break;
9621034
}
9631035
case "script.realmDestroyed": {
964-
this.#startListingOnRealmDestroyed();
1036+
this.#startListeningOnRealmDestroyed();
9651037
this.#subscribedEvents.add(event);
9661038
break;
9671039
}
@@ -971,12 +1043,12 @@ class ScriptModule extends RootBiDiModule {
9711043
#unsubscribeEvent(event) {
9721044
switch (event) {
9731045
case "script.realmCreated": {
974-
this.#stopListingOnRealmCreated();
1046+
this.#stopListeningOnRealmCreated();
9751047
this.#subscribedEvents.delete(event);
9761048
break;
9771049
}
9781050
case "script.realmDestroyed": {
979-
this.#stopListingOnRealmDestroyed();
1051+
this.#stopListeningOnRealmDestroyed();
9801052
this.#subscribedEvents.delete(event);
9811053
break;
9821054
}

0 commit comments

Comments
 (0)