update share path to .../parent/noteid

This commit is contained in:
x1arch 2025-11-21 16:51:25 +00:00
parent 5d5fd2079a
commit 1f21c65a99
4 changed files with 42 additions and 25 deletions

View File

@ -47,15 +47,14 @@ function addContentAccessQuery(note: SNote | BNote, secondEl?:boolean) {
return "" return ""
} }
function getSharedSubTreeRoot(note: SNote | BNote | undefined): Subroot { export function getSharedSubTreeRoot(note: SNote | BNote | undefined, parentId: string | undefined = undefined): Subroot {
if (!note || note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) { if (!note || note.noteId === shareRoot.SHARE_ROOT_NOTE_ID) {
// share root itself is not shared // share root itself is not shared
return {}; return {};
} }
// every path leads to share root, but which one to choose? const parentBranches = note.getParentBranches()
// for the sake of simplicity, URLs are not note paths const parentBranch = (parentId ? parentBranches.find((pb: SBranch | BBranch) => pb.parentNoteId === parentId) : undefined) || parentBranches[0];
const parentBranch = note.getParentBranches()[0];
if (note instanceof BNote) { if (note instanceof BNote) {
return { return {
@ -71,7 +70,7 @@ function getSharedSubTreeRoot(note: SNote | BNote | undefined): Subroot {
}; };
} }
return getSharedSubTreeRoot(parentBranch.getParentNote()); return getSharedSubTreeRoot(parentBranch.getParentNote(), parentId);
} }
export function renderNoteForExport(note: BNote, parentBranch: BBranch, basePath: string, ancestors: string[]) { export function renderNoteForExport(note: BNote, parentBranch: BBranch, basePath: string, ancestors: string[]) {
@ -98,7 +97,7 @@ export function renderNoteForExport(note: BNote, parentBranch: BBranch, basePath
} }
export function renderNoteContent(note: SNote) { export function renderNoteContent(note: SNote) {
const subRoot = getSharedSubTreeRoot(note); const subRoot = getSharedSubTreeRoot(note, note.parentId);
const ancestors: string[] = []; const ancestors: string[] = [];
let notePointer = note; let notePointer = note;
@ -114,23 +113,23 @@ export function renderNoteContent(note: SNote) {
// Determine CSS to load. // Determine CSS to load.
const cssToLoad: string[] = []; const cssToLoad: string[] = [];
if (!note.isLabelTruthy("shareOmitDefaultCss")) { if (!note.isLabelTruthy("shareOmitDefaultCss")) {
cssToLoad.push(`assets/styles.css`); cssToLoad.push(`../assets/styles.css`);
cssToLoad.push(`assets/scripts.css`); cssToLoad.push(`../assets/scripts.css`);
} }
for (const cssRelation of note.getRelations("shareCss")) { for (const cssRelation of note.getRelations("shareCss")) {
cssToLoad.push(`api/notes/${cssRelation.value}/download${addContentAccessQuery(note)}`); cssToLoad.push(`../api/notes/${cssRelation.value}/download${addContentAccessQuery(note)}`);
} }
// Determine JS to load. // Determine JS to load.
const jsToLoad: string[] = [ const jsToLoad: string[] = [
"assets/scripts.js" "../assets/scripts.js"
]; ];
for (const jsRelation of note.getRelations("shareJs")) { for (const jsRelation of note.getRelations("shareJs")) {
jsToLoad.push(`api/notes/${jsRelation.value}/download${addContentAccessQuery(note)}`); jsToLoad.push(`../api/notes/${jsRelation.value}/download${addContentAccessQuery(note)}`);
} }
const customLogoId = note.getRelation("shareLogo")?.value; const customLogoId = note.getRelation("shareLogo")?.value;
const logoUrl = customLogoId ? `api/images/${customLogoId}/image.png${addContentAccessQuery(note)}` : `../${assetUrlFragment}/images/icon-color.svg`; const logoUrl = customLogoId ? `../api/images/${customLogoId}/image.png${addContentAccessQuery(note)}` : `../../${assetUrlFragment}/images/icon-color.svg`;
return renderNoteContentInternal(note, { return renderNoteContentInternal(note, {
subRoot, subRoot,
@ -140,7 +139,7 @@ export function renderNoteContent(note: SNote) {
logoUrl, logoUrl,
ancestors, ancestors,
isStatic: false, isStatic: false,
faviconUrl: note.hasRelation("shareFavicon") ? `api/notes/${note.getRelationValue("shareFavicon")}/download${addContentAccessQuery(note)}` : `../favicon.ico` faviconUrl: note.hasRelation("shareFavicon") ? `../api/notes/${note.getRelationValue("shareFavicon")}/download${addContentAccessQuery(note)}` : `../../favicon.ico`
}); });
} }
@ -365,7 +364,7 @@ function handleAttachmentLink(linkEl: HTMLElement, href: string, getNote: GetNot
const attachment = getAttachment(attachmentId); const attachment = getAttachment(attachmentId);
if (attachment) { if (attachment) {
linkEl.setAttribute("href", `api/attachments/${attachmentId}/download${addContentAccessQuery(note)}`); linkEl.setAttribute("href", `../api/attachments/${attachmentId}/download${addContentAccessQuery(note)}`);
linkEl.classList.add(`attachment-link`); linkEl.classList.add(`attachment-link`);
linkEl.classList.add(`role-${attachment.role}`); linkEl.classList.add(`role-${attachment.role}`);
linkEl.childNodes.length = 0; linkEl.childNodes.length = 0;
@ -381,7 +380,7 @@ function handleAttachmentLink(linkEl: HTMLElement, href: string, getNote: GetNot
const linkedNote = getNote(noteId); const linkedNote = getNote(noteId);
if (linkedNote) { if (linkedNote) {
const isExternalLink = linkedNote.hasLabel("shareExternalLink"); const isExternalLink = linkedNote.hasLabel("shareExternalLink");
const href = isExternalLink ? linkedNote.getLabelValue("shareExternalLink") : `./${linkedNote.shareId}`; const href = isExternalLink ? linkedNote.getLabelValue("shareExternalLink") : `../${linkedNote.shareId}`;
if (href) { if (href) {
linkEl.setAttribute("href", href); linkEl.setAttribute("href", href);
} }
@ -438,7 +437,7 @@ function renderMermaid(result: Result, note: SNote | BNote) {
} }
result.content = ` result.content = `
<img src="api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}"> <img src="../api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}">
<hr> <hr>
<details> <details>
<summary>Chart source</summary> <summary>Chart source</summary>
@ -447,14 +446,14 @@ function renderMermaid(result: Result, note: SNote | BNote) {
} }
function renderImage(result: Result, note: SNote | BNote) { function renderImage(result: Result, note: SNote | BNote) {
result.content = `<img src="api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}">`; result.content = `<img src="../api/images/${note.noteId}/${note.encodedTitle}?${note.utcDateModified}${addContentAccessQuery(note, true)}">`;
} }
function renderFile(note: SNote | BNote, result: Result) { function renderFile(note: SNote | BNote, result: Result) {
if (note.mime === "application/pdf") { if (note.mime === "application/pdf") {
result.content = `<iframe class="pdf-view" src="api/notes/${note.noteId}/view${addContentAccessQuery(note)}"></iframe>`; result.content = `<iframe class="pdf-view" src="../api/notes/${note.noteId}/view${addContentAccessQuery(note)}"></iframe>`;
} else { } else {
result.content = `<button type="button" onclick="location.href='api/notes/${note.noteId}/download${addContentAccessQuery(note)}'">Download file</button>`; result.content = `<button type="button" onclick="location.href='../api/notes/${note.noteId}/download${addContentAccessQuery(note)}'">Download file</button>`;
} }
} }

View File

@ -8,7 +8,7 @@ import searchService from "../services/search/services/search.js";
import SearchContext from "../services/search/search_context.js"; import SearchContext from "../services/search/search_context.js";
import type SNote from "./shaca/entities/snote.js"; import type SNote from "./shaca/entities/snote.js";
import type SAttachment from "./shaca/entities/sattachment.js"; import type SAttachment from "./shaca/entities/sattachment.js";
import { getDefaultTemplatePath, renderNoteContent } from "./content_renderer.js"; import { getDefaultTemplatePath, getSharedSubTreeRoot, renderNoteContent } from "./content_renderer.js";
import utils from "../services/utils.js"; import utils from "../services/utils.js";
function addNoIndexHeader(note: SNote, res: Response) { function addNoIndexHeader(note: SNote, res: Response) {
@ -180,17 +180,29 @@ function register(router: Router) {
renderNote(shaca.shareRootNote, req, res); renderNote(shaca.shareRootNote, req, res);
}); });
router.get("/share/:parentShareId/:shareId", (req, res) => {
shacaLoader.ensureLoad();
const { parentShareId, shareId } = req.params;
const note = shaca.aliasToNote[shareId] || shaca.notes[shareId];
if (note){
note.parentId = parentShareId
note.initContentAccessor()
}
renderNote(note, req, res);
});
router.get("/share/:shareId", (req, res) => { router.get("/share/:shareId", (req, res) => {
shacaLoader.ensureLoad(); shacaLoader.ensureLoad();
const { shareId } = req.params; const { shareId } = req.params;
const note = shaca.aliasToNote[shareId] || shaca.notes[shareId]; const note = shaca.aliasToNote[shareId] || shaca.notes[shareId];
if (note){ const parent = getSharedSubTreeRoot(note)
note.initContentAccessor()
}
renderNote(note, req, res); res.redirect(`${parent?.note?.noteId}/${shareId}`)
}); });
router.get("/share/api/notes/:noteId", (req, res) => { router.get("/share/api/notes/:noteId", (req, res) => {

View File

@ -20,6 +20,7 @@ const isCredentials = (attr: SAttribute) => attr.type === "label" && attr.name =
class SNote extends AbstractShacaEntity { class SNote extends AbstractShacaEntity {
noteId: string; noteId: string;
parentId?: string | undefined;
title: string; title: string;
type: string; type: string;
mime: string; mime: string;
@ -40,6 +41,7 @@ class SNote extends AbstractShacaEntity {
super(); super();
this.noteId = noteId; this.noteId = noteId;
this.parentId = undefined;
this.title = isProtected ? "[protected]" : title; this.title = isProtected ? "[protected]" : title;
this.type = type; this.type = type;
this.mime = mime; this.mime = mime;
@ -70,6 +72,10 @@ class SNote extends AbstractShacaEntity {
} }
} }
getParentId() {
return this.parentId;
}
getParentBranches() { getParentBranches() {
return this.parentBranches; return this.parentBranches;
} }

View File

@ -157,7 +157,7 @@ content = content.replaceAll(headingRe, (...match) => {
<% <%
content = content content = content
.replace(/<img /g, `<img alt="${t("share_theme.image_alt")}" loading="lazy" `) .replace(/<img /g, `<img alt="${t("share_theme.image_alt")}" loading="lazy" `)
.replace(/src="(api\/[^"]+)"/g, (m, url) => `src="${url}${addContentAccessQuery(url.includes('?'))}"`); .replace(/src="(api\/[^"]+)"/g, (m, url) => `src="../${url}${addContentAccessQuery(url.includes('?'))}"`);
%> %>
<%- content %> <%- content %>
<% } %> <% } %>