import { Mark as ProsemirrorMark } from 'prosemirror-model' ; import { Plugin , TextSelection } from 'prosemirror-state' ; import { Link as TiptapLink } from 'tiptap-extensions' ; import { EditorView } from 'prosemirror-view' ; import { getMarkRange } from 'tiptap-utils' ; import { MenuData } from 'tiptap' ; import { MenuBtnView } from '@/../types' ; import AddLinkCommandButton from '@/components/MenuCommands/Link/AddLinkCommandButton.vue' ; function getAttrs ( dom ) { return { href : dom . getAttribute ( 'href' ) , openInNewTab : dom . getAttribute ( 'target' ) === '_blank' , } ; } function toDOM ( mark ) { const { href , openInNewTab , } = mark . attrs ; const attrs = { } ; attrs . href = href ; let ref = 'nofollow' ; if ( openInNewTab ) { attrs . target = '_blank' ; ref += ' noopener noreferrer' ; } attrs . ref = ref . trim ( ) ; return [ 'a' , attrs , 0 ] ; } export default class Link extends TiptapLink implements MenuBtnView { get schema ( ) { return { attrs : { href : { default : null , } , openInNewTab : { default : true , } , } , inclusive : false , parseDOM : [ { tag : 'a[href]' , getAttrs , } , ] , toDOM , } ; } get plugins ( ) { return [ new Plugin ( { props : { handleClick ( view , pos ) { const { schema , doc , tr } = view . state ; const range = getMarkRange ( doc . resolve ( pos ) , schema . marks . link ) ; if ( ! range ) return false ; const $start = doc . resolve ( range . from ) ; const $end = doc . resolve ( range . to ) ; const transaction = tr . setSelection ( new TextSelection ( $start , $end ) ) ; view . dispatch ( transaction ) ; return true ; } , } , } ) , ] ; } menuBtnView ( editorContext ) { return { component : AddLinkCommandButton , componentProps : { editorContext , } , } ; } }