summaryrefslogtreecommitdiffstats
path: root/remote/shared/messagehandler/WindowGlobalMessageHandler.sys.mjs
blob: 109bc81d1f5918200a4ca1a951fbf9195117d3f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* 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 {
  ContextDescriptorType,
  MessageHandler,
} from "chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs";

/**
 * A WindowGlobalMessageHandler is dedicated to debugging a single window
 * global. It follows the lifecycle of the corresponding window global and will
 * therefore not survive any navigation. This MessageHandler cannot forward
 * commands further to other MessageHandlers and represents a leaf node in a
 * MessageHandler network.
 */
export class WindowGlobalMessageHandler extends MessageHandler {
  #innerWindowId;

  constructor() {
    super(...arguments);

    this.#innerWindowId = this.context.window.windowGlobalChild.innerWindowId;
  }

  /**
   * Returns the WindowGlobalMessageHandler module path.
   *
   * @return {String}
   */
  static get modulePath() {
    return "windowglobal";
  }

  /**
   * Returns the WindowGlobalMessageHandler type.
   *
   * @return {String}
   */
  static get type() {
    return "WINDOW_GLOBAL";
  }

  /**
   * For WINDOW_GLOBAL MessageHandlers, `context` is a BrowsingContext,
   * and BrowsingContext.id can be used as the context id.
   *
   * @param {BrowsingContext} context
   *     WindowGlobalMessageHandler contexts are expected to be
   *     BrowsingContexts.
   * @return {String}
   *     The browsing context id.
   */
  static getIdFromContext(context) {
    return context.id;
  }

  get innerWindowId() {
    return this.#innerWindowId;
  }

  get window() {
    return this.context.window;
  }

  async applyInitialSessionDataItems(sessionDataItems) {
    if (!Array.isArray(sessionDataItems)) {
      return;
    }

    const destination = {
      type: WindowGlobalMessageHandler.type,
    };

    const sessionDataPromises = sessionDataItems.map(sessionDataItem => {
      const { moduleName, category, contextDescriptor } = sessionDataItem;
      if (!this.matchesContext(contextDescriptor)) {
        return Promise.resolve();
      }

      // Don't apply session data if the module is not present
      // for the destination.
      if (!this.moduleCache.hasModule(moduleName, destination)) {
        return Promise.resolve();
      }

      return this.handleCommand({
        moduleName,
        commandName: "_applySessionData",
        params: {
          category,
          sessionData: sessionDataItems,
        },
        destination,
      });
    });

    await Promise.all(sessionDataPromises);

    // With the session data applied the handler is now ready to be used.
    this.emitEvent("window-global-handler-created", {
      contextId: this.contextId,
      innerWindowId: this.#innerWindowId,
    });
  }

  forwardCommand(command) {
    throw new Error(
      `Cannot forward commands from a "WINDOW_GLOBAL" MessageHandler`
    );
  }

  matchesContext(contextDescriptor) {
    return (
      contextDescriptor.type === ContextDescriptorType.All ||
      (contextDescriptor.type === ContextDescriptorType.TopBrowsingContext &&
        contextDescriptor.id === this.context.browserId)
    );
  }
}