richard pushed to branch tor-browser-115.7.0esr-13.5-1 at The Tor Project / Applications / Tor Browser

Commits:

16 changed files:

Changes:

  • browser/components/torpreferences/content/bridgeQrDialog.js
    1
    +"use strict";
    
    2
    +
    
    3
    +const { QRCode } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/QRCode.sys.mjs"
    
    5
    +);
    
    6
    +
    
    7
    +const { TorStrings } = ChromeUtils.importESModule(
    
    8
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    9
    +);
    
    10
    +
    
    11
    +window.addEventListener(
    
    12
    +  "DOMContentLoaded",
    
    13
    +  () => {
    
    14
    +    const bridgeString = window.arguments[0];
    
    15
    +
    
    16
    +    document.documentElement.setAttribute(
    
    17
    +      "title",
    
    18
    +      TorStrings.settings.scanQrTitle
    
    19
    +    );
    
    20
    +    const target = document.getElementById("bridgeQr-target");
    
    21
    +    const style = window.getComputedStyle(target);
    
    22
    +    const width = style.width.substr(0, style.width.length - 2);
    
    23
    +    const height = style.height.substr(0, style.height.length - 2);
    
    24
    +    new QRCode(target, {
    
    25
    +      text: bridgeString,
    
    26
    +      width,
    
    27
    +      height,
    
    28
    +      colorDark: style.color,
    
    29
    +      colorLight: style.backgroundColor,
    
    30
    +      document,
    
    31
    +    });
    
    32
    +  },
    
    33
    +  { once: true }
    
    34
    +);

  • browser/components/torpreferences/content/bridgeQrDialog.mjs deleted
    1
    -import { QRCode } from "resource://gre/modules/QRCode.sys.mjs";
    
    2
    -
    
    3
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    4
    -
    
    5
    -export class BridgeQrDialog {
    
    6
    -  constructor() {
    
    7
    -    this._bridgeString = "";
    
    8
    -  }
    
    9
    -
    
    10
    -  static get selectors() {
    
    11
    -    return {
    
    12
    -      target: "#bridgeQr-target",
    
    13
    -    };
    
    14
    -  }
    
    15
    -
    
    16
    -  _populateXUL(window, dialog) {
    
    17
    -    dialog.parentElement.setAttribute("title", TorStrings.settings.scanQrTitle);
    
    18
    -    const target = dialog.querySelector(BridgeQrDialog.selectors.target);
    
    19
    -    const style = window.getComputedStyle(target);
    
    20
    -    const width = style.width.substr(0, style.width.length - 2);
    
    21
    -    const height = style.height.substr(0, style.height.length - 2);
    
    22
    -    new QRCode(target, {
    
    23
    -      text: this._bridgeString,
    
    24
    -      width,
    
    25
    -      height,
    
    26
    -      colorDark: style.color,
    
    27
    -      colorLight: style.backgroundColor,
    
    28
    -      document: window.document,
    
    29
    -    });
    
    30
    -  }
    
    31
    -
    
    32
    -  init(window, dialog) {
    
    33
    -    this._populateXUL(window, dialog);
    
    34
    -  }
    
    35
    -
    
    36
    -  openDialog(gSubDialog, bridgeString) {
    
    37
    -    this._bridgeString = bridgeString;
    
    38
    -    gSubDialog.open(
    
    39
    -      "chrome://browser/content/torpreferences/bridgeQrDialog.xhtml",
    
    40
    -      { features: "resizable=yes" },
    
    41
    -      this
    
    42
    -    );
    
    43
    -  }
    
    44
    -}

  • browser/components/torpreferences/content/bridgeQrDialog.xhtml
    ... ... @@ -9,6 +9,8 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="bridgeQr-dialog" buttons="accept">
    
    12
    +    <script src="chrome://browser/content/torpreferences/bridgeQrDialog.js" />
    
    13
    +
    
    12 14
         <html:div>
    
    13 15
           <html:div id="bridgeQr">
    
    14 16
             <html:div id="bridgeQr-target" />
    
    ... ... @@ -16,16 +18,5 @@
    16 18
             <html:div id="bridgeQr-onion" />
    
    17 19
           </html:div>
    
    18 20
         </html:div>
    
    19
    -    <script type="application/javascript">
    
    20
    -      <![CDATA[
    
    21
    -          "use strict";
    
    22
    -
    
    23
    -          let dialogObject = window.arguments[0];
    
    24
    -          document.addEventListener("DOMContentLoaded", () => {
    
    25
    -            let dialogElement = document.getElementById("bridgeQr-dialog");
    
    26
    -            dialogObject.init(window, dialogElement);
    
    27
    -          });
    
    28
    -        ]]>
    
    29
    -    </script>
    
    30 21
       </dialog>
    
    31 22
     </window>

  • browser/components/torpreferences/content/builtinBridgeDialog.mjsbrowser/components/torpreferences/content/builtinBridgeDialog.js
    1
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    2
    -
    
    3
    -import {
    
    4
    -  TorSettings,
    
    5
    -  TorBridgeSource,
    
    6
    -} from "resource://gre/modules/TorSettings.sys.mjs";
    
    7
    -
    
    8
    -import {
    
    9
    -  TorConnect,
    
    10
    -  TorConnectTopics,
    
    11
    -} from "resource://gre/modules/TorConnect.sys.mjs";
    
    12
    -
    
    13
    -export class BuiltinBridgeDialog {
    
    14
    -  /**
    
    15
    -   * Create a new instance.
    
    16
    -   *
    
    17
    -   * @param {Function} onSubmit - A callback for when the user accepts the
    
    18
    -   *   dialog selection.
    
    19
    -   */
    
    20
    -  constructor(onSubmit) {
    
    21
    -    this.onSubmit = onSubmit;
    
    22
    -    this._acceptButton = null;
    
    23
    -    this._radioGroup = null;
    
    24
    -  }
    
    25
    -
    
    26
    -  _populateXUL(window, dialog) {
    
    27
    -    const dialogWin = dialog.parentElement;
    
    28
    -    dialogWin.setAttribute("title", TorStrings.settings.builtinBridgeHeader);
    
    29
    -
    
    30
    -    dialog.querySelector(
    
    31
    -      "#torPreferences-builtinBridge-description"
    
    1
    +"use strict";
    
    2
    +
    
    3
    +const { TorStrings } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    5
    +);
    
    6
    +
    
    7
    +const { TorSettings, TorBridgeSource } = ChromeUtils.importESModule(
    
    8
    +  "resource://gre/modules/TorSettings.sys.mjs"
    
    9
    +);
    
    10
    +
    
    11
    +const { TorConnect, TorConnectTopics } = ChromeUtils.importESModule(
    
    12
    +  "resource://gre/modules/TorConnect.sys.mjs"
    
    13
    +);
    
    14
    +
    
    15
    +const gBuiltinBridgeDialog = {
    
    16
    +  init() {
    
    17
    +    this._result = window.arguments[0];
    
    18
    +
    
    19
    +    document.documentElement.setAttribute(
    
    20
    +      "title",
    
    21
    +      TorStrings.settings.builtinBridgeHeader
    
    22
    +    );
    
    23
    +
    
    24
    +    document.getElementById(
    
    25
    +      "torPreferences-builtinBridge-description"
    
    32 26
         ).textContent = TorStrings.settings.builtinBridgeDescription2;
    
    33 27
     
    
    34
    -    this._radioGroup = dialog.querySelector(
    
    35
    -      "#torPreferences-builtinBridge-typeSelection"
    
    28
    +    this._radioGroup = document.getElementById(
    
    29
    +      "torPreferences-builtinBridge-typeSelection"
    
    36 30
         );
    
    37 31
     
    
    38 32
         const typeStrings = {
    
    ... ... @@ -84,8 +78,12 @@ export class BuiltinBridgeDialog {
    84 78
         }
    
    85 79
     
    
    86 80
         this._radioGroup.addEventListener("select", () => this.onSelectChange());
    
    81
    +
    
    82
    +    const dialog = document.getElementById(
    
    83
    +      "torPreferences-builtinBridge-dialog"
    
    84
    +    );
    
    87 85
         dialog.addEventListener("dialogaccept", () => {
    
    88
    -      this.onSubmit(this._radioGroup.value, TorConnect.canBeginBootstrap);
    
    86
    +      this._result.accepted = true;
    
    89 87
         });
    
    90 88
     
    
    91 89
         this._acceptButton = dialog.getButton("accept");
    
    ... ... @@ -94,20 +92,28 @@ export class BuiltinBridgeDialog {
    94 92
     
    
    95 93
         this.onSelectChange();
    
    96 94
         this.onAcceptStateChange();
    
    97
    -  }
    
    95
    +  },
    
    96
    +
    
    97
    +  uninit() {
    
    98
    +    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    99
    +  },
    
    98 100
     
    
    99 101
       onSelectChange() {
    
    100
    -    this._acceptButton.disabled = !this._radioGroup.value;
    
    101
    -  }
    
    102
    +    const value = this._radioGroup.value;
    
    103
    +    this._acceptButton.disabled = !value;
    
    104
    +    this._result.type = value;
    
    105
    +  },
    
    102 106
     
    
    103 107
       onAcceptStateChange() {
    
    108
    +    const connect = TorConnect.canBeginBootstrap;
    
    109
    +    this._result.connect = connect;
    
    104 110
         this._acceptButton.setAttribute(
    
    105 111
           "label",
    
    106
    -      TorConnect.canBeginBootstrap
    
    112
    +      connect
    
    107 113
             ? TorStrings.settings.bridgeButtonConnect
    
    108 114
             : TorStrings.settings.bridgeButtonAccept
    
    109 115
         );
    
    110
    -  }
    
    116
    +  },
    
    111 117
     
    
    112 118
       observe(subject, topic, data) {
    
    113 119
         switch (topic) {
    
    ... ... @@ -115,27 +121,20 @@ export class BuiltinBridgeDialog {
    115 121
             this.onAcceptStateChange();
    
    116 122
             break;
    
    117 123
         }
    
    118
    -  }
    
    119
    -
    
    120
    -  init(window, aDialog) {
    
    121
    -    this._populateXUL(window, aDialog);
    
    122
    -  }
    
    123
    -
    
    124
    -  close() {
    
    125
    -    // Unregister our observer topics.
    
    126
    -    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    127
    -  }
    
    128
    -
    
    129
    -  openDialog(gSubDialog) {
    
    130
    -    gSubDialog.open(
    
    131
    -      "chrome://browser/content/torpreferences/builtinBridgeDialog.xhtml",
    
    132
    -      {
    
    133
    -        features: "resizable=yes",
    
    134
    -        closingCallback: () => {
    
    135
    -          this.close();
    
    136
    -        },
    
    124
    +  },
    
    125
    +};
    
    126
    +
    
    127
    +window.addEventListener(
    
    128
    +  "DOMContentLoaded",
    
    129
    +  () => {
    
    130
    +    gBuiltinBridgeDialog.init();
    
    131
    +    window.addEventListener(
    
    132
    +      "unload",
    
    133
    +      () => {
    
    134
    +        gBuiltinBridgeDialog.uninit();
    
    137 135
           },
    
    138
    -      this
    
    136
    +      { once: true }
    
    139 137
         );
    
    140
    -  }
    
    141
    -}
    138
    +  },
    
    139
    +  { once: true }
    
    140
    +);

  • browser/components/torpreferences/content/builtinBridgeDialog.xhtml
    ... ... @@ -9,6 +9,8 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="torPreferences-builtinBridge-dialog" buttons="accept,cancel">
    
    12
    +    <script src="chrome://browser/content/torpreferences/builtinBridgeDialog.js" />
    
    13
    +
    
    12 14
         <description id="torPreferences-builtinBridge-description"> </description>
    
    13 15
         <radiogroup id="torPreferences-builtinBridge-typeSelection">
    
    14 16
           <vbox class="builtin-bridges-option">
    
    ... ... @@ -78,16 +80,5 @@
    78 80
             </html:div>
    
    79 81
           </vbox>
    
    80 82
         </radiogroup>
    
    81
    -    <script type="application/javascript">
    
    82
    -      <![CDATA[
    
    83
    -          "use strict";
    
    84
    -
    
    85
    -          let builtinBridgeDialog = window.arguments[0];
    
    86
    -          document.addEventListener("DOMContentLoaded", () => {
    
    87
    -            let dialog = document.getElementById("torPreferences-builtinBridge-dialog");
    
    88
    -            builtinBridgeDialog.init(window, dialog);
    
    89
    -          });
    
    90
    -        ]]>
    
    91
    -    </script>
    
    92 83
       </dialog>
    
    93 84
     </window>

  • browser/components/torpreferences/content/connectionPane.js
    ... ... @@ -24,30 +24,6 @@ const { TorProviderBuilder, TorProviderTopics } = ChromeUtils.importESModule(
    24 24
     const { TorConnect, TorConnectTopics, TorConnectState, TorCensorshipLevel } =
    
    25 25
       ChromeUtils.importESModule("resource://gre/modules/TorConnect.sys.mjs");
    
    26 26
     
    
    27
    -const { TorLogDialog } = ChromeUtils.importESModule(
    
    28
    -  "chrome://browser/content/torpreferences/torLogDialog.mjs"
    
    29
    -);
    
    30
    -
    
    31
    -const { ConnectionSettingsDialog } = ChromeUtils.importESModule(
    
    32
    -  "chrome://browser/content/torpreferences/connectionSettingsDialog.mjs"
    
    33
    -);
    
    34
    -
    
    35
    -const { BridgeQrDialog } = ChromeUtils.importESModule(
    
    36
    -  "chrome://browser/content/torpreferences/bridgeQrDialog.mjs"
    
    37
    -);
    
    38
    -
    
    39
    -const { BuiltinBridgeDialog } = ChromeUtils.importESModule(
    
    40
    -  "chrome://browser/content/torpreferences/builtinBridgeDialog.mjs"
    
    41
    -);
    
    42
    -
    
    43
    -const { RequestBridgeDialog } = ChromeUtils.importESModule(
    
    44
    -  "chrome://browser/content/torpreferences/requestBridgeDialog.mjs"
    
    45
    -);
    
    46
    -
    
    47
    -const { ProvideBridgeDialog } = ChromeUtils.importESModule(
    
    48
    -  "chrome://browser/content/torpreferences/provideBridgeDialog.mjs"
    
    49
    -);
    
    50
    -
    
    51 27
     const { MoatRPC } = ChromeUtils.importESModule(
    
    52 28
       "resource://gre/modules/Moat.sys.mjs"
    
    53 29
     );
    
    ... ... @@ -114,6 +90,19 @@ async function getConnectedBridgeId() {
    114 90
       return bridge?.fingerprint ?? null;
    
    115 91
     }
    
    116 92
     
    
    93
    +/**
    
    94
    + * Show the bridge QR to the user.
    
    95
    + *
    
    96
    + * @param {string} bridgeString - The string to use in the QR.
    
    97
    + */
    
    98
    +function showBridgeQr(bridgeString) {
    
    99
    +  gSubDialog.open(
    
    100
    +    "chrome://browser/content/torpreferences/bridgeQrDialog.xhtml",
    
    101
    +    { features: "resizable=yes" },
    
    102
    +    bridgeString
    
    103
    +  );
    
    104
    +}
    
    105
    +
    
    117 106
     // TODO: Instead of aria-live in the DOM, use the proposed ariaNotify
    
    118 107
     // API if it gets accepted into firefox and works with screen readers.
    
    119 108
     // See https://github.com/WICG/proposals/issues/112
    
    ... ... @@ -803,8 +792,7 @@ const gBridgeGrid = {
    803 792
             if (!bridgeLine) {
    
    804 793
               return;
    
    805 794
             }
    
    806
    -        const dialog = new BridgeQrDialog();
    
    807
    -        dialog.openDialog(gSubDialog, bridgeLine);
    
    795
    +        showBridgeQr(bridgeLine);
    
    808 796
           });
    
    809 797
         row.menu
    
    810 798
           .querySelector(".tor-bridges-options-copy-one-menu-item")
    
    ... ... @@ -1571,8 +1559,7 @@ const gBridgeSettings = {
    1571 1559
         if (!this._canQRBridges) {
    
    1572 1560
           return;
    
    1573 1561
         }
    
    1574
    -    const dialog = new BridgeQrDialog();
    
    1575
    -    dialog.openDialog(gSubDialog, this._bridgeStrings);
    
    1562
    +    showBridgeQr(this._bridgeStrings);
    
    1576 1563
       },
    
    1577 1564
     
    
    1578 1565
       /**
    
    ... ... @@ -2136,96 +2123,133 @@ const gConnectionPane = (function () {
    2136 2123
         },
    
    2137 2124
     
    
    2138 2125
         /**
    
    2139
    -     * Save and apply settings, then optionally open about:torconnect and start
    
    2140
    -     * bootstrapping.
    
    2126
    +     * Open a bridge dialog that will change the users bridges.
    
    2141 2127
          *
    
    2142
    -     * @param {fucntion} changes - The changes to make.
    
    2143
    -     * @param {boolean} connect - Whether to open about:torconnect and start
    
    2144
    -     *   bootstrapping if possible.
    
    2128
    +     * @param {string} url - The url of the dialog to open.
    
    2129
    +     * @param {Function} onAccept - The method to call if the bridge dialog was
    
    2130
    +     *   accepted by the user. This will be passed a "result" object containing
    
    2131
    +     *   data set by the dialog. This should return a promise that resolves once
    
    2132
    +     *   the bridge settings have been set, or null if the settings have not
    
    2133
    +     *   been applied.
    
    2145 2134
          */
    
    2146
    -    async saveBridgeSettings(changes, connect) {
    
    2147
    -      // TODO: Move focus into the bridge area.
    
    2148
    -      // dialog.ownerGlobal.addEventListener("unload", () => gCurrentBridgesArea.takeFocus(), { once: true });
    
    2149
    -      // or use closedCallback in gSubDialog.open()
    
    2150
    -      setTorSettings(changes);
    
    2151
    -
    
    2152
    -      if (!connect) {
    
    2153
    -        return;
    
    2154
    -      }
    
    2155
    -
    
    2156
    -      // The bridge dialog button is "connect" when Tor is not bootstrapped,
    
    2157
    -      // so do the connect.
    
    2135
    +    openBridgeDialog(url, onAccept) {
    
    2136
    +      const result = { accepted: false, connect: false };
    
    2137
    +      let savedSettings = null;
    
    2138
    +      gSubDialog.open(
    
    2139
    +        url,
    
    2140
    +        {
    
    2141
    +          features: "resizable=yes",
    
    2142
    +          closingCallback: () => {
    
    2143
    +            if (!result.accepted) {
    
    2144
    +              return;
    
    2145
    +            }
    
    2146
    +            savedSettings = onAccept(result);
    
    2147
    +            if (!savedSettings) {
    
    2148
    +              // No change in settings.
    
    2149
    +              return;
    
    2150
    +            }
    
    2151
    +            if (!result.connect) {
    
    2152
    +              // Do not open about:torconnect.
    
    2153
    +              return;
    
    2154
    +            }
    
    2158 2155
     
    
    2159
    -      // Start Bootstrapping, which should use the configured bridges.
    
    2160
    -      // NOTE: We do this regardless of any previous TorConnect Error.
    
    2161
    -      if (TorConnect.canBeginBootstrap) {
    
    2162
    -        TorConnect.beginBootstrap();
    
    2163
    -      }
    
    2164
    -      // Open "about:torconnect".
    
    2165
    -      // FIXME: If there has been a previous bootstrapping error then
    
    2166
    -      // "about:torconnect" will be trying to get the user to use
    
    2167
    -      // AutoBootstrapping. It is not set up to handle a forced direct
    
    2168
    -      // entry to plain Bootstrapping from this dialog so the UI will not
    
    2169
    -      // be aligned. In particular the
    
    2170
    -      // AboutTorConnect.uiState.bootstrapCause will be aligned to
    
    2171
    -      // whatever was shown previously in "about:torconnect" instead.
    
    2172
    -      TorConnect.openTorConnect();
    
    2156
    +            // Wait until the settings are applied before bootstrapping.
    
    2157
    +            savedSettings.then(() => {
    
    2158
    +              // The bridge dialog button is "connect" when Tor is not
    
    2159
    +              // bootstrapped, so do the connect.
    
    2160
    +
    
    2161
    +              // Start Bootstrapping, which should use the configured bridges.
    
    2162
    +              // NOTE: We do this regardless of any previous TorConnect Error.
    
    2163
    +              if (TorConnect.canBeginBootstrap) {
    
    2164
    +                TorConnect.beginBootstrap();
    
    2165
    +              }
    
    2166
    +              // Open "about:torconnect".
    
    2167
    +              // FIXME: If there has been a previous bootstrapping error then
    
    2168
    +              // "about:torconnect" will be trying to get the user to use
    
    2169
    +              // AutoBootstrapping. It is not set up to handle a forced direct
    
    2170
    +              // entry to plain Bootstrapping from this dialog so the UI will
    
    2171
    +              // not be aligned. In particular the
    
    2172
    +              // AboutTorConnect.uiState.bootstrapCause will be aligned to
    
    2173
    +              // whatever was shown previously in "about:torconnect" instead.
    
    2174
    +              TorConnect.openTorConnect();
    
    2175
    +            });
    
    2176
    +          },
    
    2177
    +          // closedCallback should be called after gSubDialog has already
    
    2178
    +          // re-assigned focus back to the document.
    
    2179
    +          closedCallback: () => {
    
    2180
    +            if (!savedSettings) {
    
    2181
    +              return;
    
    2182
    +            }
    
    2183
    +            // Wait until the settings have changed, so that the UI could
    
    2184
    +            // respond, then move focus.
    
    2185
    +            savedSettings.then(() => gCurrentBridgesArea.takeFocus());
    
    2186
    +          },
    
    2187
    +        },
    
    2188
    +        result
    
    2189
    +      );
    
    2173 2190
         },
    
    2174 2191
     
    
    2175 2192
         onAddBuiltinBridge() {
    
    2176
    -      const builtinBridgeDialog = new BuiltinBridgeDialog(
    
    2177
    -        (bridgeType, connect) => {
    
    2178
    -          this.saveBridgeSettings(() => {
    
    2193
    +      this.openBridgeDialog(
    
    2194
    +        "chrome://browser/content/torpreferences/builtinBridgeDialog.xhtml",
    
    2195
    +        result => {
    
    2196
    +          if (!result.type) {
    
    2197
    +            return null;
    
    2198
    +          }
    
    2199
    +          return setTorSettings(() => {
    
    2179 2200
                 TorSettings.bridges.enabled = true;
    
    2180 2201
                 TorSettings.bridges.source = TorBridgeSource.BuiltIn;
    
    2181
    -            TorSettings.bridges.builtin_type = bridgeType;
    
    2182
    -          }, connect);
    
    2202
    +            TorSettings.bridges.builtin_type = result.type;
    
    2203
    +          });
    
    2183 2204
             }
    
    2184 2205
           );
    
    2185
    -      builtinBridgeDialog.openDialog(gSubDialog);
    
    2186 2206
         },
    
    2187 2207
     
    
    2188 2208
         // called when the request bridge button is activated
    
    2189 2209
         onRequestBridge() {
    
    2190
    -      const requestBridgeDialog = new RequestBridgeDialog(
    
    2191
    -        (aBridges, connect) => {
    
    2192
    -          if (!aBridges.length) {
    
    2193
    -            return;
    
    2210
    +      this.openBridgeDialog(
    
    2211
    +        "chrome://browser/content/torpreferences/requestBridgeDialog.xhtml",
    
    2212
    +        result => {
    
    2213
    +          if (!result.bridges?.length) {
    
    2214
    +            return null;
    
    2194 2215
               }
    
    2195
    -
    
    2196
    -          const bridgeStrings = aBridges.join("\n");
    
    2197
    -
    
    2198
    -          this.saveBridgeSettings(() => {
    
    2216
    +          return setTorSettings(() => {
    
    2199 2217
                 TorSettings.bridges.enabled = true;
    
    2200 2218
                 TorSettings.bridges.source = TorBridgeSource.BridgeDB;
    
    2201
    -            TorSettings.bridges.bridge_strings = bridgeStrings;
    
    2202
    -          }, connect);
    
    2219
    +            TorSettings.bridges.bridge_strings = result.bridges.join("\n");
    
    2220
    +          });
    
    2203 2221
             }
    
    2204 2222
           );
    
    2205
    -      requestBridgeDialog.openDialog(gSubDialog);
    
    2206 2223
         },
    
    2207 2224
     
    
    2208 2225
         onAddBridgeManually() {
    
    2209
    -      const provideBridgeDialog = new ProvideBridgeDialog(
    
    2210
    -        (aBridgeString, connect) => {
    
    2211
    -          this.saveBridgeSettings(() => {
    
    2226
    +      this.openBridgeDialog(
    
    2227
    +        "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
    
    2228
    +        result => {
    
    2229
    +          if (!result.bridgeStrings) {
    
    2230
    +            return null;
    
    2231
    +          }
    
    2232
    +          return setTorSettings(() => {
    
    2212 2233
                 TorSettings.bridges.enabled = true;
    
    2213 2234
                 TorSettings.bridges.source = TorBridgeSource.UserProvided;
    
    2214
    -            TorSettings.bridges.bridge_strings = aBridgeString;
    
    2215
    -          }, connect);
    
    2235
    +            TorSettings.bridges.bridge_strings = result.bridgeStrings;
    
    2236
    +          });
    
    2216 2237
             }
    
    2217 2238
           );
    
    2218
    -      provideBridgeDialog.openDialog(gSubDialog);
    
    2219 2239
         },
    
    2220 2240
     
    
    2221 2241
         onAdvancedSettings() {
    
    2222
    -      const connectionSettingsDialog = new ConnectionSettingsDialog();
    
    2223
    -      connectionSettingsDialog.openDialog(gSubDialog);
    
    2242
    +      gSubDialog.open(
    
    2243
    +        "chrome://browser/content/torpreferences/connectionSettingsDialog.xhtml",
    
    2244
    +        { features: "resizable=yes" }
    
    2245
    +      );
    
    2224 2246
         },
    
    2225 2247
     
    
    2226 2248
         onViewTorLogs() {
    
    2227
    -      const torLogDialog = new TorLogDialog();
    
    2228
    -      torLogDialog.openDialog(gSubDialog);
    
    2249
    +      gSubDialog.open(
    
    2250
    +        "chrome://browser/content/torpreferences/torLogDialog.xhtml",
    
    2251
    +        { features: "resizable=yes" }
    
    2252
    +      );
    
    2229 2253
         },
    
    2230 2254
       };
    
    2231 2255
       return retval;
    

  • browser/components/torpreferences/content/connectionSettingsDialog.mjsbrowser/components/torpreferences/content/connectionSettingsDialog.js
    1
    -import {
    
    2
    -  TorSettings,
    
    3
    -  TorProxyType,
    
    4
    -} from "resource://gre/modules/TorSettings.sys.mjs";
    
    1
    +"use strict";
    
    5 2
     
    
    6
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    3
    +const { TorSettings, TorProxyType } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/TorSettings.sys.mjs"
    
    5
    +);
    
    7 6
     
    
    8
    -export class ConnectionSettingsDialog {
    
    9
    -  constructor() {
    
    10
    -    this._dialog = null;
    
    11
    -    this._useProxyCheckbox = null;
    
    12
    -    this._proxyTypeLabel = null;
    
    13
    -    this._proxyTypeMenulist = null;
    
    14
    -    this._proxyAddressLabel = null;
    
    15
    -    this._proxyAddressTextbox = null;
    
    16
    -    this._proxyPortLabel = null;
    
    17
    -    this._proxyPortTextbox = null;
    
    18
    -    this._proxyUsernameLabel = null;
    
    19
    -    this._proxyUsernameTextbox = null;
    
    20
    -    this._proxyPasswordLabel = null;
    
    21
    -    this._proxyPasswordTextbox = null;
    
    22
    -    this._useFirewallCheckbox = null;
    
    23
    -    this._allowedPortsLabel = null;
    
    24
    -    this._allowedPortsTextbox = null;
    
    25
    -  }
    
    7
    +const { TorStrings } = ChromeUtils.importESModule(
    
    8
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    9
    +);
    
    26 10
     
    
    27
    -  static get selectors() {
    
    28
    -    return {
    
    29
    -      header: "#torPreferences-connection-header",
    
    30
    -      useProxyCheckbox: "checkbox#torPreferences-connection-toggleProxy",
    
    31
    -      proxyTypeLabel: "label#torPreferences-localProxy-type",
    
    32
    -      proxyTypeList: "menulist#torPreferences-localProxy-builtinList",
    
    33
    -      proxyAddressLabel: "label#torPreferences-localProxy-address",
    
    34
    -      proxyAddressTextbox: "input#torPreferences-localProxy-textboxAddress",
    
    35
    -      proxyPortLabel: "label#torPreferences-localProxy-port",
    
    36
    -      proxyPortTextbox: "input#torPreferences-localProxy-textboxPort",
    
    37
    -      proxyUsernameLabel: "label#torPreferences-localProxy-username",
    
    38
    -      proxyUsernameTextbox: "input#torPreferences-localProxy-textboxUsername",
    
    39
    -      proxyPasswordLabel: "label#torPreferences-localProxy-password",
    
    40
    -      proxyPasswordTextbox: "input#torPreferences-localProxy-textboxPassword",
    
    41
    -      useFirewallCheckbox: "checkbox#torPreferences-connection-toggleFirewall",
    
    42
    -      firewallAllowedPortsLabel: "label#torPreferences-connection-allowedPorts",
    
    43
    -      firewallAllowedPortsTextbox:
    
    44
    -        "input#torPreferences-connection-textboxAllowedPorts",
    
    45
    -    };
    
    46
    -  }
    
    11
    +const gConnectionSettingsDialog = {
    
    12
    +  _useProxyCheckbox: null,
    
    13
    +  _proxyTypeLabel: null,
    
    14
    +  _proxyTypeMenulist: null,
    
    15
    +  _proxyAddressLabel: null,
    
    16
    +  _proxyAddressTextbox: null,
    
    17
    +  _proxyPortLabel: null,
    
    18
    +  _proxyPortTextbox: null,
    
    19
    +  _proxyUsernameLabel: null,
    
    20
    +  _proxyUsernameTextbox: null,
    
    21
    +  _proxyPasswordLabel: null,
    
    22
    +  _proxyPasswordTextbox: null,
    
    23
    +  _useFirewallCheckbox: null,
    
    24
    +  _allowedPortsLabel: null,
    
    25
    +  _allowedPortsTextbox: null,
    
    26
    +
    
    27
    +  selectors: {
    
    28
    +    header: "#torPreferences-connection-header",
    
    29
    +    useProxyCheckbox: "checkbox#torPreferences-connection-toggleProxy",
    
    30
    +    proxyTypeLabel: "label#torPreferences-localProxy-type",
    
    31
    +    proxyTypeList: "menulist#torPreferences-localProxy-builtinList",
    
    32
    +    proxyAddressLabel: "label#torPreferences-localProxy-address",
    
    33
    +    proxyAddressTextbox: "input#torPreferences-localProxy-textboxAddress",
    
    34
    +    proxyPortLabel: "label#torPreferences-localProxy-port",
    
    35
    +    proxyPortTextbox: "input#torPreferences-localProxy-textboxPort",
    
    36
    +    proxyUsernameLabel: "label#torPreferences-localProxy-username",
    
    37
    +    proxyUsernameTextbox: "input#torPreferences-localProxy-textboxUsername",
    
    38
    +    proxyPasswordLabel: "label#torPreferences-localProxy-password",
    
    39
    +    proxyPasswordTextbox: "input#torPreferences-localProxy-textboxPassword",
    
    40
    +    useFirewallCheckbox: "checkbox#torPreferences-connection-toggleFirewall",
    
    41
    +    firewallAllowedPortsLabel: "label#torPreferences-connection-allowedPorts",
    
    42
    +    firewallAllowedPortsTextbox:
    
    43
    +      "input#torPreferences-connection-textboxAllowedPorts",
    
    44
    +  },
    
    47 45
     
    
    48 46
       // disables the provided list of elements
    
    49 47
       _setElementsDisabled(elements, disabled) {
    
    50 48
         for (let currentElement of elements) {
    
    51 49
           currentElement.disabled = disabled;
    
    52 50
         }
    
    53
    -  }
    
    51
    +  },
    
    54 52
     
    
    55
    -  _populateXUL(window, aDialog) {
    
    56
    -    const selectors = ConnectionSettingsDialog.selectors;
    
    53
    +  init() {
    
    54
    +    const selectors = this.selectors;
    
    57 55
     
    
    58
    -    this._dialog = aDialog;
    
    59
    -    const dialogWin = this._dialog.parentElement;
    
    60
    -    dialogWin.setAttribute(
    
    56
    +    document.documentElement.setAttribute(
    
    61 57
           "title",
    
    62 58
           TorStrings.settings.connectionSettingsDialogTitle
    
    63 59
         );
    
    64
    -    this._dialog.querySelector(selectors.header).textContent =
    
    60
    +    document.querySelector(selectors.header).textContent =
    
    65 61
           TorStrings.settings.connectionSettingsDialogHeader;
    
    66 62
     
    
    67 63
         // Local Proxy
    
    68
    -    this._useProxyCheckbox = this._dialog.querySelector(
    
    69
    -      selectors.useProxyCheckbox
    
    70
    -    );
    
    64
    +    this._useProxyCheckbox = document.querySelector(selectors.useProxyCheckbox);
    
    71 65
         this._useProxyCheckbox.setAttribute(
    
    72 66
           "label",
    
    73 67
           TorStrings.settings.useLocalProxy
    
    ... ... @@ -76,7 +70,7 @@ export class ConnectionSettingsDialog {
    76 70
           const checked = this._useProxyCheckbox.checked;
    
    77 71
           this.onToggleProxy(checked);
    
    78 72
         });
    
    79
    -    this._proxyTypeLabel = this._dialog.querySelector(selectors.proxyTypeLabel);
    
    73
    +    this._proxyTypeLabel = document.querySelector(selectors.proxyTypeLabel);
    
    80 74
         this._proxyTypeLabel.setAttribute("value", TorStrings.settings.proxyType);
    
    81 75
     
    
    82 76
         let mockProxies = [
    
    ... ... @@ -90,9 +84,7 @@ export class ConnectionSettingsDialog {
    90 84
           },
    
    91 85
           { value: TorProxyType.HTTPS, label: TorStrings.settings.proxyTypeHTTP },
    
    92 86
         ];
    
    93
    -    this._proxyTypeMenulist = this._dialog.querySelector(
    
    94
    -      selectors.proxyTypeList
    
    95
    -    );
    
    87
    +    this._proxyTypeMenulist = document.querySelector(selectors.proxyTypeList);
    
    96 88
         this._proxyTypeMenulist.addEventListener("command", e => {
    
    97 89
           const value = this._proxyTypeMenulist.value;
    
    98 90
           this.onSelectProxyType(value);
    
    ... ... @@ -104,14 +96,14 @@ export class ConnectionSettingsDialog {
    104 96
           this._proxyTypeMenulist.querySelector("menupopup").appendChild(menuEntry);
    
    105 97
         }
    
    106 98
     
    
    107
    -    this._proxyAddressLabel = this._dialog.querySelector(
    
    99
    +    this._proxyAddressLabel = document.querySelector(
    
    108 100
           selectors.proxyAddressLabel
    
    109 101
         );
    
    110 102
         this._proxyAddressLabel.setAttribute(
    
    111 103
           "value",
    
    112 104
           TorStrings.settings.proxyAddress
    
    113 105
         );
    
    114
    -    this._proxyAddressTextbox = this._dialog.querySelector(
    
    106
    +    this._proxyAddressTextbox = document.querySelector(
    
    115 107
           selectors.proxyAddressTextbox
    
    116 108
         );
    
    117 109
         this._proxyAddressTextbox.setAttribute(
    
    ... ... @@ -129,33 +121,31 @@ export class ConnectionSettingsDialog {
    129 121
             }
    
    130 122
           }
    
    131 123
         });
    
    132
    -    this._proxyPortLabel = this._dialog.querySelector(selectors.proxyPortLabel);
    
    124
    +    this._proxyPortLabel = document.querySelector(selectors.proxyPortLabel);
    
    133 125
         this._proxyPortLabel.setAttribute("value", TorStrings.settings.proxyPort);
    
    134
    -    this._proxyPortTextbox = this._dialog.querySelector(
    
    135
    -      selectors.proxyPortTextbox
    
    136
    -    );
    
    137
    -    this._proxyUsernameLabel = this._dialog.querySelector(
    
    126
    +    this._proxyPortTextbox = document.querySelector(selectors.proxyPortTextbox);
    
    127
    +    this._proxyUsernameLabel = document.querySelector(
    
    138 128
           selectors.proxyUsernameLabel
    
    139 129
         );
    
    140 130
         this._proxyUsernameLabel.setAttribute(
    
    141 131
           "value",
    
    142 132
           TorStrings.settings.proxyUsername
    
    143 133
         );
    
    144
    -    this._proxyUsernameTextbox = this._dialog.querySelector(
    
    134
    +    this._proxyUsernameTextbox = document.querySelector(
    
    145 135
           selectors.proxyUsernameTextbox
    
    146 136
         );
    
    147 137
         this._proxyUsernameTextbox.setAttribute(
    
    148 138
           "placeholder",
    
    149 139
           TorStrings.settings.proxyUsernamePasswordPlaceholder
    
    150 140
         );
    
    151
    -    this._proxyPasswordLabel = this._dialog.querySelector(
    
    141
    +    this._proxyPasswordLabel = document.querySelector(
    
    152 142
           selectors.proxyPasswordLabel
    
    153 143
         );
    
    154 144
         this._proxyPasswordLabel.setAttribute(
    
    155 145
           "value",
    
    156 146
           TorStrings.settings.proxyPassword
    
    157 147
         );
    
    158
    -    this._proxyPasswordTextbox = this._dialog.querySelector(
    
    148
    +    this._proxyPasswordTextbox = document.querySelector(
    
    159 149
           selectors.proxyPasswordTextbox
    
    160 150
         );
    
    161 151
         this._proxyPasswordTextbox.setAttribute(
    
    ... ... @@ -174,7 +164,7 @@ export class ConnectionSettingsDialog {
    174 164
         }
    
    175 165
     
    
    176 166
         // Local firewall
    
    177
    -    this._useFirewallCheckbox = this._dialog.querySelector(
    
    167
    +    this._useFirewallCheckbox = document.querySelector(
    
    178 168
           selectors.useFirewallCheckbox
    
    179 169
         );
    
    180 170
         this._useFirewallCheckbox.setAttribute(
    
    ... ... @@ -185,14 +175,14 @@ export class ConnectionSettingsDialog {
    185 175
           const checked = this._useFirewallCheckbox.checked;
    
    186 176
           this.onToggleFirewall(checked);
    
    187 177
         });
    
    188
    -    this._allowedPortsLabel = this._dialog.querySelector(
    
    178
    +    this._allowedPortsLabel = document.querySelector(
    
    189 179
           selectors.firewallAllowedPortsLabel
    
    190 180
         );
    
    191 181
         this._allowedPortsLabel.setAttribute(
    
    192 182
           "value",
    
    193 183
           TorStrings.settings.allowedPorts
    
    194 184
         );
    
    195
    -    this._allowedPortsTextbox = this._dialog.querySelector(
    
    185
    +    this._allowedPortsTextbox = document.querySelector(
    
    196 186
           selectors.firewallAllowedPortsTextbox
    
    197 187
         );
    
    198 188
         this._allowedPortsTextbox.setAttribute(
    
    ... ... @@ -207,10 +197,11 @@ export class ConnectionSettingsDialog {
    207 197
             TorSettings.firewall.allowed_ports.join(", ");
    
    208 198
         }
    
    209 199
     
    
    210
    -    this._dialog.addEventListener("dialogaccept", e => {
    
    200
    +    const dialog = document.getElementById("torPreferences-connection-dialog");
    
    201
    +    dialog.addEventListener("dialogaccept", e => {
    
    211 202
           this._applySettings();
    
    212 203
         });
    
    213
    -  }
    
    204
    +  },
    
    214 205
     
    
    215 206
       // callback when proxy is toggled
    
    216 207
       onToggleProxy(enabled) {
    
    ... ... @@ -235,7 +226,7 @@ export class ConnectionSettingsDialog {
    235 226
         if (enabled) {
    
    236 227
           this.onSelectProxyType(this._proxyTypeMenulist.value);
    
    237 228
         }
    
    238
    -  }
    
    229
    +  },
    
    239 230
     
    
    240 231
       // callback when proxy type is changed
    
    241 232
       onSelectProxyType(value) {
    
    ... ... @@ -308,7 +299,7 @@ export class ConnectionSettingsDialog {
    308 299
             break;
    
    309 300
           }
    
    310 301
         }
    
    311
    -  }
    
    302
    +  },
    
    312 303
     
    
    313 304
       // callback when firewall proxy is toggled
    
    314 305
       onToggleFirewall(enabled) {
    
    ... ... @@ -319,7 +310,7 @@ export class ConnectionSettingsDialog {
    319 310
           [this._allowedPortsLabel, this._allowedPortsTextbox],
    
    320 311
           disabled
    
    321 312
         );
    
    322
    -  }
    
    313
    +  },
    
    323 314
     
    
    324 315
       // pushes settings from UI to tor
    
    325 316
       _applySettings() {
    
    ... ... @@ -372,17 +363,13 @@ export class ConnectionSettingsDialog {
    372 363
     
    
    373 364
         TorSettings.saveToPrefs();
    
    374 365
         TorSettings.applySettings();
    
    375
    -  }
    
    376
    -
    
    377
    -  init(window, aDialog) {
    
    378
    -    this._populateXUL(window, aDialog);
    
    379
    -  }
    
    366
    +  },
    
    367
    +};
    
    380 368
     
    
    381
    -  openDialog(gSubDialog) {
    
    382
    -    gSubDialog.open(
    
    383
    -      "chrome://browser/content/torpreferences/connectionSettingsDialog.xhtml",
    
    384
    -      { features: "resizable=yes" },
    
    385
    -      this
    
    386
    -    );
    
    387
    -  }
    
    388
    -}
    369
    +window.addEventListener(
    
    370
    +  "DOMContentLoaded",
    
    371
    +  () => {
    
    372
    +    gConnectionSettingsDialog.init();
    
    373
    +  },
    
    374
    +  { once: true }
    
    375
    +);

  • browser/components/torpreferences/content/connectionSettingsDialog.xhtml
    ... ... @@ -9,6 +9,8 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="torPreferences-connection-dialog" buttons="accept,cancel">
    
    12
    +    <script src="chrome://browser/content/torpreferences/connectionSettingsDialog.js" />
    
    13
    +
    
    12 14
         <html:h3 id="torPreferences-connection-header">&#8203;</html:h3>
    
    13 15
         <!-- Local Proxy -->
    
    14 16
         <checkbox id="torPreferences-connection-toggleProxy" label="&#8203;" />
    
    ... ... @@ -78,16 +80,5 @@
    78 80
             />
    
    79 81
           </hbox>
    
    80 82
         </box>
    
    81
    -    <script type="application/javascript">
    
    82
    -      <![CDATA[
    
    83
    -          "use strict";
    
    84
    -
    
    85
    -          let connectionSettingsDialog = window.arguments[0];
    
    86
    -          document.addEventListener("DOMContentLoaded", () => {
    
    87
    -            let dialog = document.getElementById("torPreferences-connection-dialog");
    
    88
    -            connectionSettingsDialog.init(window, dialog);
    
    89
    -          });
    
    90
    -        ]]>
    
    91
    -    </script>
    
    92 83
       </dialog>
    
    93 84
     </window>

  • browser/components/torpreferences/content/provideBridgeDialog.mjsbrowser/components/torpreferences/content/provideBridgeDialog.js
    1
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    2
    -
    
    3
    -import {
    
    4
    -  TorSettings,
    
    5
    -  TorBridgeSource,
    
    6
    -} from "resource://gre/modules/TorSettings.sys.mjs";
    
    7
    -
    
    8
    -import {
    
    9
    -  TorConnect,
    
    10
    -  TorConnectTopics,
    
    11
    -} from "resource://gre/modules/TorConnect.sys.mjs";
    
    12
    -
    
    13
    -export class ProvideBridgeDialog {
    
    14
    -  constructor(onSubmit) {
    
    15
    -    this.onSubmit = onSubmit;
    
    16
    -    this._dialog = null;
    
    17
    -    this._textarea = null;
    
    18
    -    this._acceptButton = null;
    
    19
    -  }
    
    20
    -
    
    21
    -  static get selectors() {
    
    22
    -    return {
    
    23
    -      description: "#torPreferences-provideBridge-description",
    
    24
    -      textarea: "#torPreferences-provideBridge-textarea",
    
    25
    -    };
    
    26
    -  }
    
    27
    -
    
    28
    -  _populateXUL(window, aDialog) {
    
    29
    -    const selectors = ProvideBridgeDialog.selectors;
    
    30
    -
    
    31
    -    const openHelp = () => {
    
    1
    +"use strict";
    
    2
    +
    
    3
    +const { TorStrings } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    5
    +);
    
    6
    +
    
    7
    +const { TorSettings, TorBridgeSource } = ChromeUtils.importESModule(
    
    8
    +  "resource://gre/modules/TorSettings.sys.mjs"
    
    9
    +);
    
    10
    +
    
    11
    +const { TorConnect, TorConnectTopics } = ChromeUtils.importESModule(
    
    12
    +  "resource://gre/modules/TorConnect.sys.mjs"
    
    13
    +);
    
    14
    +
    
    15
    +const gProvideBridgeDialog = {
    
    16
    +  init() {
    
    17
    +    this._result = window.arguments[0];
    
    18
    +
    
    19
    +    document.documentElement.setAttribute(
    
    20
    +      "title",
    
    21
    +      TorStrings.settings.provideBridgeTitleAdd
    
    22
    +    );
    
    23
    +    const learnMore = document.createXULElement("label");
    
    24
    +    learnMore.className = "learnMore text-link";
    
    25
    +    learnMore.setAttribute("is", "text-link");
    
    26
    +    learnMore.setAttribute("value", TorStrings.settings.learnMore);
    
    27
    +    learnMore.addEventListener("click", () => {
    
    32 28
           window.top.openTrustedLinkIn(
    
    33 29
             TorStrings.settings.learnMoreBridgesURL,
    
    34 30
             "tab"
    
    35 31
           );
    
    36
    -    };
    
    32
    +    });
    
    37 33
     
    
    38
    -    this._dialog = aDialog;
    
    39
    -    const dialogWin = this._dialog.parentElement;
    
    40
    -    dialogWin.setAttribute("title", TorStrings.settings.provideBridgeTitleAdd);
    
    41
    -    const learnMore = window.document.createXULElement("label");
    
    42
    -    learnMore.className = "learnMore text-link";
    
    43
    -    learnMore.setAttribute("is", "text-link");
    
    44
    -    learnMore.setAttribute("value", TorStrings.settings.learnMore);
    
    45
    -    learnMore.addEventListener("click", openHelp);
    
    46
    -    const descr = this._dialog.querySelector(selectors.description);
    
    47
    -    descr.textContent = "";
    
    48 34
         const pieces = TorStrings.settings.provideBridgeDescription.split("%S");
    
    49
    -    descr.append(pieces[0], learnMore, pieces[1] || "");
    
    50
    -    this._textarea = this._dialog.querySelector(selectors.textarea);
    
    35
    +    document
    
    36
    +      .getElementById("torPreferences-provideBridge-description")
    
    37
    +      .replaceChildren(pieces[0], learnMore, pieces[1] || "");
    
    38
    +
    
    39
    +    this._textarea = document.getElementById(
    
    40
    +      "torPreferences-provideBridge-textarea"
    
    41
    +    );
    
    51 42
         this._textarea.setAttribute(
    
    52 43
           "placeholder",
    
    53 44
           TorStrings.settings.provideBridgePlaceholder
    
    ... ... @@ -58,32 +49,44 @@ export class ProvideBridgeDialog {
    58 49
           this._textarea.value = TorSettings.bridges.bridge_strings.join("\n");
    
    59 50
         }
    
    60 51
     
    
    61
    -    this._dialog.addEventListener("dialogaccept", e => {
    
    62
    -      this.onSubmit(this._textarea.value, TorConnect.canBeginBootstrap);
    
    52
    +    const dialog = document.getElementById(
    
    53
    +      "torPreferences-provideBridge-dialog"
    
    54
    +    );
    
    55
    +    dialog.addEventListener("dialogaccept", e => {
    
    56
    +      this._result.accepted = true;
    
    63 57
         });
    
    64 58
     
    
    65
    -    this._acceptButton = this._dialog.getButton("accept");
    
    59
    +    this._acceptButton = dialog.getButton("accept");
    
    66 60
     
    
    67 61
         Services.obs.addObserver(this, TorConnectTopics.StateChange);
    
    68 62
     
    
    69 63
         this.onValueChange();
    
    70 64
         this.onAcceptStateChange();
    
    71
    -  }
    
    65
    +  },
    
    66
    +
    
    67
    +  uninit() {
    
    68
    +    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    69
    +  },
    
    72 70
     
    
    73 71
       onValueChange() {
    
    74 72
         // TODO: Do some proper value parsing and error reporting. See
    
    75 73
         // tor-browser#40552.
    
    76
    -    this._acceptButton.disabled = !this._textarea.value.trim();
    
    77
    -  }
    
    74
    +    const value = this._textarea.value.trim();
    
    75
    +    this._acceptButton.disabled = !value;
    
    76
    +    this._result.bridgeStrings = value;
    
    77
    +  },
    
    78 78
     
    
    79 79
       onAcceptStateChange() {
    
    80
    +    const connect = TorConnect.canBeginBootstrap;
    
    81
    +    this._result.connect = connect;
    
    82
    +
    
    80 83
         this._acceptButton.setAttribute(
    
    81 84
           "label",
    
    82
    -      TorConnect.canBeginBootstrap
    
    85
    +      connect
    
    83 86
             ? TorStrings.settings.bridgeButtonConnect
    
    84 87
             : TorStrings.settings.bridgeButtonAccept
    
    85 88
         );
    
    86
    -  }
    
    89
    +  },
    
    87 90
     
    
    88 91
       observe(subject, topic, data) {
    
    89 92
         switch (topic) {
    
    ... ... @@ -91,27 +94,20 @@ export class ProvideBridgeDialog {
    91 94
             this.onAcceptStateChange();
    
    92 95
             break;
    
    93 96
         }
    
    94
    -  }
    
    95
    -
    
    96
    -  init(window, aDialog) {
    
    97
    -    this._populateXUL(window, aDialog);
    
    98
    -  }
    
    99
    -
    
    100
    -  close() {
    
    101
    -    // Unregister our observer topics.
    
    102
    -    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    103
    -  }
    
    104
    -
    
    105
    -  openDialog(gSubDialog) {
    
    106
    -    gSubDialog.open(
    
    107
    -      "chrome://browser/content/torpreferences/provideBridgeDialog.xhtml",
    
    108
    -      {
    
    109
    -        features: "resizable=yes",
    
    110
    -        closingCallback: () => {
    
    111
    -          this.close();
    
    112
    -        },
    
    97
    +  },
    
    98
    +};
    
    99
    +
    
    100
    +window.addEventListener(
    
    101
    +  "DOMContentLoaded",
    
    102
    +  () => {
    
    103
    +    gProvideBridgeDialog.init();
    
    104
    +    window.addEventListener(
    
    105
    +      "unload",
    
    106
    +      () => {
    
    107
    +        gProvideBridgeDialog.uninit();
    
    113 108
           },
    
    114
    -      this
    
    109
    +      { once: true }
    
    115 110
         );
    
    116
    -  }
    
    117
    -}
    111
    +  },
    
    112
    +  { once: true }
    
    113
    +);

  • browser/components/torpreferences/content/provideBridgeDialog.xhtml
    ... ... @@ -9,6 +9,8 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="torPreferences-provideBridge-dialog" buttons="accept,cancel">
    
    12
    +    <script src="chrome://browser/content/torpreferences/provideBridgeDialog.js" />
    
    13
    +
    
    12 14
         <description>
    
    13 15
           <html:div id="torPreferences-provideBridge-description"
    
    14 16
             >&#8203;<br />&#8203;</html:div
    
    ... ... @@ -19,16 +21,5 @@
    19 21
           multiline="true"
    
    20 22
           rows="3"
    
    21 23
         />
    
    22
    -    <script type="application/javascript">
    
    23
    -      <![CDATA[
    
    24
    -          "use strict";
    
    25
    -
    
    26
    -          let provideBridgeDialog = window.arguments[0];
    
    27
    -          document.addEventListener("DOMContentLoaded", () => {
    
    28
    -            let dialog = document.getElementById("torPreferences-provideBridge-dialog");
    
    29
    -            provideBridgeDialog.init(window, dialog);
    
    30
    -          });
    
    31
    -        ]]>
    
    32
    -    </script>
    
    33 24
       </dialog>
    
    34 25
     </window>

  • browser/components/torpreferences/content/requestBridgeDialog.mjsbrowser/components/torpreferences/content/requestBridgeDialog.js
    1
    -import { BridgeDB } from "resource://gre/modules/BridgeDB.sys.mjs";
    
    2
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    3
    -
    
    4
    -import {
    
    5
    -  TorConnect,
    
    6
    -  TorConnectTopics,
    
    7
    -} from "resource://gre/modules/TorConnect.sys.mjs";
    
    8
    -
    
    9
    -export class RequestBridgeDialog {
    
    10
    -  constructor(onSubmit) {
    
    11
    -    this.onSubmit = onSubmit;
    
    12
    -    this._dialog = null;
    
    13
    -    this._submitButton = null;
    
    14
    -    this._dialogHeader = null;
    
    15
    -    this._captchaImage = null;
    
    16
    -    this._captchaEntryTextbox = null;
    
    17
    -    this._captchaRefreshButton = null;
    
    18
    -    this._incorrectCaptchaHbox = null;
    
    19
    -    this._incorrectCaptchaLabel = null;
    
    20
    -  }
    
    21
    -
    
    22
    -  static get selectors() {
    
    23
    -    return {
    
    24
    -      dialogHeader: "h3#torPreferences-requestBridge-header",
    
    25
    -      captchaImage: "image#torPreferences-requestBridge-captchaImage",
    
    26
    -      captchaEntryTextbox: "input#torPreferences-requestBridge-captchaTextbox",
    
    27
    -      refreshCaptchaButton:
    
    28
    -        "button#torPreferences-requestBridge-refreshCaptchaButton",
    
    29
    -      incorrectCaptchaHbox:
    
    30
    -        "hbox#torPreferences-requestBridge-incorrectCaptchaHbox",
    
    31
    -      incorrectCaptchaLabel:
    
    32
    -        "label#torPreferences-requestBridge-incorrectCaptchaError",
    
    33
    -    };
    
    34
    -  }
    
    35
    -
    
    36
    -  _populateXUL(window, dialog) {
    
    37
    -    const selectors = RequestBridgeDialog.selectors;
    
    1
    +"use strict";
    
    2
    +
    
    3
    +const { BridgeDB } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/BridgeDB.sys.mjs"
    
    5
    +);
    
    6
    +const { TorStrings } = ChromeUtils.importESModule(
    
    7
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    8
    +);
    
    9
    +
    
    10
    +const { TorConnect, TorConnectTopics } = ChromeUtils.importESModule(
    
    11
    +  "resource://gre/modules/TorConnect.sys.mjs"
    
    12
    +);
    
    13
    +
    
    14
    +const gRequestBridgeDialog = {
    
    15
    +  selectors: {
    
    16
    +    dialogHeader: "h3#torPreferences-requestBridge-header",
    
    17
    +    captchaImage: "image#torPreferences-requestBridge-captchaImage",
    
    18
    +    captchaEntryTextbox: "input#torPreferences-requestBridge-captchaTextbox",
    
    19
    +    refreshCaptchaButton:
    
    20
    +      "button#torPreferences-requestBridge-refreshCaptchaButton",
    
    21
    +    incorrectCaptchaHbox:
    
    22
    +      "hbox#torPreferences-requestBridge-incorrectCaptchaHbox",
    
    23
    +    incorrectCaptchaLabel:
    
    24
    +      "label#torPreferences-requestBridge-incorrectCaptchaError",
    
    25
    +  },
    
    26
    +
    
    27
    +  init() {
    
    28
    +    this._result = window.arguments[0];
    
    29
    +
    
    30
    +    const selectors = this.selectors;
    
    31
    +
    
    32
    +    this._dialog = document.getElementById(
    
    33
    +      "torPreferences-requestBridge-dialog"
    
    34
    +    );
    
    38 35
     
    
    39
    -    this._dialog = dialog;
    
    40
    -    const dialogWin = dialog.parentElement;
    
    41
    -    dialogWin.setAttribute(
    
    36
    +    document.documentElement.setAttribute(
    
    42 37
           "title",
    
    43 38
           TorStrings.settings.requestBridgeDialogTitle
    
    44 39
         );
    
    ... ... @@ -104,16 +99,24 @@ export class RequestBridgeDialog {
    104 99
     
    
    105 100
         Services.obs.addObserver(this, TorConnectTopics.StateChange);
    
    106 101
         this.onAcceptStateChange();
    
    107
    -  }
    
    102
    +  },
    
    103
    +
    
    104
    +  uninit() {
    
    105
    +    BridgeDB.close();
    
    106
    +    // Unregister our observer topics.
    
    107
    +    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    108
    +  },
    
    108 109
     
    
    109 110
       onAcceptStateChange() {
    
    111
    +    const connect = TorConnect.canBeginBootstrap;
    
    112
    +    this._result.connect = connect;
    
    110 113
         this._submitButton.setAttribute(
    
    111 114
           "label",
    
    112
    -      TorConnect.canBeginBootstrap
    
    115
    +      connect
    
    113 116
             ? TorStrings.settings.bridgeButtonConnect
    
    114 117
             : TorStrings.settings.submitCaptcha
    
    115 118
         );
    
    116
    -  }
    
    119
    +  },
    
    117 120
     
    
    118 121
       observe(subject, topic, data) {
    
    119 122
         switch (topic) {
    
    ... ... @@ -121,7 +124,7 @@ export class RequestBridgeDialog {
    121 124
             this.onAcceptStateChange();
    
    122 125
             break;
    
    123 126
         }
    
    124
    -  }
    
    127
    +  },
    
    125 128
     
    
    126 129
       _setcaptchaImage(uri) {
    
    127 130
         if (uri != this._captchaImage.src) {
    
    ... ... @@ -131,27 +134,17 @@ export class RequestBridgeDialog {
    131 134
           this._captchaEntryTextbox.focus();
    
    132 135
           this._captchaEntryTextbox.select();
    
    133 136
         }
    
    134
    -  }
    
    137
    +  },
    
    135 138
     
    
    136 139
       _setUIDisabled(disabled) {
    
    137 140
         this._submitButton.disabled = this._captchaGuessIsEmpty() || disabled;
    
    138 141
         this._captchaEntryTextbox.disabled = disabled;
    
    139 142
         this._captchaRefreshButton.disabled = disabled;
    
    140
    -  }
    
    143
    +  },
    
    141 144
     
    
    142 145
       _captchaGuessIsEmpty() {
    
    143 146
         return this._captchaEntryTextbox.value == "";
    
    144
    -  }
    
    145
    -
    
    146
    -  init(window, dialog) {
    
    147
    -    this._populateXUL(window, dialog);
    
    148
    -  }
    
    149
    -
    
    150
    -  close() {
    
    151
    -    BridgeDB.close();
    
    152
    -    // Unregister our observer topics.
    
    153
    -    Services.obs.removeObserver(this, TorConnectTopics.StateChange);
    
    154
    -  }
    
    147
    +  },
    
    155 148
     
    
    156 149
       /*
    
    157 150
         Event Handlers
    
    ... ... @@ -169,8 +162,9 @@ export class RequestBridgeDialog {
    169 162
     
    
    170 163
         BridgeDB.submitCaptchaGuess(captchaText)
    
    171 164
           .then(aBridges => {
    
    172
    -        if (aBridges) {
    
    173
    -          this.onSubmit(aBridges, TorConnect.canBeginBootstrap);
    
    165
    +        if (aBridges && aBridges.length) {
    
    166
    +          this._result.accepted = true;
    
    167
    +          this._result.bridges = aBridges;
    
    174 168
               this._submitButton.disabled = false;
    
    175 169
               // This was successful, but use cancelDialog() to close, since
    
    176 170
               // we intercept the `dialogaccept` event.
    
    ... ... @@ -186,7 +180,7 @@ export class RequestBridgeDialog {
    186 180
             this._incorrectCaptchaHbox.style.visibility = "visible";
    
    187 181
             console.log(aError);
    
    188 182
           });
    
    189
    -  }
    
    183
    +  },
    
    190 184
     
    
    191 185
       onRefreshCaptcha() {
    
    192 186
         this._setUIDisabled(true);
    
    ... ... @@ -198,18 +192,20 @@ export class RequestBridgeDialog {
    198 192
         BridgeDB.requestNewCaptchaImage().then(uri => {
    
    199 193
           this._setcaptchaImage(uri);
    
    200 194
         });
    
    201
    -  }
    
    202
    -
    
    203
    -  openDialog(gSubDialog) {
    
    204
    -    gSubDialog.open(
    
    205
    -      "chrome://browser/content/torpreferences/requestBridgeDialog.xhtml",
    
    206
    -      {
    
    207
    -        features: "resizable=yes",
    
    208
    -        closingCallback: () => {
    
    209
    -          this.close();
    
    210
    -        },
    
    195
    +  },
    
    196
    +};
    
    197
    +
    
    198
    +window.addEventListener(
    
    199
    +  "DOMContentLoaded",
    
    200
    +  () => {
    
    201
    +    gRequestBridgeDialog.init();
    
    202
    +    window.addEventListener(
    
    203
    +      "unload",
    
    204
    +      () => {
    
    205
    +        gRequestBridgeDialog.uninit();
    
    211 206
           },
    
    212
    -      this
    
    207
    +      { once: true }
    
    213 208
         );
    
    214
    -  }
    
    215
    -}
    209
    +  },
    
    210
    +  { once: true }
    
    211
    +);

  • browser/components/torpreferences/content/requestBridgeDialog.xhtml
    ... ... @@ -9,6 +9,8 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="torPreferences-requestBridge-dialog" buttons="accept,cancel">
    
    12
    +    <script src="chrome://browser/content/torpreferences/requestBridgeDialog.js" />
    
    13
    +
    
    12 14
         <!-- ok, so &#8203; is a zero-width space. We need to have *something* in the innerText so that XUL knows how tall the
    
    13 15
            title node is so that it can determine how large to make the dialog element's inner draw area. If we have nothing
    
    14 16
            in the innerText, then it collapse to 0 height, and the contents of the dialog ends up partially hidden >:( -->
    
    ... ... @@ -30,16 +32,5 @@
    30 32
           <image id="torPreferences-requestBridge-errorIcon" />
    
    31 33
           <label id="torPreferences-requestBridge-incorrectCaptchaError" flex="1" />
    
    32 34
         </hbox>
    
    33
    -    <script type="application/javascript">
    
    34
    -      <![CDATA[
    
    35
    -          "use strict";
    
    36
    -
    
    37
    -          let requestBridgeDialog = window.arguments[0];
    
    38
    -          document.addEventListener("DOMContentLoaded", () => {
    
    39
    -            let dialog = document.getElementById("torPreferences-requestBridge-dialog");
    
    40
    -            requestBridgeDialog.init(window, dialog);
    
    41
    -          });
    
    42
    -        ]]>
    
    43
    -    </script>
    
    44 35
       </dialog>
    
    45 36
     </window>

  • browser/components/torpreferences/content/torLogDialog.js
    1
    +"use strict";
    
    2
    +
    
    3
    +const { setTimeout, clearTimeout } = ChromeUtils.importESModule(
    
    4
    +  "resource://gre/modules/Timer.sys.mjs"
    
    5
    +);
    
    6
    +
    
    7
    +const { TorProviderBuilder } = ChromeUtils.importESModule(
    
    8
    +  "resource://gre/modules/TorProviderBuilder.sys.mjs"
    
    9
    +);
    
    10
    +const { TorStrings } = ChromeUtils.importESModule(
    
    11
    +  "resource://gre/modules/TorStrings.sys.mjs"
    
    12
    +);
    
    13
    +
    
    14
    +window.addEventListener(
    
    15
    +  "DOMContentLoaded",
    
    16
    +  () => {
    
    17
    +    document.documentElement.setAttribute(
    
    18
    +      "title",
    
    19
    +      TorStrings.settings.torLogDialogTitle
    
    20
    +    );
    
    21
    +
    
    22
    +    const dialog = document.getElementById("torPreferences-torLog-dialog");
    
    23
    +    const copyLogButton = dialog.getButton("extra1");
    
    24
    +    copyLogButton.setAttribute("label", TorStrings.settings.copyLog);
    
    25
    +
    
    26
    +    const logText = document.getElementById(
    
    27
    +      "torPreferences-torDialog-textarea"
    
    28
    +    );
    
    29
    +
    
    30
    +    let restoreButtonTimeout = null;
    
    31
    +    copyLogButton.addEventListener("command", () => {
    
    32
    +      // Copy tor log messages to the system clipboard.
    
    33
    +      let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
    
    34
    +        Ci.nsIClipboardHelper
    
    35
    +      );
    
    36
    +      clipboard.copyString(logText.value);
    
    37
    +
    
    38
    +      const label = copyLogButton.querySelector("label");
    
    39
    +      label.setAttribute("value", TorStrings.settings.copied);
    
    40
    +      copyLogButton.classList.add("primary");
    
    41
    +
    
    42
    +      const RESTORE_TIME = 1200;
    
    43
    +      if (restoreButtonTimeout !== null) {
    
    44
    +        clearTimeout(restoreButtonTimeout);
    
    45
    +      }
    
    46
    +      restoreButtonTimeout = setTimeout(() => {
    
    47
    +        label.setAttribute("value", TorStrings.settings.copyLog);
    
    48
    +        copyLogButton.classList.remove("primary");
    
    49
    +        restoreButtonTimeout = null;
    
    50
    +      }, RESTORE_TIME);
    
    51
    +    });
    
    52
    +
    
    53
    +    // A waiting state should not be needed at this point.
    
    54
    +    // Also, we probably cannot even arrive here if the provider failed to
    
    55
    +    // initialize, otherwise we could use a try/catch, and write the exception
    
    56
    +    // text in the logs, instead.
    
    57
    +    TorProviderBuilder.build().then(
    
    58
    +      provider => (logText.value = provider.getLog())
    
    59
    +    );
    
    60
    +  },
    
    61
    +  { once: true }
    
    62
    +);

  • browser/components/torpreferences/content/torLogDialog.mjs deleted
    1
    -import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs";
    
    2
    -
    
    3
    -import { TorProviderBuilder } from "resource://gre/modules/TorProviderBuilder.sys.mjs";
    
    4
    -import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
    
    5
    -
    
    6
    -export class TorLogDialog {
    
    7
    -  constructor() {
    
    8
    -    this._dialog = null;
    
    9
    -    this._logTextarea = null;
    
    10
    -    this._copyLogButton = null;
    
    11
    -    this._restoreButtonTimeout = null;
    
    12
    -  }
    
    13
    -
    
    14
    -  static get selectors() {
    
    15
    -    return {
    
    16
    -      copyLogButton: "extra1",
    
    17
    -      logTextarea: "textarea#torPreferences-torDialog-textarea",
    
    18
    -    };
    
    19
    -  }
    
    20
    -
    
    21
    -  async _populateXUL(aDialog) {
    
    22
    -    this._dialog = aDialog;
    
    23
    -    const dialogWin = this._dialog.parentElement;
    
    24
    -    dialogWin.setAttribute("title", TorStrings.settings.torLogDialogTitle);
    
    25
    -
    
    26
    -    this._logTextarea = this._dialog.querySelector(
    
    27
    -      TorLogDialog.selectors.logTextarea
    
    28
    -    );
    
    29
    -
    
    30
    -    this._copyLogButton = this._dialog.getButton(
    
    31
    -      TorLogDialog.selectors.copyLogButton
    
    32
    -    );
    
    33
    -    this._copyLogButton.setAttribute("label", TorStrings.settings.copyLog);
    
    34
    -    this._copyLogButton.addEventListener("command", () => {
    
    35
    -      this.copyTorLog();
    
    36
    -      const label = this._copyLogButton.querySelector("label");
    
    37
    -      label.setAttribute("value", TorStrings.settings.copied);
    
    38
    -      this._copyLogButton.classList.add("primary");
    
    39
    -
    
    40
    -      const RESTORE_TIME = 1200;
    
    41
    -      if (this._restoreButtonTimeout !== null) {
    
    42
    -        clearTimeout(this._restoreButtonTimeout);
    
    43
    -      }
    
    44
    -      this._restoreButtonTimeout = setTimeout(() => {
    
    45
    -        label.setAttribute("value", TorStrings.settings.copyLog);
    
    46
    -        this._copyLogButton.classList.remove("primary");
    
    47
    -        this._restoreButtonTimeout = null;
    
    48
    -      }, RESTORE_TIME);
    
    49
    -    });
    
    50
    -
    
    51
    -    // A waiting state should not be needed at this point.
    
    52
    -    // Also, we probably cannot even arrive here if the provider failed to
    
    53
    -    // initialize, otherwise we could use a try/catch, and write the exception
    
    54
    -    // text in the logs, instead.
    
    55
    -    const provider = await TorProviderBuilder.build();
    
    56
    -    this._logTextarea.value = provider.getLog();
    
    57
    -  }
    
    58
    -
    
    59
    -  init(window, aDialog) {
    
    60
    -    this._populateXUL(aDialog);
    
    61
    -  }
    
    62
    -
    
    63
    -  copyTorLog() {
    
    64
    -    // Copy tor log messages to the system clipboard.
    
    65
    -    let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
    
    66
    -      Ci.nsIClipboardHelper
    
    67
    -    );
    
    68
    -    clipboard.copyString(this._logTextarea.value);
    
    69
    -  }
    
    70
    -
    
    71
    -  openDialog(gSubDialog) {
    
    72
    -    gSubDialog.open(
    
    73
    -      "chrome://browser/content/torpreferences/torLogDialog.xhtml",
    
    74
    -      { features: "resizable=yes" },
    
    75
    -      this
    
    76
    -    );
    
    77
    -  }
    
    78
    -}

  • browser/components/torpreferences/content/torLogDialog.xhtml
    ... ... @@ -9,21 +9,12 @@
    9 9
       xmlns:html="http://www.w3.org/1999/xhtml"
    
    10 10
     >
    
    11 11
       <dialog id="torPreferences-torLog-dialog" buttons="accept,extra1">
    
    12
    +    <script src="chrome://browser/content/torpreferences/torLogDialog.js" />
    
    13
    +
    
    12 14
         <html:textarea
    
    13 15
           id="torPreferences-torDialog-textarea"
    
    14 16
           multiline="true"
    
    15 17
           readonly="true"
    
    16 18
         />
    
    17
    -    <script type="application/javascript">
    
    18
    -      <![CDATA[
    
    19
    -          "use strict";
    
    20
    -
    
    21
    -          let torLogDialog = window.arguments[0];
    
    22
    -          document.addEventListener("DOMContentLoaded", () => {
    
    23
    -            let dialog = document.getElementById("torPreferences-torLog-dialog");
    
    24
    -            torLogDialog.init(window, dialog);
    
    25
    -          });
    
    26
    -        ]]>
    
    27
    -    </script>
    
    28 19
       </dialog>
    
    29 20
     </window>

  • browser/components/torpreferences/jar.mn
    ... ... @@ -2,19 +2,19 @@ browser.jar:
    2 2
         content/browser/torpreferences/bridge.svg                        (content/bridge.svg)
    
    3 3
         content/browser/torpreferences/bridge-qr.svg                     (content/bridge-qr.svg)
    
    4 4
         content/browser/torpreferences/bridgeQrDialog.xhtml              (content/bridgeQrDialog.xhtml)
    
    5
    -    content/browser/torpreferences/bridgeQrDialog.mjs                (content/bridgeQrDialog.mjs)
    
    5
    +    content/browser/torpreferences/bridgeQrDialog.js                 (content/bridgeQrDialog.js)
    
    6 6
         content/browser/torpreferences/builtinBridgeDialog.xhtml         (content/builtinBridgeDialog.xhtml)
    
    7
    -    content/browser/torpreferences/builtinBridgeDialog.mjs           (content/builtinBridgeDialog.mjs)
    
    7
    +    content/browser/torpreferences/builtinBridgeDialog.js            (content/builtinBridgeDialog.js)
    
    8 8
         content/browser/torpreferences/connectionSettingsDialog.xhtml    (content/connectionSettingsDialog.xhtml)
    
    9
    -    content/browser/torpreferences/connectionSettingsDialog.mjs      (content/connectionSettingsDialog.mjs)
    
    9
    +    content/browser/torpreferences/connectionSettingsDialog.js       (content/connectionSettingsDialog.js)
    
    10 10
         content/browser/torpreferences/network.svg                       (content/network.svg)
    
    11 11
         content/browser/torpreferences/network-broken.svg                (content/network-broken.svg)
    
    12 12
         content/browser/torpreferences/provideBridgeDialog.xhtml         (content/provideBridgeDialog.xhtml)
    
    13
    -    content/browser/torpreferences/provideBridgeDialog.mjs           (content/provideBridgeDialog.mjs)
    
    13
    +    content/browser/torpreferences/provideBridgeDialog.js            (content/provideBridgeDialog.js)
    
    14 14
         content/browser/torpreferences/requestBridgeDialog.xhtml         (content/requestBridgeDialog.xhtml)
    
    15
    -    content/browser/torpreferences/requestBridgeDialog.mjs           (content/requestBridgeDialog.mjs)
    
    15
    +    content/browser/torpreferences/requestBridgeDialog.js            (content/requestBridgeDialog.js)
    
    16 16
         content/browser/torpreferences/connectionCategory.inc.xhtml      (content/connectionCategory.inc.xhtml)
    
    17
    -    content/browser/torpreferences/torLogDialog.mjs                  (content/torLogDialog.mjs)
    
    17
    +    content/browser/torpreferences/torLogDialog.js                   (content/torLogDialog.js)
    
    18 18
         content/browser/torpreferences/torLogDialog.xhtml                (content/torLogDialog.xhtml)
    
    19 19
         content/browser/torpreferences/connectionPane.js                 (content/connectionPane.js)
    
    20 20
         content/browser/torpreferences/connectionPane.xhtml              (content/connectionPane.xhtml)