67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
import {
|
|
LinkNode,
|
|
type LinkAttributes,
|
|
type SerializedLinkNode,
|
|
} from "@lexical/link";
|
|
|
|
const CUSTOM_MENTION_URL_RE = /^(agent|project):\/\//;
|
|
|
|
export class MentionAwareLinkNode extends LinkNode {
|
|
static getType(): string {
|
|
return "mention-aware-link";
|
|
}
|
|
|
|
static clone(node: MentionAwareLinkNode): MentionAwareLinkNode {
|
|
return new MentionAwareLinkNode(
|
|
node.getURL(),
|
|
{
|
|
rel: node.getRel(),
|
|
target: node.getTarget(),
|
|
title: node.getTitle(),
|
|
},
|
|
node.getKey(),
|
|
);
|
|
}
|
|
|
|
static importJSON(serializedNode: SerializedLinkNode): MentionAwareLinkNode {
|
|
return new MentionAwareLinkNode(
|
|
serializedNode.url ?? "",
|
|
{
|
|
rel: serializedNode.rel ?? null,
|
|
target: serializedNode.target ?? null,
|
|
title: serializedNode.title ?? null,
|
|
},
|
|
);
|
|
}
|
|
|
|
constructor(url?: string, attributes?: LinkAttributes, key?: string) {
|
|
super(url, attributes, key);
|
|
}
|
|
|
|
sanitizeUrl(url: string): string {
|
|
if (CUSTOM_MENTION_URL_RE.test(url)) return url;
|
|
return super.sanitizeUrl(url);
|
|
}
|
|
}
|
|
|
|
type MentionAwareLinkSource = Pick<LinkNode, "getURL" | "getRel" | "getTarget" | "getTitle">;
|
|
|
|
export function getMentionAwareLinkNodeInit(node: MentionAwareLinkSource) {
|
|
return {
|
|
url: node.getURL(),
|
|
attributes: {
|
|
rel: node.getRel(),
|
|
target: node.getTarget(),
|
|
title: node.getTitle(),
|
|
},
|
|
};
|
|
}
|
|
|
|
export const mentionAwareLinkNodeReplacement = {
|
|
replace: LinkNode,
|
|
with: (node: LinkNode) => {
|
|
const { url, attributes } = getMentionAwareLinkNodeInit(node);
|
|
return new MentionAwareLinkNode(url, attributes);
|
|
},
|
|
withKlass: MentionAwareLinkNode,
|
|
} as const;
|