1
+ import type { DeltaStatic } from 'quill' ;
1
2
import type { ReactQuillProps } from 'react-quill' ;
2
3
3
4
import dynamic from 'next/dynamic' ;
@@ -9,6 +10,7 @@ import { editorClassnames as cn } from '~/components/Editor/editorClassnames';
9
10
import EditorSkeleton from '~/components/Editor/EditorSkeleton' ;
10
11
import { articleCss } from '~/services/article' ;
11
12
import { fontCss , palettes } from '~/styles/utils' ;
13
+ import { regex } from '~/utils' ;
12
14
13
15
const ReactQuill = dynamic ( import ( 'react-quill' ) , {
14
16
ssr : false ,
@@ -32,6 +34,31 @@ const Editor = (props: EditorProps) => {
32
34
) ;
33
35
} ;
34
36
37
+ // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#node.text_node
38
+ const TEXT_NODE = 3 ;
39
+
40
+ // https://github.com/quilljs/quill/issues/109#issuecomment-278181150
41
+ const convertUrlTextToLink = ( node : Text , delta : DeltaStatic ) => {
42
+ if ( typeof node . data !== 'string' ) return ;
43
+ const matches = node . data . match ( regex . looseUrl ) ;
44
+
45
+ if ( matches && matches . length > 0 ) {
46
+ const ops = [ ] ;
47
+ let str = node . data ;
48
+ matches . forEach ( ( match ) => {
49
+ const split = str . split ( match ) ;
50
+ const beforeLink = split . shift ( ) ;
51
+ ops . push ( { insert : beforeLink } ) ;
52
+ ops . push ( { insert : match , attributes : { link : match } } ) ;
53
+ str = split . join ( match ) ;
54
+ } ) ;
55
+ ops . push ( { insert : str } ) ;
56
+ delta . ops = ops ;
57
+ }
58
+
59
+ return delta ;
60
+ } ;
61
+
35
62
const modules = {
36
63
toolbar : {
37
64
container : [
@@ -43,6 +70,9 @@ const modules = {
43
70
[ 'clean' ] ,
44
71
] ,
45
72
} ,
73
+ clipboard : {
74
+ matchers : [ [ TEXT_NODE , convertUrlTextToLink ] ] ,
75
+ } ,
46
76
} ;
47
77
48
78
const formats = [
0 commit comments