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 ""
}
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) {
// share root itself is not shared
return {};
}
// every path leads to share root, but which one to choose?
// for the sake of simplicity, URLs are not note paths
const parentBranch = note.getParentBranches()[0];
const parentBranches = note.getParentBranches()
const parentBranch = (parentId ? parentBranches.find((pb: SBranch | BBranch) => pb.parentNoteId === parentId) : undefined) || parentBranches[0];
if (note instanceof BNote) {
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[]) {
@ -98,7 +97,7 @@ export function renderNoteForExport(note: BNote, parentBranch: BBranch, basePath
}
export function renderNoteContent(note: SNote) {
const subRoot = getSharedSubTreeRoot(note);
const subRoot = getSharedSubTreeRoot(note, note.parentId);
const ancestors: string[] = [];
let notePointer = note;
@ -114,23 +113,23 @@ export function renderNoteContent(note: SNote) {
// Determine CSS to load.
const cssToLoad: string[] = [];
if (!note.isLabelTruthy("shareOmitDefaultCss")) {
cssToLoad.push(`assets/styles.css`);
cssToLoad.push(`assets/scripts.css`);
cssToLoad.push(`../assets/styles.css`);
cssToLoad.push(`../assets/scripts.css`);
}
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.
const jsToLoad: string[] = [
"assets/scripts.js"
"../assets/scripts.js"
];
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 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, {
subRoot,
@ -140,7 +139,7 @@ export function renderNoteContent(note: SNote) {
logoUrl,
ancestors,
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);
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(`role-${attachment.role}`);
linkEl.childNodes.length = 0;
@ -381,7 +380,7 @@ function handleAttachmentLink(linkEl: HTMLElement, href: string, getNote: GetNot
const linkedNote = getNote(noteId);
if (linkedNote) {
const isExternalLink = linkedNote.hasLabel("shareExternalLink");
const href = isExternalLink ? linkedNote.getLabelValue("shareExternalLink") : `./${linkedNote.shareId}`;
const href = isExternalLink ? linkedNote.getLabelValue("shareExternalLink") : `../${linkedNote.shareId}`;
if (href) {
linkEl.setAttribute("href", href);
}
@ -438,7 +437,7 @@ function renderMermaid(result: Result, note: SNote | BNote) {
}
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>
<details>
<summary>Chart source</summary>
@ -447,14 +446,14 @@ function renderMermaid(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) {
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 {
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 type SNote from "./shaca/entities/snote.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";
function addNoIndexHeader(note: SNote, res: Response) {
@ -180,17 +180,29 @@ function register(router: Router) {
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) => {
shacaLoader.ensureLoad();
const { shareId } = req.params;
const note = shaca.aliasToNote[shareId] || shaca.notes[shareId];
if (note){
note.initContentAccessor()
}
const parent = getSharedSubTreeRoot(note)
renderNote(note, req, res);
res.redirect(`${parent?.note?.noteId}/${shareId}`)
});
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 {
noteId: string;
parentId?: string | undefined;
title: string;
type: string;
mime: string;
@ -40,6 +41,7 @@ class SNote extends AbstractShacaEntity {
super();
this.noteId = noteId;
this.parentId = undefined;
this.title = isProtected ? "[protected]" : title;
this.type = type;
this.mime = mime;
@ -70,6 +72,10 @@ class SNote extends AbstractShacaEntity {
}
}
getParentId() {
return this.parentId;
}
getParentBranches() {
return this.parentBranches;
}

View File

@ -157,7 +157,7 @@ content = content.replaceAll(headingRe, (...match) => {
<%
content = content
.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 %>
<% } %>