@@ -12,6 +12,7 @@ import { BlockNoteEditor } from "../../editor/BlockNoteEditor.js";
1212import { BlockNoteExtension } from "../../editor/BlockNoteExtension.js" ;
1313import { CustomBlockNoteSchema } from "../../schema/schema.js" ;
1414import { UserStore } from "./userstore/UserStore.js" ;
15+ import { getMarkRange } from "@tiptap/core" ;
1516
1617const PLUGIN_KEY = new PluginKey ( `blocknote-comments` ) ;
1718const SET_SELECTED_THREAD_ID = "SET_SELECTED_THREAD_ID" ;
@@ -239,10 +240,39 @@ export class CommentsPlugin extends BlockNoteExtension {
239240 return ;
240241 }
241242
242- const commentMark = node . marks . find (
243- ( mark ) =>
244- mark . type . name === markType && mark . attrs . orphan !== true ,
245- ) ;
243+ const markInSchema = view . state . schema . marks [ markType ] ;
244+ const resolvedPos = view . state . doc . resolve ( pos ) ;
245+ const commentMark = node . marks
246+ . filter (
247+ ( mark ) =>
248+ mark . type . name === markType && mark . attrs . orphan !== true ,
249+ )
250+ . map ( ( mark ) => {
251+ // get the range of this mark within the document, to check how close it is to the click position
252+ const range = getMarkRange (
253+ resolvedPos ,
254+ markInSchema ,
255+ mark . attrs ,
256+ ) ! ;
257+
258+ return {
259+ mark,
260+ // calculate how far the mark is from the click position
261+ distance :
262+ ( Math . abs ( range . from - pos ) + Math . abs ( range . to - pos ) ) / 2 ,
263+ // calculate the length of text the mark spans
264+ length : range . to - range . from ,
265+ } ;
266+ } )
267+ // This allows us to not have comments which are unreachable because they are completely overlapped by other comments (issue #2073)
268+ . sort ( ( a , b ) => {
269+ // Find the mark which is closest to the click position
270+ if ( a . distance !== b . distance ) {
271+ return a . distance - b . distance ;
272+ }
273+ // Otherwise, select the mark which spans the smallest amount of text (most likely to be unreachable)
274+ return a . length - b . length ;
275+ } ) [ 0 ] ?. mark ;
246276
247277 const threadId = commentMark ?. attrs . threadId as string | undefined ;
248278 self . selectThread ( threadId , false ) ;
0 commit comments