From a167b0f5294b2c4231e4bfb4e07d362f03f17608 Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Fri, 28 Aug 2026 13:18:41 +0200 Subject: [PATCH 1/2] fix(section anchors): leave the page counter out of the copied link Clicking the "#" handle next to a view display copied the address bar as it stood, and Wicket keeps a counter for the page instance it is serving at the front of the query string, as a parameter with no value: https://nanodash.knowledgepixels.com/space?0&id=https://w3id.org/spaces/... That counter belongs to one visit and means nothing to whoever the link is sent to, so the copied link now leaves it out and reads: https://nanodash.knowledgepixels.com/space?id=https://w3id.org/spaces/...#messages Any other valueless number in the query string goes the same way, since nanodash's own parameters all have names. Where the counter was the only thing in the query string the "?" goes with it, and an address that never had one is copied unchanged. The link the handle itself navigates to is untouched: it is the bare "#section" and never carried the counter. Closes #650 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NSAawRfUm4Au1UkejyNKY1 --- .../knowledgepixels/nanodash/script/nanodash.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js b/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js index f872715b..6faabd1e 100644 --- a/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js +++ b/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js @@ -71,6 +71,21 @@ function renderFriendlyDates(root) { }); } +/* The address of the page as it is worth sending to somebody else. Wicket keeps a + counter for the page instance it is serving and puts it at the front of the query + string as a parameter with no value: ".../space?3&id=...". It belongs to one visit + and means nothing to whoever the link is sent to, so it is left out. Any other + valueless number goes the same way; nanodash's own parameters all have names. */ +function shareableUrl() { + var url = window.location.href.split("#")[0]; + var queryStart = url.indexOf("?"); + if (queryStart === -1) return url; + var params = url.slice(queryStart + 1).split("&").filter(function (param) { + return !/^[0-9]+$/.test(param); + }); + return url.slice(0, queryStart) + (params.length ? "?" + params.join("&") : ""); +} + /* Section anchors — every view display of a page carries a fragment identifier (server-side, see ViewAnchors): on its wrapping .listview element where ViewList renders it, and on the panel itself (.view-section) on the pages that build their @@ -98,7 +113,7 @@ function addSectionAnchors(root) { // The href already moves the browser to the section; additionally put the full // link on the clipboard, which is what one actually wants it for. if (!navigator.clipboard) return; - var url = window.location.href.split("#")[0] + "#" + section.id; + var url = shareableUrl() + "#" + section.id; navigator.clipboard.writeText(url).then(function () { showToast("Link to section copied to clipboard!"); }, function () { /* clipboard denied: the plain link still works */ }); From 9d8870055bb70563b8d68b6ce6d8ed31651bb02e Mon Sep 17 00:00:00 2001 From: Ashley Caselli Date: Mon, 31 Aug 2026 09:10:39 +0200 Subject: [PATCH 2/2] fix(section anchors): leave the session id out of the copied link too When the visitor has cookies disabled, Wicket rewrites URLs with the session id in the path: https://nanodash.knowledgepixels.com/space;jsessionid=79B384...?0&id=... Copying that as-is hands whoever the link is sent to a live session, which is worse than the page counter the previous commit dropped. The copied link now leaves it out as well: https://nanodash.knowledgepixels.com/space?id=...#messages The strip is scoped to the path, so a query value that happens to contain ";jsessionid=" -- an "id=" pointing at some other URL, say -- is left alone. It is case-insensitive and applies to every path segment, not just the last. Closes #650 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014dByNErNfuj4au4r5vMsbf --- .../nanodash/script/nanodash.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js b/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js index 6faabd1e..f8d97c33 100644 --- a/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js +++ b/src/main/java/com/knowledgepixels/nanodash/script/nanodash.js @@ -71,19 +71,24 @@ function renderFriendlyDates(root) { }); } -/* The address of the page as it is worth sending to somebody else. Wicket keeps a - counter for the page instance it is serving and puts it at the front of the query - string as a parameter with no value: ".../space?3&id=...". It belongs to one visit - and means nothing to whoever the link is sent to, so it is left out. Any other - valueless number goes the same way; nanodash's own parameters all have names. */ +/* The address of the page as it is worth sending to somebody else. Two things Wicket + puts there belong to the current visit only and are left out: + - the counter for the page instance it is serving, at the front of the query string + as a parameter with no value: ".../space?3&id=...". Any other valueless number + goes the same way; nanodash's own parameters all have names. + - the session id, which Wicket writes into the path as ";jsessionid=..." when the + visitor has cookies disabled: ".../space;jsessionid=79B384...?id=...". Sending + that on would hand the recipient a live session. */ function shareableUrl() { var url = window.location.href.split("#")[0]; var queryStart = url.indexOf("?"); - if (queryStart === -1) return url; + var path = (queryStart === -1 ? url : url.slice(0, queryStart)) + .replace(/;jsessionid=[^/]*/gi, ""); + if (queryStart === -1) return path; var params = url.slice(queryStart + 1).split("&").filter(function (param) { return !/^[0-9]+$/.test(param); }); - return url.slice(0, queryStart) + (params.length ? "?" + params.join("&") : ""); + return path + (params.length ? "?" + params.join("&") : ""); } /* Section anchors — every view display of a page carries a fragment identifier