fix: Allow backlinks to work with fully qualified urls and anchors (#4050)

closes #4048
This commit is contained in:
Tom Moor
2022-09-04 09:14:21 +02:00
committed by GitHub
parent e1b0e94fd5
commit e0e87ea6a2
3 changed files with 34 additions and 17 deletions

View File

@@ -3,14 +3,21 @@ import parseDocumentIds from "./parseDocumentIds";
it("should not return non links", () => {
expect(parseDocumentIds(`# Header`).length).toBe(0);
});
it("should return an array of document ids", () => {
const result = parseDocumentIds(`# Header
[internal](/doc/test-456733)
[internal](http://app.getoutline.com/doc/test-456733)
More text
[internal](/doc/test-123456#heading-anchor)
`);
expect(result.length).toBe(1);
expect(result.length).toBe(2);
expect(result[0]).toBe("test-456733");
expect(result[1]).toBe("test-123456");
});
it("should not return duplicate document ids", () => {
expect(parseDocumentIds(`# Header`).length).toBe(0);
const result = parseDocumentIds(`# Header
@@ -22,9 +29,11 @@ it("should not return duplicate document ids", () => {
expect(result.length).toBe(1);
expect(result[0]).toBe("test-456733");
});
it("should not return non document links", () => {
expect(parseDocumentIds(`[google](http://www.google.com)`).length).toBe(0);
});
it("should not return non document relative links", () => {
expect(parseDocumentIds(`[relative](/developers)`).length).toBe(0);
});

View File

@@ -1,28 +1,30 @@
import { Node } from "prosemirror-model";
import parseDocumentSlug from "@shared/utils/parseDocumentSlug";
import { parser } from "@server/editor";
/**
* Parse a list of unique document identifiers contained in links in markdown
* text.
*
* @param text The text to parse in Markdown format
* @returns An array of document identifiers
*/
export default function parseDocumentIds(text: string): string[] {
const value = parser.parse(text);
const links: string[] = [];
const identifiers: string[] = [];
function findLinks(node: Node) {
// get text nodes
if (node.type.name === "text") {
// get marks for text nodes
node.marks.forEach((mark) => {
// any of the marks links?
// any of the marks identifiers?
if (mark.type.name === "link") {
const { href } = mark.attrs;
const slug = parseDocumentSlug(mark.attrs.href);
// any of the links to other docs?
if (href.startsWith("/doc")) {
const tokens = href.replace(/\/$/, "").split("/");
const lastToken = tokens[tokens.length - 1];
// don't return the same link more than once
if (!links.includes(lastToken)) {
links.push(lastToken);
}
// don't return the same link more than once
if (slug && !identifiers.includes(slug)) {
identifiers.push(slug);
}
}
});
@@ -36,5 +38,5 @@ export default function parseDocumentIds(text: string): string[] {
}
findLinks(value);
return links;
return identifiers;
}