From 0deb5f6417928c60399989b368dc90e7725b38e2 Mon Sep 17 00:00:00 2001 From: Peixiong Gao Date: Mon, 27 Jul 2026 16:55:30 +0800 Subject: [PATCH 1/4] fix(graph): add decodeURIComponent for non-ASCII page URLs and filter tag pages when showTags is false --- src/components/scripts/graph.inline.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/components/scripts/graph.inline.ts b/src/components/scripts/graph.inline.ts index 3b2773e..b9efb3c 100644 --- a/src/components/scripts/graph.inline.ts +++ b/src/components/scripts/graph.inline.ts @@ -88,6 +88,7 @@ import { async function renderGraph(graph, fullSlug, renderGeneration) { var slug = simplifySlug(fullSlug); + try { slug = decodeURIComponent(slug); } catch {} if (slug === "") slug = "index"; var visited = getVisited(); removeAllChildren(graph); @@ -117,7 +118,9 @@ import { var dataRaw = await fetchData; data = new Map(); for (var key in dataRaw) { - data.set(simplifySlug(key), dataRaw[key]); + var cleanKey = simplifySlug(key); + try { cleanKey = decodeURIComponent(cleanKey); } catch {} + data.set(cleanKey, dataRaw[key]); } } catch (err) { console.error("[Graph] Error loading data:", err); @@ -135,6 +138,7 @@ import { var outgoing = details.links || []; for (var i = 0; i < outgoing.length; i++) { var dest = simplifySlug(outgoing[i]); + try { dest = decodeURIComponent(dest); } catch {} if (validLinks.has(dest)) { links.push({ source: source, target: dest }); } @@ -146,6 +150,7 @@ import { var tag = tags[i]; if (removeTags.indexOf(tag) === -1) { var tagSlug = simplifySlug("tags/" + tag); + try { tagSlug = decodeURIComponent(tagSlug); } catch {} if (allTags.indexOf(tagSlug) === -1) { allTags.push(tagSlug); } @@ -180,10 +185,13 @@ import { } } else { validLinks.forEach(function (id) { + if (!showTags && id.startsWith("tags/")) return; neighbourhood.add(id); }); - for (var i = 0; i < allTags.length; i++) { - neighbourhood.add(allTags[i]); + if (showTags) { + for (var i = 0; i < allTags.length; i++) { + neighbourhood.add(allTags[i]); + } } } @@ -191,7 +199,9 @@ import { var nodeMap = new Map(); neighbourhood.forEach(function (url) { var isTag = url.startsWith("tags/"); - var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || url; + var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || (function(x) { + try { return decodeURIComponent(x); } catch { return x; } + })(url); var nodeTags = isTag ? [] : data.get(url)?.tags || []; var node = { id: url, From f59175d267420a4f242b31354fda17f5b7a6e256 Mon Sep 17 00:00:00 2001 From: Peixiong Gao Date: Mon, 27 Jul 2026 16:59:24 +0800 Subject: [PATCH 2/4] refactor(graph): extract safeDecodeURIComponent helper for DRY URL decoding --- src/components/scripts/graph.inline.ts | 25 +++++++++++++------------ src/util/lang.ts | 9 +++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/components/scripts/graph.inline.ts b/src/components/scripts/graph.inline.ts index b9efb3c..ce705c0 100644 --- a/src/components/scripts/graph.inline.ts +++ b/src/components/scripts/graph.inline.ts @@ -8,6 +8,14 @@ import { } from "@quartz-community/utils"; (function () { + function safeDecode(str) { + try { + return decodeURIComponent(str); + } catch { + return str; + } + } + function getSlugFromUrl() { var slug = getFullSlugFromUrl(); var base = getBasePath(); @@ -87,8 +95,7 @@ import { } async function renderGraph(graph, fullSlug, renderGeneration) { - var slug = simplifySlug(fullSlug); - try { slug = decodeURIComponent(slug); } catch {} + var slug = safeDecode(simplifySlug(fullSlug)); if (slug === "") slug = "index"; var visited = getVisited(); removeAllChildren(graph); @@ -118,9 +125,7 @@ import { var dataRaw = await fetchData; data = new Map(); for (var key in dataRaw) { - var cleanKey = simplifySlug(key); - try { cleanKey = decodeURIComponent(cleanKey); } catch {} - data.set(cleanKey, dataRaw[key]); + data.set(safeDecode(simplifySlug(key)), dataRaw[key]); } } catch (err) { console.error("[Graph] Error loading data:", err); @@ -137,8 +142,7 @@ import { data.forEach(function (details, source) { var outgoing = details.links || []; for (var i = 0; i < outgoing.length; i++) { - var dest = simplifySlug(outgoing[i]); - try { dest = decodeURIComponent(dest); } catch {} + var dest = safeDecode(simplifySlug(outgoing[i])); if (validLinks.has(dest)) { links.push({ source: source, target: dest }); } @@ -149,8 +153,7 @@ import { for (var i = 0; i < tags.length; i++) { var tag = tags[i]; if (removeTags.indexOf(tag) === -1) { - var tagSlug = simplifySlug("tags/" + tag); - try { tagSlug = decodeURIComponent(tagSlug); } catch {} + var tagSlug = safeDecode(simplifySlug("tags/" + tag)); if (allTags.indexOf(tagSlug) === -1) { allTags.push(tagSlug); } @@ -199,9 +202,7 @@ import { var nodeMap = new Map(); neighbourhood.forEach(function (url) { var isTag = url.startsWith("tags/"); - var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || (function(x) { - try { return decodeURIComponent(x); } catch { return x; } - })(url); + var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || safeDecode(url); var nodeTags = isTag ? [] : data.get(url)?.tags || []; var node = { id: url, diff --git a/src/util/lang.ts b/src/util/lang.ts index 5e39aa2..52a8c0d 100644 --- a/src/util/lang.ts +++ b/src/util/lang.ts @@ -1 +1,10 @@ export { classNames } from "@quartz-community/utils/lang"; + +export function safeDecodeURIComponent(str: string): string { + try { + return decodeURIComponent(str); + } catch { + return str; + } +} + From c35c93141fd4d55e72161aa5055621ef83d01943 Mon Sep 17 00:00:00 2001 From: Peixiong Gao Date: Mon, 27 Jul 2026 17:01:30 +0800 Subject: [PATCH 3/4] refactor(graph): import safeDecodeURIComponent directly from util/lang --- src/components/scripts/graph.inline.ts | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/components/scripts/graph.inline.ts b/src/components/scripts/graph.inline.ts index ce705c0..c21b534 100644 --- a/src/components/scripts/graph.inline.ts +++ b/src/components/scripts/graph.inline.ts @@ -6,16 +6,9 @@ import { simplifySlug, resolveBasePath, } from "@quartz-community/utils"; +import { safeDecodeURIComponent } from "../../util/lang"; (function () { - function safeDecode(str) { - try { - return decodeURIComponent(str); - } catch { - return str; - } - } - function getSlugFromUrl() { var slug = getFullSlugFromUrl(); var base = getBasePath(); @@ -95,7 +88,7 @@ import { } async function renderGraph(graph, fullSlug, renderGeneration) { - var slug = safeDecode(simplifySlug(fullSlug)); + var slug = safeDecodeURIComponent(simplifySlug(fullSlug)); if (slug === "") slug = "index"; var visited = getVisited(); removeAllChildren(graph); @@ -125,7 +118,7 @@ import { var dataRaw = await fetchData; data = new Map(); for (var key in dataRaw) { - data.set(safeDecode(simplifySlug(key)), dataRaw[key]); + data.set(safeDecodeURIComponent(simplifySlug(key)), dataRaw[key]); } } catch (err) { console.error("[Graph] Error loading data:", err); @@ -142,7 +135,7 @@ import { data.forEach(function (details, source) { var outgoing = details.links || []; for (var i = 0; i < outgoing.length; i++) { - var dest = safeDecode(simplifySlug(outgoing[i])); + var dest = safeDecodeURIComponent(simplifySlug(outgoing[i])); if (validLinks.has(dest)) { links.push({ source: source, target: dest }); } @@ -153,7 +146,7 @@ import { for (var i = 0; i < tags.length; i++) { var tag = tags[i]; if (removeTags.indexOf(tag) === -1) { - var tagSlug = safeDecode(simplifySlug("tags/" + tag)); + var tagSlug = safeDecodeURIComponent(simplifySlug("tags/" + tag)); if (allTags.indexOf(tagSlug) === -1) { allTags.push(tagSlug); } @@ -202,7 +195,7 @@ import { var nodeMap = new Map(); neighbourhood.forEach(function (url) { var isTag = url.startsWith("tags/"); - var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || safeDecode(url); + var text = isTag ? "#" + url.substring(5) : data.get(url)?.title || safeDecodeURIComponent(url); var nodeTags = isTag ? [] : data.get(url)?.tags || []; var node = { id: url, From a54e9b15aea7597252b96836c195f771c7acb1cf Mon Sep 17 00:00:00 2001 From: Peixiong Gao Date: Mon, 27 Jul 2026 17:03:38 +0800 Subject: [PATCH 4/4] fix(graph): focus PR strictly on decodeURIComponent for non-ASCII page URLs --- src/components/scripts/graph.inline.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/scripts/graph.inline.ts b/src/components/scripts/graph.inline.ts index c21b534..96d27fa 100644 --- a/src/components/scripts/graph.inline.ts +++ b/src/components/scripts/graph.inline.ts @@ -181,13 +181,10 @@ import { safeDecodeURIComponent } from "../../util/lang"; } } else { validLinks.forEach(function (id) { - if (!showTags && id.startsWith("tags/")) return; neighbourhood.add(id); }); - if (showTags) { - for (var i = 0; i < allTags.length; i++) { - neighbourhood.add(allTags[i]); - } + for (var i = 0; i < allTags.length; i++) { + neighbourhood.add(allTags[i]); } }