- TipTap 2 → 3: Extension from @tiptap/core, Placeholder from @tiptap/extensions, TaskList/TaskItem from @tiptap/extension-list, link: false in StarterKit (now bundles Link), @tiptap/core added - marked 15 → 17: heading renderer updated to tokens/parseInline API - Pinia 2 → 3, Vue Router 4 → 5 (no code changes required) - Vite 6 → 7, @vitejs/plugin-vue 5 → 6, vue-tsc 2 → 3 - TypeScript 5.6 → 5.9: fixed Uint8Array<ArrayBuffer> strictness in push.ts, removed unused bodyEl ref in NoteViewerView.vue - .npmrc: legacy-peer-deps=true for TipTap v3 peer dep resolution TipTap 3 new capabilities now available: static renderer (createStaticRenderer), MarkViews, @tiptap/extensions package. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { Extension } from "@tiptap/core";
|
|
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
|
|
|
const WIKILINK_RE = /\[\[([^\]]+)\]\]/g;
|
|
|
|
export const WikilinkDecoration = Extension.create({
|
|
name: "wikilinkDecoration",
|
|
|
|
addProseMirrorPlugins() {
|
|
return [
|
|
new Plugin({
|
|
key: new PluginKey("wikilinkDecoration"),
|
|
props: {
|
|
decorations(state) {
|
|
const decorations: Decoration[] = [];
|
|
state.doc.descendants((node, pos) => {
|
|
if (!node.isText || !node.text) return;
|
|
WIKILINK_RE.lastIndex = 0;
|
|
let match: RegExpExecArray | null;
|
|
while ((match = WIKILINK_RE.exec(node.text)) !== null) {
|
|
const from = pos + match.index;
|
|
const to = from + match[0].length;
|
|
decorations.push(
|
|
Decoration.inline(from, to, { class: "wikilink" })
|
|
);
|
|
}
|
|
});
|
|
return DecorationSet.create(state.doc, decorations);
|
|
},
|
|
},
|
|
}),
|
|
];
|
|
},
|
|
});
|