Skip to content

Commit

Permalink
CRISTAL-406: Selecting an internal link still displays a full url
Browse files Browse the repository at this point in the history
- Fix a problem with external link on Nextcloud and File System backends
- Add more checks to prevent issues in case of bad syntax
  • Loading branch information
manuelleduc committed Jan 14, 2025
1 parent 9d23f92 commit be35fa6
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 16 deletions.
68 changes: 52 additions & 16 deletions core/markdown/markdown-default/src/parseInternalLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,53 @@ function parseStringForInternalLinks(
return tokens;
}

function referenceToURL(
remoteURLSerializer: RemoteURLSerializer,
modelReferenceParser: ModelReferenceParser,
reference: string,
) {
return remoteURLSerializer.serialize(modelReferenceParser.parse(reference));
}

function parseReference(
v: InternalLink,
remoteURLSerializer: RemoteURLSerializer,
modelReferenceParser: ModelReferenceParser,
) {
const { text, reference } = v;
let href: string;
try {
href =
referenceToURL(remoteURLSerializer, modelReferenceParser, reference) ??
"";
} catch {
// Prevent the parser from failing in case of bad reference (e.g., an url in an internal link).
href = reference;
}
return { text, reference, href };
}

function handleLink(
v: InternalLink,
remoteURLSerializer: RemoteURLSerializer,
modelReferenceParser: ModelReferenceParser,
state: StateCore,
) {
const { text, reference, href } = parseReference(
v,
remoteURLSerializer,
modelReferenceParser,
);

const openToken = new state.Token("link_open", "a", 1);
openToken.attrSet("href", href ?? "");
openToken.attrPush(["class", "internal-link"]);
const contentToken = new state.Token("text", "", 0);
contentToken.content = text ?? reference;
const closeToken = new state.Token("link_close", "a", -1);
return [openToken, contentToken, closeToken];
}

export function parseInternalLinks(
modelReferenceParser: ModelReferenceParser,
remoteURLSerializer: RemoteURLSerializer,
Expand All @@ -100,29 +147,18 @@ export function parseInternalLinks(
// We replace the content of the current block node only if at least a link has been found.
if (hasLink(internalTokens)) {
blockToken.content = "";
// TODO: reduce the number of statements in the following method and reactivate the disabled eslint
// rule.
// eslint-disable-next-line max-statements
blockToken.children = internalTokens.flatMap((v) => {
if (typeof v == "string") {
const token = new state.Token("text", "span", 0);
token.content = v;
return [token];
} else {
const { text, reference } = v;

const openToken = new state.Token("link_open", "a", 1);
openToken.attrSet(
"href",
remoteURLSerializer.serialize(
modelReferenceParser.parse(reference),
) ?? "",
return handleLink(
v,
remoteURLSerializer,
modelReferenceParser,
state,
);
openToken.attrPush(["class", "internal-link"]);
const contentToken = new state.Token("text", "", 0);
contentToken.content = text || reference;
const closeToken = new state.Token("link_close", "a", -1);
return [openToken, contentToken, closeToken];
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import { injectable } from "inversify";
@injectable()
export class FileSystemModelReferenceParser implements ModelReferenceParser {
parse(reference: string): EntityReference {
if (/^https?:\/\//.test(reference)) {
throw new Error(`[${reference}] is not a valid entity reference`);
}
const segments = reference.split(/(?<!\\)\//);
if (segments[segments.length - 2] == "attachments") {
return new AttachmentReference(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import { injectable } from "inversify";
@injectable()
export class NextcloudModelReferenceParser implements ModelReferenceParser {
parse(reference: string): EntityReference {
if (/^https?:\/\//.test(reference)) {
throw new Error(`[${reference}] is not a valid entity reference`);
}
let segments = reference.split("/");
if (segments[0] == "") {
segments = segments.slice(1);
Expand Down

0 comments on commit be35fa6

Please sign in to comment.