summaryrefslogtreecommitdiffstats
path: root/browser/extensions/report-site-issue/background.js
blob: 8c8234e52f36b08a0f172b285426be4bacce44d0 (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
/* 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";

/* globals browser */

const desktopReporterConfig = {
  src: "desktop-reporter",
  utm_campaign: "report-site-issue-button",
  utm_source: "desktop-reporter",
};

const androidReporterConfig = {
  src: "android-components-reporter",
  utm_campaign: "report-site-issue-button",
  utm_source: "android-components-reporter",
};

const getReporterConfig = (() => {
  let promise;
  return async () => {
    promise ??= new Promise(resolve => {
      browser.permissions
        .contains({ permissions: ["nativeMessaging"] })
        .then(needProductName => {
          if (needProductName) {
            const port = browser.runtime.connectNative(
              "mozacWebcompatReporter"
            );
            port.onMessage.addListener(message => {
              if ("productName" in message) {
                androidReporterConfig.productName = message.productName;
                resolve(androidReporterConfig);

                // For now, setting the productName is the only use for this port, and that's only happening
                // once after startup, so let's disconnect the port when we're done.
                port.disconnect();
              }
            });
          } else {
            resolve(desktopReporterConfig);
          }
        });
    });
    return promise;
  };
})();

async function loadTab(url) {
  const newTab = await browser.tabs.create({ url });
  return new Promise(resolve => {
    const listener = (tabId, changeInfo, tab) => {
      if (
        tabId == newTab.id &&
        tab.url !== "about:blank" &&
        changeInfo.status == "complete"
      ) {
        browser.tabs.onUpdated.removeListener(listener);
        resolve(newTab);
      }
    };
    browser.tabs.onUpdated.addListener(listener);
  });
}

async function captureAndSendReport(tab) {
  const { id, url } = tab;
  try {
    const { endpointUrl, webcompatInfo } =
      await browser.tabExtras.getWebcompatInfo(id);
    const reporterConfig = await getReporterConfig();
    const dataToSend = {
      endpointUrl,
      reportUrl: url,
      reporterConfig,
      webcompatInfo,
    };
    const newTab = await loadTab(endpointUrl);
    browser.tabExtras.sendWebcompatInfo(newTab.id, dataToSend);
  } catch (err) {
    console.error("WebCompat Reporter: unexpected error", err);
  }
}

if ("helpMenu" in browser) {
  // desktop
  browser.helpMenu.onHelpMenuCommand.addListener(captureAndSendReport);
} else {
  // Android
  browser.pageAction.onClicked.addListener(captureAndSendReport);
}