@blocknote/core
Version:
A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.
2 lines • 7.64 kB
JavaScript
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./BlockNoteExtension-BJCLnwrE.cjs"),t=require("./UserStore-mj3fXW4D.cjs"),n=require("./ThreadStore-Bx-gSEh1.cjs");let r=require("@tiptap/core"),i=require("prosemirror-state"),a=require("prosemirror-view");var o=r.Mark.create({name:`comment`,excludes:``,inclusive:!1,keepOnSplit:!0,group:e.a,addAttributes(){return{orphan:{parseHTML:e=>!!e.getAttribute(`data-orphan`),renderHTML:e=>e.orphan?{"data-orphan":`true`}:{},default:!1},threadId:{parseHTML:e=>e.getAttribute(`data-bn-thread-id`),renderHTML:e=>({"data-bn-thread-id":e.threadId}),default:``}}},renderHTML({HTMLAttributes:e}){return[`span`,(0,r.mergeAttributes)(e,{class:`bn-thread-mark`})]},parseHTML(){return[{tag:`span.bn-thread-mark`}]},extendMarkSchema(e){return e.name===`comment`?{blocknoteIgnore:!0}:{}}}),s=new i.PluginKey(`blocknote-comments`);function c(e,t){let n=new Map;return e.descendants((e,r)=>{e.marks.forEach(i=>{if(i.type.name===t){let t=i.attrs.threadId;if(!t)return;let a=r,o=a+e.nodeSize,s=n.get(t)??{from:1/0,to:0};n.set(t,{from:Math.min(a,s.from),to:Math.max(o,s.to)})}})}),n}var l=e.t(({editor:n,options:{schema:r,threadStore:l,resolveUsers:u,confirmBeforeDiscard:d=!0}})=>{if(!u)throw Error(`resolveUsers is required to be defined when using comments`);if(!l)throw Error(`threadStore is required to be defined when using comments`);let f=t.n(u),p=o.name,m=e.n({pendingComment:!1,selectedThreadId:void 0,threadPositions:new Map},{onUpdate(e,t){e.selectedThreadId!==t.selectedThreadId&&n.transact(e=>e.setMeta(s,!0))}}),h=e=>{n.transact(t=>{t.doc.descendants((n,r)=>{n.marks.forEach(i=>{if(i.type.name===p){let a=i.type,o=i.attrs.threadId,s=e.get(o),c=!!(!s||s.resolved||s.deletedAt);if(c!==i.attrs.orphan){let e=Math.max(r,0),s=Math.min(r+n.nodeSize,t.doc.content.size-1,t.doc.content.size-1);t.removeMark(e,s,i),t.addMark(e,s,a.create({...i.attrs,orphan:c})),c&&m.state.selectedThreadId===o&&m.setState(e=>({...e,selectedThreadId:void 0}))}}})})})};return{key:`comments`,store:m,userStore:f,runsBefore:[`link`],tiptapExtensions:[o],prosemirrorPlugins:[new i.Plugin({key:s,state:{init(){return{decorations:a.DecorationSet.empty}},apply(e,t){let n=e.getMeta(s);if(!e.docChanged&&!n)return t;let r=e.docChanged?c(e.doc,p):m.state.threadPositions;(r.size>0||m.state.threadPositions.size>0)&&m.setState(e=>({...e,threadPositions:r}));let i=[];if(m.state.selectedThreadId){let e=r.get(m.state.selectedThreadId);e&&i.push(a.Decoration.inline(e.from,e.to,{class:`bn-thread-mark-selected`}))}return{decorations:a.DecorationSet.create(e.doc,i)}}},props:{decorations(e){return s.getState(e)?.decorations??a.DecorationSet.empty},handleClick:(e,t,n)=>{if(n.button!==0)return!1;let r=e.state.doc.nodeAt(t);if(!r)return m.setState(e=>({...e,selectedThreadId:void 0})),!1;let i=r.marks.find(e=>e.type.name===p&&e.attrs.orphan!==!0);if(!i)return m.state.selectedThreadId!==void 0&&m.setState(e=>({...e,selectedThreadId:void 0})),!1;let a=i.attrs.threadId;return a!==m.state.selectedThreadId&&(m.setState(e=>({...e,selectedThreadId:a})),!0)}}})],threadStore:l,mount(){let e=l.subscribe(h);h(l.getThreads());let t=n.onSelectionChange(()=>{m.state.pendingComment&&m.setState(e=>({...e,pendingComment:!1}))});return()=>{e(),t()}},selectThread(e,t=!0){if(m.state.selectedThreadId!==e&&(m.setState(t=>({...t,pendingComment:!1,selectedThreadId:e})),e&&t)){let t=m.state.threadPositions.get(e);if(!t)return;(n.prosemirrorView?.domAtPos(t.from).node)?.scrollIntoView({behavior:`smooth`,block:`center`})}},startPendingComment(){m.setState(e=>({...e,selectedThreadId:void 0,pendingComment:!0})),n.domElement?.focus(),n.getExtension(t.r)?.showSelection(!0,`comments`)},stopPendingComment(){m.setState(e=>({...e,selectedThreadId:void 0,pendingComment:!1})),n.getExtension(t.r)?.showSelection(!1,`comments`)},async createThread(e){let t=await l.createThread(e);l.addThreadToDocument?await l.addThreadToDocument({threadId:t.id,selection:n.transact(e=>e.selection),editor:n}):n._tiptapEditor.commands.setMark(p,{orphan:!1,threadId:t.id})},commentEditorSchema:r,confirmBeforeDiscard:d}}),u=class{},d=class extends u{userId;role;constructor(e,t){super(),this.userId=e,this.role=t}canCreateThread(){return!0}canAddComment(e){return!0}canUpdateComment(e){return e.userId===this.userId}canDeleteComment(e){return e.userId===this.userId||this.role===`editor`}canDeleteThread(e){return this.role===`editor`}canResolveThread(e){return!0}canUnresolveThread(e){return!0}canAddReaction(e,t){return!t||!e.reactions.some(e=>e.emoji===t&&e.userIds.includes(this.userId))}canDeleteReaction(e,t){return!t||e.reactions.some(e=>e.emoji===t&&e.userIds.includes(this.userId))}},f=class extends n.t{userId;provider;constructor(e,t,n){super(n),this.userId=e,this.provider=t}async createThread(e){let t=this.provider.createThread({data:e.metadata});return t=this.provider.addComment(t.id,{content:e.initialComment.body,data:{metadata:e.initialComment.metadata,userId:this.userId}}),this.tiptapThreadToThreadData(t)}addThreadToDocument=void 0;async addComment(e){let t=this.provider.addComment(e.threadId,{content:e.comment.body,data:{metadata:e.comment.metadata,userId:this.userId}});return this.tiptapCommentToCommentData(t.comments[t.comments.length-1])}async updateComment(e){let t=this.provider.getThreadComment(e.threadId,e.commentId,!0);if(!t)throw Error(`Comment not found`);this.provider.updateComment(e.threadId,e.commentId,{content:e.comment.body,data:{...t.data,metadata:e.comment.metadata}})}tiptapCommentToCommentData(e){let t=[];for(let n of e.data?.reactions||[]){let e=t.find(e=>e.emoji===n.emoji);e?(e.userIds.push(n.userId),e.createdAt=new Date(Math.min(e.createdAt.getTime(),n.createdAt))):t.push({emoji:n.emoji,createdAt:new Date(n.createdAt),userIds:[n.userId]})}return{type:`comment`,id:e.id,body:e.content,metadata:e.data?.metadata,userId:e.data?.userId,createdAt:new Date(e.createdAt),updatedAt:new Date(e.updatedAt),reactions:t}}tiptapThreadToThreadData(e){return{type:`thread`,id:e.id,comments:e.comments.map(e=>this.tiptapCommentToCommentData(e)),resolved:!!e.resolvedAt,metadata:e.data?.metadata,createdAt:new Date(e.createdAt),updatedAt:new Date(e.updatedAt)}}async deleteComment(e){this.provider.deleteComment(e.threadId,e.commentId)}async deleteThread(e){this.provider.deleteThread(e.threadId)}async resolveThread(e){this.provider.updateThread(e.threadId,{resolvedAt:new Date().toISOString()})}async unresolveThread(e){this.provider.updateThread(e.threadId,{resolvedAt:null})}async addReaction(e){let t=this.provider.getThreadComment(e.threadId,e.commentId,!0);if(!t)throw Error(`Comment not found`);this.provider.updateComment(e.threadId,e.commentId,{data:{...t.data,reactions:[...t.data?.reactions||[],{emoji:e.emoji,createdAt:Date.now(),userId:this.userId}]}})}async deleteReaction(e){let t=this.provider.getThreadComment(e.threadId,e.commentId,!0);if(!t)throw Error(`Comment not found`);this.provider.updateComment(e.threadId,e.commentId,{data:{...t.data,reactions:(t.data?.reactions||[]).filter(t=>t.emoji!==e.emoji&&t.userId!==this.userId)}})}getThread(e){let t=this.provider.getThread(e);if(!t)throw Error(`Thread not found`);return this.tiptapThreadToThreadData(t)}getThreads(){return new Map(this.provider.getThreads().map(e=>[e.id,this.tiptapThreadToThreadData(e)]))}subscribe(e){let t=()=>{e(this.getThreads())};return this.provider.watchThreads(t),()=>{this.provider.unwatchThreads(t)}}};exports.CommentMark=o,exports.CommentsExtension=l,exports.DefaultThreadStoreAuth=d,exports.ThreadStore=n.t,exports.ThreadStoreAuth=u,exports.TiptapThreadStore=f;
//# sourceMappingURL=comments.cjs.map