1
0

More fixes related to #363

This commit is contained in:
Zef Hemel 2023-12-19 17:55:11 +01:00
parent a5c7405a35
commit 30436d97ea
9 changed files with 70 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import {
cleanPageRef,
federatedPathToUrl,
resolveAttachmentPath,
resolvePath,
rewritePageRefs,
} from "$sb/lib/resolve.ts";
@ -90,4 +91,22 @@ This is a [[!silverbullet.md/local link]] and [[!silverbullet.md/local link|with
rewrittenText,
`This is a [[local link]] and [[local link|with alias]].`,
);
assertEquals("test.jpg", resolveAttachmentPath("test", "test.jpg"));
assertEquals(
"folder/test.jpg",
resolveAttachmentPath("folder/test", "test.jpg"),
);
assertEquals(
"test.jpg",
resolveAttachmentPath("folder/test", "/test.jpg"),
);
assertEquals(
"https://silverbullet.md/something/test.jpg",
resolveAttachmentPath("!silverbullet.md/something/bla", "test.jpg"),
);
assertEquals(
"https://silverbullet.md/test.jpg",
resolveAttachmentPath("!silverbullet.md/something/bla", "/test.jpg"),
);
});

View File

@ -16,7 +16,24 @@ export function resolvePath(
}
}
export function resolveAttachmentPath(
currentPage: string,
pathToResolve: string,
): string {
const folder = folderName(currentPage);
if (folder && !pathToResolve.startsWith("/")) {
pathToResolve = folder + "/" + pathToResolve;
}
if (pathToResolve.startsWith("/")) {
pathToResolve = pathToResolve.slice(1);
}
return federatedPathToUrl(resolvePath(currentPage, pathToResolve));
}
export function federatedPathToUrl(path: string): string {
if (!path.startsWith("!")) {
return path;
}
path = path.substring(1);
if (path.startsWith("localhost")) {
path = "http://" + path;
@ -101,3 +118,7 @@ export function cleanPageRef(pageRef: string) {
return pageRef;
}
}
export function folderName(path: string) {
return path.split("/").slice(0, -1).join("/");
}

View File

@ -7,7 +7,7 @@ import {
nodeAtPos,
ParseTree,
} from "$sb/lib/tree.ts";
import { resolvePath } from "$sb/lib/resolve.ts";
import { resolveAttachmentPath, resolvePath } from "$sb/lib/resolve.ts";
async function actionClickOrActionEnter(
mdTree: ParseTree | null,
@ -79,7 +79,9 @@ async function actionClickOrActionEnter(
return editor.flashNotification("Empty link, ignoring", "error");
}
if (url.indexOf("://") === -1 && !url.startsWith("mailto:")) {
return editor.openUrl(resolvePath(currentPage, decodeURI(url)));
return editor.openUrl(
resolveAttachmentPath(currentPage, decodeURI(url)),
);
} else {
await editor.openUrl(url);
}
@ -94,7 +96,10 @@ async function actionClickOrActionEnter(
const args = argsText ? JSON.parse(`[${argsText}]`) : [];
await system.invokeCommand(commandName, args);
} catch (e: any) {
await editor.flashNotification(`Error parsing command link arguments: ${e.message}`, "error");
await editor.flashNotification(
`Error parsing command link arguments: ${e.message}`,
"error",
);
}
break;
}

View File

@ -1,8 +1,7 @@
import { asset, clientStore, editor, markdown, system } from "$sb/syscalls.ts";
import { renderMarkdownToHtml } from "./markdown_render.ts";
import { resolvePath } from "$sb/lib/resolve.ts";
import { resolveAttachmentPath } from "$sb/lib/resolve.ts";
import { expandCodeWidgets } from "./api.ts";
import { folderName, resolve } from "../../common/path.ts";
export async function updateMarkdownPreview() {
if (!(await clientStore.get("enableMarkdownPreview"))) {
@ -19,14 +18,9 @@ export async function updateMarkdownPreview() {
const html = renderMarkdownToHtml(mdTree, {
smartHardBreak: true,
annotationPositions: true,
translateUrls: (url, type) => {
translateUrls: (url) => {
if (!url.includes("://")) {
if (type === "image" && !url.startsWith("/")) {
// Make relative to current folder
url = resolve(folderName(currentPage), decodeURI(url));
} else if (type === "link") { // link
url = resolvePath(currentPage, decodeURI(url), true);
}
url = resolveAttachmentPath(currentPage, decodeURI(url));
}
return url;
},

View File

@ -16,7 +16,7 @@ import { fencedCodePlugin } from "./fenced_code.ts";
export function cleanModePlugins(editor: Client) {
return [
linkPlugin(),
linkPlugin(editor),
directivePlugin(),
blockquotePlugin(),
admonitionPlugin(editor),

View File

@ -8,8 +8,7 @@ import {
import { decoratorStateField } from "./util.ts";
import type { Client } from "../client.ts";
import { resolvePath } from "$sb/lib/resolve.ts";
import { folderName, resolve } from "../../common/path.ts";
import { resolveAttachmentPath, resolvePath } from "$sb/lib/resolve.ts";
class InlineImageWidget extends WidgetType {
constructor(
@ -77,11 +76,8 @@ export function inlineImagesPlugin(client: Client) {
let url = imageRexexResult.groups.url;
const title = imageRexexResult.groups.title;
const currentPage = client.currentPage!;
const currentFolder = folderName(currentPage);
if (url.indexOf("://") === -1 && !url.startsWith("/")) {
url = resolve(currentFolder, decodeURI(url));
url = resolveAttachmentPath(client.currentPage!, decodeURI(url));
}
widgets.push(
Decoration.widget({

View File

@ -1,3 +1,5 @@
import { resolveAttachmentPath } from "$sb/lib/resolve.ts";
import { Client } from "../client.ts";
import { Decoration, syntaxTree } from "../deps.ts";
import {
decoratorStateField,
@ -5,7 +7,7 @@ import {
isCursorInRange,
} from "./util.ts";
export function linkPlugin() {
export function linkPlugin(client: Client) {
return decoratorStateField((state) => {
const widgets: any[] = [];
@ -31,7 +33,14 @@ export function linkPlugin() {
return;
}
const cleanAnchor = anchorPart.substring(1); // cut off the initial [
const cleanLink = linkPart.substring(0, linkPart.length - 1); // cut off the final )
let cleanLink = linkPart.substring(0, linkPart.length - 1); // cut off the final )
if (!cleanLink.includes("://")) {
cleanLink = resolveAttachmentPath(
client.currentPage!,
decodeURI(cleanLink),
);
}
// Hide the start [
widgets.push(

View File

@ -9,8 +9,7 @@ import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
import { ParseTree } from "$sb/lib/tree.ts";
import { lezerToParseTree } from "../../common/markdown_parser/parse_tree.ts";
import type { Client } from "../client.ts";
import { resolvePath } from "$sb/lib/resolve.ts";
import { folderName, resolve } from "../../common/path.ts";
import { resolveAttachmentPath } from "$sb/lib/resolve.ts";
class TableViewWidget extends WidgetType {
constructor(
@ -39,14 +38,9 @@ class TableViewWidget extends WidgetType {
// Annotate every element with its position so we can use it to put
// the cursor there when the user clicks on the table.
annotationPositions: true,
translateUrls: (url, type) => {
translateUrls: (url) => {
if (!url.includes("://")) {
if (type === "image" && !url.startsWith("/")) {
// Make relative to current folder
url = resolve(folderName(this.editor.currentPage!), decodeURI(url));
} else if (type === "link") { // link
url = resolvePath(this.editor.currentPage!, decodeURI(url), true);
}
url = resolveAttachmentPath(this.editor.currentPage!, decodeURI(url));
}
return url;

View File

@ -11,6 +11,7 @@ release.
* A new `silverbullet sync` command to [[Sync]] spaces (early days, use with caution)
* Technical refactoring in preparation for multi-tenant deployment support (allowing you to run a single SB instance and serve multiple spaces and users at the same time)
* Lazy everything: plugs are now lazily loaded (after a first load, manifests are cached). On the server side, a whole lot of infrastructure is now only booted once the first HTTP request comes in
* Non-external URLs used in links (`[page](url)` syntax and `![alt](url)` image syntax) are now relative to the page's folder, unless their URL starts with a `/` then they're relative to the space root.
---