summaryrefslogtreecommitdiffstats
path: root/browser/extensions/report-site-issue/experimentalAPIs/tabExtras.js
blob: be070896ab168dcc7b11fa3c7c0a0a1ec7aba6b6 (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
/* 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/. */

"use strict";

/* global ExtensionAPI, XPCOMUtils, Services */

XPCOMUtils.defineLazyServiceGetter(
  this,
  "resProto",
  "@mozilla.org/network/protocol;1?name=resource",
  "nsISubstitutingProtocolHandler"
);

this.tabExtras = class extends ExtensionAPI {
  constructor(extension) {
    super(extension);
    this._registerActorModule();
  }

  getAPI(context) {
    const { tabManager } = context.extension;
    return {
      tabExtras: {
        async getWebcompatInfo(tabId) {
          const { browsingContext } = tabManager.get(tabId).browser;
          const actors = gatherActors("ReportSiteIssueHelper", browsingContext);
          const promises = actors.map(actor => actor.sendQuery("GetLog"));
          const logs = await Promise.all(promises);
          const info = await actors[0].sendQuery("GetBlockingStatus");
          info.hasMixedActiveContentBlocked = !!(
            browsingContext.secureBrowserUI.state &
            Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT
          );
          info.hasMixedDisplayContentBlocked = !!(
            browsingContext.secureBrowserUI.state &
            Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT
          );
          info.log = logs
            .flat()
            .sort((a, b) => a.timeStamp - b.timeStamp)
            .map(m => m.message);
          return info;
        },
      },
    };
  }

  onShutdown(isAppShutdown) {
    this._unregisterActorModule();
  }

  _registerActorModule() {
    resProto.setSubstitution(
      "report-site-issue",
      Services.io.newURI(
        "experimentalAPIs/actors/",
        null,
        this.extension.rootURI
      )
    );
    ChromeUtils.registerWindowActor("ReportSiteIssueHelper", {
      child: {
        moduleURI: "resource://report-site-issue/tabExtrasActor.jsm",
      },
      allFrames: true,
    });
  }

  _unregisterActorModule() {
    ChromeUtils.unregisterWindowActor("ReportSiteIssueHelper");
    resProto.setSubstitution("report-site-issue", null);
  }
};

function getActorForBrowsingContext(name, browsingContext) {
  const windowGlobal = browsingContext.currentWindowGlobal;
  return windowGlobal ? windowGlobal.getActor(name) : null;
}

function gatherActors(name, browsingContext) {
  const list = [];

  const actor = getActorForBrowsingContext(name, browsingContext);
  if (actor) {
    list.push(actor);
  }

  for (const child of browsingContext.children) {
    list.push(...gatherActors(name, child));
  }

  return list;
}