Verified Commit d06a5e26 authored by henry's avatar henry Committed by ma1
Browse files

fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in...

fixup! TB 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection

TB 43328: Improve the Tor log dialog.
parent d3a49585
Loading
Loading
Loading
Loading
+82 −11
Original line number Diff line number Diff line
@@ -4,20 +4,18 @@ const { setTimeout, clearTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);

const { TorProviderBuilder } = ChromeUtils.importESModule(
const { TorProviderBuilder, TorProviderTopics } = ChromeUtils.importESModule(
  "resource://gre/modules/TorProviderBuilder.sys.mjs"
);

window.addEventListener(
  "DOMContentLoaded",
  () => {
const gTorLogDialog = {
  init() {
    const dialog = document.getElementById("torPreferences-torLog-dialog");
    const copyLogButton = dialog.getButton("extra1");
    copyLogButton.setAttribute("data-l10n-id", "tor-log-dialog-copy-button");

    const logText = document.getElementById(
      "torPreferences-torDialog-textarea"
    );
    this._logTable = document.getElementById("tor-log-table");
    this._logBody = document.getElementById("tor-log-body");

    let restoreButtonTimeout = null;
    copyLogButton.addEventListener("command", () => {
@@ -25,7 +23,14 @@ window.addEventListener(
      let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(
        Ci.nsIClipboardHelper
      );
      clipboard.copyString(logText.value);
      // The copied text should match the text content the user would get if
      // they hand-selected the entire table.
      clipboard.copyString(
        Array.from(
          this._logTable.querySelectorAll("td"),
          el => el.textContent
        ).join("\n")
      );

      copyLogButton.setAttribute(
        "data-l10n-id",
@@ -47,13 +52,79 @@ window.addEventListener(
      }, RESTORE_TIME);
    });

    // Intercept the copy event.
    // NOTE: We attach this to the window rather than the _logTable because if
    // the whole table is selected it will not receive the "copy" event.
    window.addEventListener("copy", event => {
      event.preventDefault();
      event.clipboardData.setData(
        "text",
        // By default the selected text will insert "\n\t" between the <td>
        // elements, which separates the timestamp from the message column.
        // We drop this "\t" character, to just keep the "\n".
        window.getSelection().toString().replace(/^\t/gm, "")
      );
    });

    // A waiting state should not be needed at this point.
    // Also, we probably cannot even arrive here if the provider failed to
    // initialize, otherwise we could use a try/catch, and write the exception
    // text in the logs, instead.
    TorProviderBuilder.build().then(
      provider => (logText.value = provider.getLog())
    TorProviderBuilder.build().then(provider => {
      Services.obs.addObserver(this, TorProviderTopics.TorLog);
      window.addEventListener(
        "unload",
        () => {
          Services.obs.removeObserver(this, TorProviderTopics.TorLog);
        },
        { once: true }
      );

      for (const logEntry of provider.getLog()) {
        this.addLogEntry(logEntry, true);
      }
      // Set the initial scroll to the bottom.
      this._logTable.scrollTo({
        top: this._logTable.scrollTopMax,
        behaviour: "instant",
      });
    });
  },

  observe(subject, topic) {
    if (topic === TorProviderTopics.TorLog) {
      this.addLogEntry(subject.wrappedJSObject, false);
    }
  },

  addLogEntry(logEntry, initial) {
    const timeEl = document.createElement("td");
    timeEl.textContent = logEntry.timestamp;
    timeEl.classList.add("time");
    const messageEl = document.createElement("td");
    messageEl.textContent = `[${logEntry.type}] ${logEntry.msg}`;
    messageEl.classList.add("message");

    const row = document.createElement("tr");
    row.append(timeEl, messageEl);

    // If this is a new entry, and we are currently scrolled to the bottom (with
    // a 6px allowance) we keep the scroll position at the bottom to "follow"
    // the updates.
    const scrollToBottom =
      !initial && this._logTable.scrollTop >= this._logTable.scrollTopMax - 6;

    this._logBody.append(row);
    if (scrollToBottom) {
      this._logTable.scrollTo({ top: this._logTable.scrollTopMax });
    }
  },
};

window.addEventListener(
  "DOMContentLoaded",
  () => {
    gTorLogDialog.init();
  },
  { once: true }
);
+28 −5
Original line number Diff line number Diff line
@@ -23,10 +23,33 @@

    <script src="chrome://browser/content/torpreferences/torLogDialog.js" />

    <html:textarea
      id="torPreferences-torDialog-textarea"
      multiline="true"
      readonly="true"
    />
    <!-- We use a <table> element rather than a <ol>. A table structure allows
       - screen reader users to navigate within one column so they can avoid the
       - readback of the timestamp on every row. See tor-browser#43328.
       - NOTE: We add the explicit role="table". Whilst this should not be
       - neccessary, nor is it recommended, some screen readers (Orca 46) do not
       - read out the default table role if the CSS `display` is not `table`.
       - NOTE: Even though this table is updated with live information, we do
       - not want to make this an aria-live area or use a "log updated"
       - notification because the log messages are potentially busy.
       - Moreover, the live updates is a convience so that the log doesn't need
       - to be manually refreshed, rather than important information.
       - NOTE: We add a tabindex=0 to make this element focusable with or
       - without the overflow. This also makes the table the the initial focus
       - of the dialog.
       - NOTE: We add lang="en" and dir="ltr" to the <tbody> since the content
       - of the log is in English. We do not add this to the <table> element
       - since its aria-label is localised and we want the scrollbar to match
       - the locale direction.
       - NOTE: We avoid any whitespace between the <table> and <tbody> to ensure
       - it does not contribute to the text content when the top of the table is
       - manually copied. -->
    <html:table
      id="tor-log-table"
      role="table"
      data-l10n-id="tor-log-dialog-table"
      tabindex="0"
      ><html:tbody id="tor-log-body" lang="en" dir="ltr"></html:tbody
    ></html:table>
  </dialog>
</window>
+32 −5
Original line number Diff line number Diff line
@@ -1058,12 +1058,39 @@ groupbox#torPreferences-bridges-group textarea {
}

/* Tor logs dialog */
textarea#torPreferences-torDialog-textarea {
#tor-log-table {
  flex: 1 0 auto;
  font-family: monospace;
  font-size: 0.8em;
  white-space: pre;
  overflow: auto;
  /* 10 lines */
  min-height: 20em;
  height: 20em;
  display: flex;
  flex-direction: column;
  padding: var(--space-small);
  margin-block-end: 4px;
  border: 1px solid var(--in-content-box-border-color);
  border-radius: var(--border-radius-small);
  font-size: var(--font-size-small);
}

#tor-log-body,
#tor-log-table tr {
  display: contents;
}

#tor-log-table td {
  flex: 0 0 auto;
  padding: 0;
}

#tor-log-table td.time {
  color: var(--text-color-deemphasized);
  margin-block-end: var(--space-xsmall);
}

#tor-log-table td.message {
  overflow-wrap: anywhere;
}

#tor-log-table tr:not(:last-of-type) td.message {
  margin-block-end: var(--space-medium);
}