summaryrefslogtreecommitdiffstats
path: root/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs')
-rw-r--r--remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs159
1 files changed, 159 insertions, 0 deletions
diff --git a/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs
new file mode 100644
index 0000000000..675626353c
--- /dev/null
+++ b/remote/webdriver-bidi/modules/windowglobal/browsingContext.sys.mjs
@@ -0,0 +1,159 @@
+/* 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 { WindowGlobalBiDiModule } from "chrome://remote/content/webdriver-bidi/modules/WindowGlobalBiDiModule.sys.mjs";
+
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+ LoadListener: "chrome://remote/content/shared/listeners/LoadListener.sys.mjs",
+});
+
+class BrowsingContextModule extends WindowGlobalBiDiModule {
+ #loadListener;
+ #subscribedEvents;
+
+ constructor(messageHandler) {
+ super(messageHandler);
+
+ // Setup the LoadListener as early as possible.
+ this.#loadListener = new lazy.LoadListener(this.messageHandler.window);
+ this.#loadListener.on("DOMContentLoaded", this.#onDOMContentLoaded);
+ this.#loadListener.on("load", this.#onLoad);
+
+ // Set of event names which have active subscriptions.
+ this.#subscribedEvents = new Set();
+ }
+
+ destroy() {
+ this.#loadListener.destroy();
+ this.#subscribedEvents = null;
+ }
+
+ #getNavigationInfo(data) {
+ return {
+ context: this.messageHandler.context,
+ // TODO: The navigation id should be a real id mapped to the navigation.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=1763122
+ navigation: null,
+ timestamp: Date.now(),
+ url: data.target.URL,
+ };
+ }
+
+ #startListening() {
+ if (this.#subscribedEvents.size == 0) {
+ this.#loadListener.startListening();
+ }
+ }
+
+ #stopListening() {
+ if (this.#subscribedEvents.size == 0) {
+ this.#loadListener.stopListening();
+ }
+ }
+
+ #subscribeEvent(event) {
+ switch (event) {
+ case "browsingContext._documentInteractive":
+ this.#startListening();
+ this.#subscribedEvents.add("browsingContext._documentInteractive");
+ break;
+ case "browsingContext.domContentLoaded":
+ this.#startListening();
+ this.#subscribedEvents.add("browsingContext.domContentLoaded");
+ break;
+ case "browsingContext.load":
+ this.#startListening();
+ this.#subscribedEvents.add("browsingContext.load");
+ break;
+ }
+ }
+
+ #unsubscribeEvent(event) {
+ switch (event) {
+ case "browsingContext._documentInteractive":
+ this.#subscribedEvents.delete("browsingContext._documentInteractive");
+ break;
+ case "browsingContext.domContentLoaded":
+ this.#subscribedEvents.delete("browsingContext.domContentLoaded");
+ break;
+ case "browsingContext.load":
+ this.#subscribedEvents.delete("browsingContext.load");
+ break;
+ }
+
+ this.#stopListening();
+ }
+
+ #onDOMContentLoaded = (eventName, data) => {
+ if (this.#subscribedEvents.has("browsingContext._documentInteractive")) {
+ this.messageHandler.emitEvent("browsingContext._documentInteractive", {
+ baseURL: data.target.baseURI,
+ contextId: this.messageHandler.contextId,
+ documentURL: data.target.URL,
+ innerWindowId: this.messageHandler.innerWindowId,
+ readyState: data.target.readyState,
+ });
+ }
+
+ if (this.#subscribedEvents.has("browsingContext.domContentLoaded")) {
+ this.emitEvent(
+ "browsingContext.domContentLoaded",
+ this.#getNavigationInfo(data)
+ );
+ }
+ };
+
+ #onLoad = (eventName, data) => {
+ if (this.#subscribedEvents.has("browsingContext.load")) {
+ this.emitEvent("browsingContext.load", this.#getNavigationInfo(data));
+ }
+ };
+
+ /**
+ * Internal commands
+ */
+
+ _applySessionData(params) {
+ // TODO: Bug 1775231. Move this logic to a shared module or an abstract
+ // class.
+ const { category } = params;
+ if (category === "event") {
+ const filteredSessionData = params.sessionData.filter(item =>
+ this.messageHandler.matchesContext(item.contextDescriptor)
+ );
+ for (const event of this.#subscribedEvents.values()) {
+ const hasSessionItem = filteredSessionData.some(
+ item => item.value === event
+ );
+ // If there are no session items for this context, we should unsubscribe from the event.
+ if (!hasSessionItem) {
+ this.#unsubscribeEvent(event);
+ }
+ }
+
+ // Subscribe to all events, which have an item in SessionData.
+ for (const { value } of filteredSessionData) {
+ this.#subscribeEvent(value);
+ }
+ }
+ }
+
+ _getBaseURL() {
+ return this.messageHandler.window.document.baseURI;
+ }
+
+ _getScreenshotRect() {
+ const win = this.messageHandler.window;
+ return new DOMRect(
+ win.pageXOffset,
+ win.pageYOffset,
+ win.innerWidth,
+ win.innerHeight
+ );
+ }
+}
+
+export const browsingContext = BrowsingContextModule;