[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-102.6.0esr-12.5-1] fixup! Bug 16940: After update, load local change notes.
Richard Pospesel (@richard)
git at gitlab.torproject.org
Mon Jan 9 20:08:34 UTC 2023
Richard Pospesel pushed to branch tor-browser-102.6.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
9714187f by Henry Wilkes at 2023-01-09T20:07:59+00:00
fixup! Bug 16940: After update, load local change notes.
We make a number of related changed to improve the semantics and
accessibility of the about:tbupdate page:
+ We parse and show the release notes as a bullet list.
+ We use paragraphs, headings and bullet list to structure content.
+ We stop using fixed "px" font sizes and use relative sizes instead.
+ Add a lang="en-US" and dir="ltr" attribute to the english text.
- - - - -
4 changed files:
- browser/actors/AboutTBUpdateParent.jsm
- browser/base/content/abouttbupdate/aboutTBUpdate.css
- browser/base/content/abouttbupdate/aboutTBUpdate.js
- browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
Changes:
=====================================
browser/actors/AboutTBUpdateParent.jsm
=====================================
@@ -8,7 +8,6 @@
this.EXPORTED_SYMBOLS = ["AboutTBUpdateParent"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
@@ -74,41 +73,72 @@ class AboutTBUpdateParent extends JSWindowActorParent {
f.append("Docs");
f.append("ChangeLog.txt");
- let s = await IOUtils.readUTF8(f.path);
-
- // Truncate at the first empty line.
- s = s.replace(/[\r\n][\r\n][\s\S]*$/m, "");
-
- // Split into first line (version plus releaseDate) and
- // remainder (releaseNotes).
- // This first match() uses multiline mode with two capture groups:
- // first line: (.*$)
- // remaining lines: ([\s\S]+)
- // [\s\S] matches all characters including end of line. This trick
- // is needed because when using JavaScript regex in multiline mode,
- // . does not match an end of line character.
- let matchArray = s.match(/(.*$)\s*([\s\S]+)/m);
- if (matchArray && matchArray.length == 3) {
- info.releaseNotes = matchArray[2];
- let line1 = matchArray[1];
- // Extract the version and releaseDate. The first line looks like:
- // Tor Browser 8.5 -- May 1 2019
- // The regex uses two capture groups:
- // text that does not include a hyphen: (^[^-]*)
- // remaining text: (.*$)
- // In between we match optional whitespace, one or more hyphens, and
- // optional whitespace by using: \s*-+\s*
- matchArray = line1.match(/(^[^-]*)\s*-+\s*(.*$)/);
- if (matchArray && matchArray.length == 3) {
- info.version = matchArray[1];
- info.releaseDate = matchArray[2];
+ // NOTE: We load in the entire file, but only use the first few lines
+ // before the first blank line.
+ const logLines = (await IOUtils.readUTF8(f.path))
+ .replace(/\n\r?\n.*/ms, "")
+ .split(/\n\r?/);
+
+ // Read the first line to get the version and date.
+ // Assume everything after the last "-" is the date.
+ const firstLine = logLines.shift();
+ const match = firstLine?.match(/(.*)-+(.*)/);
+ if (match) {
+ info.version = match[1].trim();
+ info.releaseDate = match[2].trim();
+ } else {
+ // No date.
+ info.version = firstLine?.trim();
+ }
+
+ // We want to read the rest of the release notes as a tree. Each entry
+ // will contain the text for that line.
+ // We choose a negative index for the top node of this tree to ensure no
+ // line will appear less indented.
+ const topEntry = { indent: -1, children: undefined };
+ let prevEntry = topEntry;
+
+ for (let line of logLines) {
+ const indent = line.match(/^ */)[0];
+ line = line.trim();
+ if (line.startsWith("*")) {
+ // Treat as a bullet point.
+ let entry = {
+ text: line.replace(/^\*\s/, ""),
+ indent: indent.length,
+ };
+ let parentEntry;
+ if (entry.indent > prevEntry.indent) {
+ // A sub-list of the previous item.
+ prevEntry.children = [];
+ parentEntry = prevEntry;
+ } else {
+ // Same list or end of sub-list.
+ // Search for the first parent whose indent comes before ours.
+ parentEntry = prevEntry.parent;
+ while (entry.indent <= parentEntry.indent) {
+ parentEntry = parentEntry.parent;
+ }
+ }
+ entry.parent = parentEntry;
+ parentEntry.children.push(entry);
+ prevEntry = entry;
+ } else if (prevEntry === topEntry) {
+ // Unexpected, missing bullet point on first line.
+ // Place as its own bullet point instead, and set as prevEntry for the
+ // next loop.
+ prevEntry = { text: line, indent: indent.length, parent: topEntry };
+ topEntry.children = [prevEntry];
} else {
- info.version = line1; // Match failed: return entire line in version.
+ // Append to the previous bullet point.
+ prevEntry.text += ` ${line}`;
}
- } else {
- info.releaseNotes = s; // Only one line: use as releaseNotes.
}
- } catch (e) {}
+
+ info.releaseNotes = topEntry.children;
+ } catch (e) {
+ Cu.reportError(e);
+ }
return info;
}
=====================================
browser/base/content/abouttbupdate/aboutTBUpdate.css
=====================================
@@ -14,61 +14,54 @@ body {
font-family: Helvetica, Arial, sans-serif;
color: var(--abouttor-text-color);
background-color: var(--abouttor-bg-toron-color);
- background-attachment: fixed;
- background-size: 100% 100%;
-}
-
-a {
- color: var(--abouttor-text-color);
-}
-
-.two-column-grid {
- display: inline-grid;
+ margin-block: 40px;
+ margin-inline: 50px;
+ display: grid;
grid-template-columns: auto auto;
- grid-column-gap: 50px;
- margin: 10px 0px 0px 50px;
+ align-items: baseline;
+ gap: 40px 50px;
}
-.two-column-grid div {
- margin-top: 40px;
- align-self: baseline; /* Align baseline of text across the row. */
+body > *:not([hidden]) {
+ display: contents;
}
.label-column {
- font-size: 14px;
- font-weight: 400;
+ grid-column: 1;
}
-/*
- * Use a reduced top margin to bring the row that contains the
- * "visit our website" link closer to the row that precedes it. This
- * looks better because the "visit our website" row does not have a
- * label in the left column.
- */
-div.more-info-row {
- margin-top: 5px;
- font-size: 14px;
+.content {
+ grid-column: 2;
+ font-family: monospace;
+ line-height: 1.4;
+}
+
+.label-column, .content {
+ margin: 0;
+ padding: 0;
+ font-size: 1rem;
+ font-weight: normal;
}
-#version-content {
- font-size: 50px;
- font-weight: 300;
+a {
+ color: inherit;
}
-body:not([havereleasedate]) .release-date-cell {
- display: none;
+.no-line-break {
+ white-space: nowrap;
}
-#releasedate-content {
- font-size: 17px;
+ul {
+ padding-inline: 1em 0;
}
-#releasenotes-label {
- align-self: start; /* Anchor "Release Notes" label at the top. */
+h3, h4 {
+ font-size: 1.1rem;
+ font-weight: bold;
}
-#releasenotes-content {
- font-family: monospace;
- font-size: 15px;
- white-space: pre;
+h3.build-system-heading {
+ font-size: 1.5rem;
+ font-weight: normal;
+ margin-block-start: 3em;
}
=====================================
browser/base/content/abouttbupdate/aboutTBUpdate.js
=====================================
@@ -5,23 +5,105 @@
/* eslint-env mozilla/frame-script */
-// aData may contain the following string properties:
-// version
-// releaseDate
-// moreInfoURL
-// releaseNotes
-function onUpdate(aData) {
- document.getElementById("version-content").textContent = aData.version;
- if (aData.releaseDate) {
- document.body.setAttribute("havereleasedate", "true");
- document.getElementById("releasedate-content").textContent =
- aData.releaseDate;
+/**
+ * An object representing a bullet point in the release notes.
+ *
+ * typedef {Object} ReleaseBullet
+ * @property {string} text - The text for this bullet point.
+ * @property {?Array<ReleaseBullet>} children - A sub-list of bullet points.
+ */
+
+/**
+ * Fill an element with the given list of release bullet points.
+ *
+ * @param {Element} container - The element to fill with bullet points.
+ * @param {Array<ReleaseBullet>} bulletPoints - The list of bullet points.
+ * @param {string} [childTag="h3"] - The element tag name to use for direct
+ * children. Initially, the children are h3 sub-headings.
+ */
+function fillReleaseNotes(container, bulletPoints, childTag = "h3") {
+ for (const { text, children } of bulletPoints) {
+ const childEl = document.createElement(childTag);
+ // Keep dashes like "[tor-browser]" on the same line by nowrapping the word.
+ for (const [index, part] of text.split(/(\S+-\S+)/).entries()) {
+ if (!part) {
+ continue;
+ }
+ const span = document.createElement("span");
+ span.textContent = part;
+ span.classList.toggle("no-line-break", index % 2);
+ childEl.appendChild(span);
+ }
+ container.appendChild(childEl);
+ if (children) {
+ if (childTag == "h3" && text.toLowerCase() === "build system") {
+ // Special case: treat the "Build System" heading's children as
+ // sub-headings.
+ childEl.classList.add("build-system-heading");
+ fillReleaseNotes(container, children, "h4");
+ } else {
+ const listEl = document.createElement("ul");
+ fillReleaseNotes(listEl, children, "li");
+ if (childTag == "li") {
+ // Insert within the "li" element.
+ childEl.appendChild(listEl);
+ } else {
+ container.appendChild(listEl);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Set the content for the specified container, or hide it if we have no
+ * content.
+ *
+ * @template C
+ * @param {string} containerId - The id for the container.
+ * @param {?C} content - The content for this container, or a falsey value if
+ * the container has no content.
+ * @param {function(contentEl: Elemenet, content: C)} [fillContent] - A function
+ * to fill the ".content" contentEl with the given 'content'. If unspecified,
+ * the 'content' will become the contentEl's textContent.
+ */
+function setContent(containerId, content, fillContent) {
+ const container = document.getElementById(containerId);
+ if (!content) {
+ container.hidden = true;
+ return;
}
+ const contentEl = container.querySelector(".content");
+ // Release notes are only in English.
+ contentEl.setAttribute("lang", "en-US");
+ contentEl.setAttribute("dir", "ltr");
+ if (fillContent) {
+ fillContent(contentEl, content);
+ } else {
+ contentEl.textContent = content;
+ }
+}
+
+/**
+ * Callback when we receive the update details.
+ *
+ * @param {Object} aData - The update details.
+ * @param {?string} aData.version - The update version.
+ * @param {?string} aData.releaseDate - The release date.
+ * @param {?string} aData.moreInfoURL - A URL for more info.
+ * @param {?Array<ReleaseBullet>} aData.releaseNotes - Release notes as bullet
+ * points.
+ */
+function onUpdate(aData) {
+ setContent("version-row", aData.version);
+ setContent("releasedate-row", aData.releaseDate);
+ setContent("releasenotes", aData.releaseNotes, fillReleaseNotes);
+
if (aData.moreInfoURL) {
document.getElementById("infolink").setAttribute("href", aData.moreInfoURL);
+ } else {
+ document.getElementById("fullinfo").hidden = true;
}
- document.getElementById("releasenotes-content").textContent =
- aData.releaseNotes;
}
RPMSendQuery("FetchUpdateData").then(onUpdate);
=====================================
browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
=====================================
@@ -21,19 +21,26 @@
type="text/javascript"/>
</head>
<body dir="&locale.dir;">
-<div class="two-column-grid">
- <div class="label-column">&aboutTBUpdate.version;</div>
- <div id="version-content"/>
-
- <div class="label-column release-date-cell">&aboutTBUpdate.releaseDate;</div>
- <div id="releasedate-content" class="release-date-cell"/>
-
- <div class="more-info-row"/>
- <div class="more-info-row">&aboutTBUpdate.linkPrefix;<a id="infolink">&aboutTBUpdate.linkLabel;</a>&aboutTBUpdate.linkSuffix;</div>
-
- <div id="releasenotes-label"
- class="label-column">&aboutTBUpdate.releaseNotes;</div>
- <div id="releasenotes-content"></div>
-</div>
+ <!-- NOTE: We don't use the <dl>, <dt> and <dd> elements to form name-value
+ - pairs because this semantics is relatively new, whilst firefox
+ - currently still maps these to the more limited "definitionlist", "term"
+ - and "definition" roles. -->
+ <div id="version-row">
+ <span class="label-column">&aboutTBUpdate.version;</span>
+ <span class="content"></span>
+ </div>
+ <div id="releasedate-row">
+ <span class="label-column">&aboutTBUpdate.releaseDate;</span>
+ <span class="content"></span>
+ </div>
+ <div id="fullinfo">
+ <p class="content">
+ &aboutTBUpdate.linkPrefix;<a id="infolink">&aboutTBUpdate.linkLabel;</a>&aboutTBUpdate.linkSuffix;
+ </p>
+ </div>
+ <section id="releasenotes">
+ <h2 class="label-column">&aboutTBUpdate.releaseNotes;</h2>
+ <div class="content"></div>
+ </section>
</body>
</html>
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/9714187f4d1d60c5d41716b1ec0d6e393ba4bcd3
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/9714187f4d1d60c5d41716b1ec0d6e393ba4bcd3
You're receiving this email because of your account on gitlab.torproject.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230109/853be707/attachment-0001.htm>
More information about the tbb-commits
mailing list