Skip to content
4 changes: 2 additions & 2 deletions src/commonmark/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,9 @@ export function insertCommonmarkLinkCommand(
}

/**
* Inserts a tagLink at the cursor, optionally placing it around the currently selected text if able
* Inserts a tag_link at the cursor, optionally placing it around the currently selected text if able
* @param validate The validation method that will be used to validate the selected text
* @param isMetaTag Whether or not the inserted tagLink is for a meta tag
* @param isMetaTag Whether or not the inserted tag_link is for a meta tag
*/
export function insertTagLinkCommand(
validate: TagLinkOptions["validate"],
Expand Down
6 changes: 3 additions & 3 deletions src/rich-text/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ function getHeadingLevel(state: EditorState): number {
}

/**
* Creates a command that toggles tagLink formatting for a node
* Creates a command that toggles tag_link formatting for a node
* @param validate The function to validate the tagName with
* @param isMetaTag Whether the tag to be created is a meta tag or not
*/
Expand All @@ -294,7 +294,7 @@ export function toggleTagLinkCommand(
}

let tr = state.tr;
const nodeCheck = nodeTypeActive(state.schema.nodes.tagLink);
const nodeCheck = nodeTypeActive(state.schema.nodes.tag_link);
if (nodeCheck(state)) {
const selectedText = state.selection.content().content.firstChild
.attrs["tagName"] as string;
Expand All @@ -314,7 +314,7 @@ export function toggleTagLinkCommand(
return false;
}

const newTagNode = state.schema.nodes.tagLink.create({
const newTagNode = state.schema.nodes.tag_link.create({
tagName: selectedText.trim(),
tagType: isMetaTag ? "meta-tag" : "tag",
});
Expand Down
5 changes: 0 additions & 5 deletions src/rich-text/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { stackOverflowMarkdownSerializer } from "../shared/markdown-serializer";
import { CodeBlockView } from "./node-views/code-block";
import { HtmlBlock, HtmlBlockContainer } from "./node-views/html-block";
import { ImageView } from "./node-views/image";
import { TagLink } from "./node-views/tag-link";
import { richTextCodePasteHandler } from "../shared/prosemirror-plugins/code-paste-handler";
import { linkPasteHandler } from "./plugins/link-paste-handler";
import { linkPreviewPlugin, LinkPreviewProvider } from "./plugins/link-preview";
Expand Down Expand Up @@ -101,7 +100,6 @@ export class RichTextEditor extends BaseView {
EditorType.RichText
);

const tagLinkOptions = this.options.parserFeatures.tagLinks;
this.editorView = new EditorView(
(node: HTMLElement) => {
node.classList.add(...(this.options.classList || []));
Expand Down Expand Up @@ -162,9 +160,6 @@ export class RichTextEditor extends BaseView {
) {
return new ImageView(node, view, getPos);
},
tagLink(node: ProseMirrorNode) {
return new TagLink(node, tagLinkOptions);
},
html_block: function (node: ProseMirrorNode) {
return new HtmlBlock(node);
},
Expand Down
40 changes: 0 additions & 40 deletions src/rich-text/node-views/tag-link.ts

This file was deleted.

37 changes: 33 additions & 4 deletions src/rich-text/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,16 +425,45 @@ const nodes: {
},
},

// TODO should this be a mark instead?
tagLink: {
tag_link: {
content: "text*",
marks: "", // TODO should it accept marks?
marks: "",
atom: true, // TODO allow this to be editable
inline: true,
group: "inline",
attrs: {
tagName: { default: null },
tagType: { default: "tag" },
href: { default: null },
title: { default: null },
additionalClasses: { default: "" },
},
parseDOM: [
{
tag: "a.s-tag",
getAttrs(dom: HTMLElement) {
dom.classList.remove("s-tag");
return {
href: dom.getAttribute("href"),
title: dom.getAttribute("title"),
additionalClasses: Array.from(dom.classList).join(" "),
tagType: dom.getAttribute("tagtype"),
tagName: dom.textContent,
};
},
},
],
toDOM(node) {
return [
"a",
{
tagType: node.attrs.tagType as string,
href: node.attrs.href as string,
title: node.attrs.title as string,
class: `s-tag ${node.attrs.additionalClasses as string}`,
},
node.attrs.tagName,
];
},
},
};
Expand Down Expand Up @@ -481,7 +510,7 @@ const marks: {
},
parseDOM: [
{
tag: "a[href]",
tag: "a[href]:not(.s-tag)",
getAttrs(dom: HTMLElement) {
return {
href: dom.getAttribute("href"),
Expand Down
22 changes: 20 additions & 2 deletions src/shared/markdown-it/tag-link.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import MarkdownIt from "markdown-it/lib";
import StateInline from "markdown-it/lib/rules_inline/state_inline";
import { error } from "../logger";
import type { TagLinkOptions } from "../view";

function parse_tag_link(
Expand Down Expand Up @@ -33,7 +34,7 @@ function parse_tag_link(

const totalContent = state.src.slice(state.pos, labelEnd + 1);
const isMeta = totalContent.slice(0, 10) === "[meta-tag:";
const tagName = totalContent.slice(isMeta ? 10 : 5, -1);
const tagName = totalContent.slice(isMeta ? 10 : 5, -1).trim();

if (options.validate && !options.validate(tagName, isMeta, totalContent)) {
return false;
Expand All @@ -43,7 +44,24 @@ function parse_tag_link(
let token = state.push("tag_link_open", "a", 1);
token.attrSet("tagName", tagName);
token.attrSet("tagType", isMeta ? "meta-tag" : "tag");
token.content = totalContent;

// call the renderer as if it exists
if (options.render) {
const rendered = options.render(tagName, isMeta);

if (rendered && rendered.link) {
const additionalClasses = rendered.additionalClasses || [];
token.attrSet("href", rendered.link);
token.attrSet("title", rendered.linkTitle);
token.attrSet("additionalClasses", additionalClasses.join(" "));
} else {
// We don't want to crash the parsing process here since we can still display a passable version of the tag link.
// However, we should at least log a console error.
error(
`Unable to fully render taglink for [${tagName}] due to invalid response from options.renderer.`
);
}
}

token = state.push("text", "", 0);
token.content = tagName;
Expand Down
5 changes: 4 additions & 1 deletion src/shared/markdown-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,13 @@ const customMarkdownParserTokens: MarkdownParser["tokens"] = {
},

tag_link: {
block: "tagLink",
block: "tag_link",
getAttrs: (tok: Token) => ({
tagName: tok.attrGet("tagName"),
tagType: tok.attrGet("tagType"),
href: tok.attrGet("href"),
additionalClasses: tok.attrGet("additionalClasses"),
title: tok.attrGet("title"),
}),
},

Expand Down
2 changes: 1 addition & 1 deletion src/shared/markdown-serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ const customMarkdownSerializerNodes: MarkdownSerializerNodes = {
state.closeBlock(node);
},

tagLink(state, node) {
tag_link(state, node) {
const isMeta = node.attrs.tagType === "meta-tag";
const prefix = isMeta ? "meta-tag" : "tag";
const tag = node.attrs.tagName as string;
Expand Down
4 changes: 2 additions & 2 deletions src/shared/menu/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const moreFormattingDropdown = (schema: Schema, options: CommonViewOptions) =>
options.parserFeatures?.tagLinks?.validate,
false
),
active: nodeTypeActive(schema.nodes.tagLink),
active: nodeTypeActive(schema.nodes.tag_link),
},
commonmark: insertTagLinkCommand(
options.parserFeatures?.tagLinks?.validate,
Expand All @@ -188,7 +188,7 @@ const moreFormattingDropdown = (schema: Schema, options: CommonViewOptions) =>
options.parserFeatures?.tagLinks?.validate,
true
),
active: nodeTypeActive(schema.nodes.tagLink),
active: nodeTypeActive(schema.nodes.tag_link),
},
commonmark: insertTagLinkCommand(
options.parserFeatures?.tagLinks?.validate,
Expand Down
14 changes: 7 additions & 7 deletions test/rich-text/commands/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ describe("commands", () => {
let containsTagLink = false;

newState.doc.nodesBetween(0, newState.doc.content.size, (node) => {
containsTagLink = node.type.name === "tagLink";
containsTagLink = node.type.name === "tag_link";

return !containsTagLink;
});
Expand All @@ -497,7 +497,7 @@ describe("commands", () => {
let containsTagLink = false;

newState.doc.nodesBetween(0, newState.doc.content.size, (node) => {
containsTagLink = node.type.name === "tagLink";
containsTagLink = node.type.name === "tag_link";

return !containsTagLink;
});
Expand Down Expand Up @@ -533,7 +533,7 @@ describe("commands", () => {
0,
tagLinkResult.newState.doc.content.size,
(node) => {
containsTagLink = node.type.name === "tagLink";
containsTagLink = node.type.name === "tag_link";

return !containsTagLink;
}
Expand All @@ -543,7 +543,7 @@ describe("commands", () => {
}
);

it("should replace selected text with tagLink", () => {
it("should replace selected text with tag_link", () => {
let state = createState("this is my state", []);

state = applySelection(state, 5, 7); //"is"
Expand All @@ -566,7 +566,7 @@ describe("commands", () => {
text: "this ",
},
{
"type.name": "tagLink",
"type.name": "tag_link",
},
{
isText: true,
Expand All @@ -578,7 +578,7 @@ describe("commands", () => {
});
});

it("should untoggle tagLink when selected", () => {
it("should untoggle tag_link when selected", () => {
let state = createState("someText", []);

state = applySelection(state, 0, 8); // cursor is inside the tag
Expand All @@ -597,7 +597,7 @@ describe("commands", () => {
"type.name": "paragraph",
"content": [
{
"type.name": "tagLink",
"type.name": "tag_link",
},
],
},
Expand Down
2 changes: 1 addition & 1 deletion test/shared/markdown-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ console.log("test");
"childCount": 1,
"content": [
{
"type.name": "tagLink",
"type.name": "tag_link",
"childCount": 1,
"content": [{ text: "python" }],
},
Expand Down