Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
at main 91 lines 2.7 kB view raw
1import { LENS_NAMESPACE } from "@hey/data/constants"; 2import { 3 defineBaseCommands, 4 defineBaseKeymap, 5 defineHistory, 6 defineNodeSpec, 7 union 8} from "prosekit/core"; 9import { defineBold } from "prosekit/extensions/bold"; 10import { defineDoc } from "prosekit/extensions/doc"; 11import { defineItalic } from "prosekit/extensions/italic"; 12import { defineLinkMarkRule, defineLinkSpec } from "prosekit/extensions/link"; 13import type { MentionAttrs } from "prosekit/extensions/mention"; 14import { defineMentionCommands } from "prosekit/extensions/mention"; 15import { defineModClickPrevention } from "prosekit/extensions/mod-click-prevention"; 16import { defineParagraph } from "prosekit/extensions/paragraph"; 17import { definePlaceholder } from "prosekit/extensions/placeholder"; 18import { defineText } from "prosekit/extensions/text"; 19import { defineVirtualSelection } from "prosekit/extensions/virtual-selection"; 20 21const defineAutoLink = () => { 22 return union([defineLinkSpec(), defineLinkMarkRule()]); 23}; 24 25const defineMentionSpec = () => { 26 return defineNodeSpec({ 27 atom: true, 28 attrs: { id: {}, kind: { default: "" }, value: {} }, 29 group: "inline", 30 inline: true, 31 name: "mention", 32 parseDOM: [ 33 { 34 getAttrs: (dom): MentionAttrs => { 35 const el = dom as HTMLElement; 36 const id = el.getAttribute("data-id") || ""; 37 const kind = el.getAttribute("data-mention") || ""; 38 const value = el.textContent?.replace(/^@(?:lens\/)?/g, "") || ""; 39 return { id, kind, value }; 40 }, 41 tag: "span[data-mention]" 42 } 43 ], 44 toDOM(node) { 45 const attrs = node.attrs as MentionAttrs; 46 const value = attrs.value.toString(); 47 48 const children = 49 attrs.kind === "account" 50 ? [ 51 ["span", "@"], 52 ["span", { class: "hidden" }, LENS_NAMESPACE], 53 ["span", value] 54 ] 55 : [["span", value]]; 56 57 return [ 58 "span", 59 { 60 "data-id": attrs.id.toString(), 61 "data-mention": attrs.kind.toString() 62 }, 63 ...children 64 ]; 65 } 66 }); 67}; 68 69const defineMention = () => { 70 return union([defineMentionSpec(), defineMentionCommands()]); 71}; 72 73export const defineEditorExtension = () => { 74 return union([ 75 defineDoc(), 76 defineText(), 77 defineParagraph(), 78 defineHistory(), 79 defineBaseKeymap(), 80 defineBaseCommands(), 81 defineItalic(), 82 defineBold(), 83 defineAutoLink(), 84 defineVirtualSelection(), 85 defineMention(), 86 defineModClickPrevention(), 87 definePlaceholder({ placeholder: "What's new?!", strategy: "doc" }) 88 ]); 89}; 90 91export type EditorExtension = ReturnType<typeof defineEditorExtension>;