diff --git a/website/src/components/brand/CookbookRecipe.tsx b/website/src/components/brand/CookbookRecipe.tsx
index 315ac386..faaecde9 100644
--- a/website/src/components/brand/CookbookRecipe.tsx
+++ b/website/src/components/brand/CookbookRecipe.tsx
@@ -368,7 +368,7 @@ function RecipeFileView({
if (status === "error" || text === undefined) {
return (
- Couldn't load this file. View it on GitHub.
+ Couldn't load this file. View it on GitHub.
);
}
diff --git a/website/src/components/brand/DetailChassis.tsx b/website/src/components/brand/DetailChassis.tsx
index 42b71296..9040d7c8 100644
--- a/website/src/components/brand/DetailChassis.tsx
+++ b/website/src/components/brand/DetailChassis.tsx
@@ -402,11 +402,20 @@ export function buildDetailToc(markdownHtml: string): {
(match, attrs: string, inner: string) => {
const label = inner
.replace(/<[^>]+>/g, "")
- .replace(/&/g, "&")
- .replace(/</g, "<")
- .replace(/>/g, ">")
- .replace(/"/g, '"')
- .replace(/'/g, "'")
+ .replace(/<|>|"|'|&/g, (entity) => {
+ switch (entity) {
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case """:
+ return '"';
+ case "'":
+ return "'";
+ default:
+ return "&";
+ }
+ })
.trim();
if (!label) return match;
diff --git a/website/src/components/brand/SkillDetail.tsx b/website/src/components/brand/SkillDetail.tsx
index 54b8afb7..07a61e57 100644
--- a/website/src/components/brand/SkillDetail.tsx
+++ b/website/src/components/brand/SkillDetail.tsx
@@ -480,7 +480,7 @@ function FileView({
if (status === "error" || text === undefined) {
return (
- Couldn't load this file. View it on GitHub.
+ Couldn't load this file. View it on GitHub.
);
}
diff --git a/website/src/components/brand/SyntaxHighlightedCode.tsx b/website/src/components/brand/SyntaxHighlightedCode.tsx
index 78d4a8f0..bc926cbd 100644
--- a/website/src/components/brand/SyntaxHighlightedCode.tsx
+++ b/website/src/components/brand/SyntaxHighlightedCode.tsx
@@ -52,7 +52,7 @@ const rules: Record = {
{ kind: "punctuation", expression: /[{}[\],:]/y },
],
markup: [
- { kind: "comment", expression: //y },
+ { kind: "comment", expression: //y },
{ kind: "tag", expression: /<\/?[A-Za-z][\w:-]*/y },
{ kind: "attr-name", expression: /[A-Za-z_:][\w:.-]*(?=\s*=)/y },
{ kind: "string", expression: /"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/y },
diff --git a/website/src/components/brand/catalogFilters.ts b/website/src/components/brand/catalogFilters.ts
index c065c37c..f8f5dca2 100644
--- a/website/src/components/brand/catalogFilters.ts
+++ b/website/src/components/brand/catalogFilters.ts
@@ -14,7 +14,7 @@ export const updatedBuckets: { label: string; max: number }[] = [
{ label: "Older", max: Number.POSITIVE_INFINITY },
];
-/** Whole days between `lastUpdated` and now. Unparseable dates sort as oldest. */
+/** Whole days between `lastUpdated` and now. Unparsable dates sort as oldest. */
export function daysSince(lastUpdated: string | undefined): number {
if (!lastUpdated) return Number.POSITIVE_INFINITY;
const then = Date.parse(lastUpdated);
diff --git a/website/src/components/brand/pagefindSearch.ts b/website/src/components/brand/pagefindSearch.ts
index 416a1a61..99908007 100644
--- a/website/src/components/brand/pagefindSearch.ts
+++ b/website/src/components/brand/pagefindSearch.ts
@@ -15,6 +15,19 @@ type PagefindResultData = {
meta?: Record;
};
+/** Strip HTML tags, repeating until no more tags remain so a malformed or
+ * nested markup fragment (e.g. `<