11import $ from 'jquery' ;
2+
23const { csrfToken} = window . config ;
34
45async function uploadFile ( file , uploadUrl ) {
@@ -21,72 +22,104 @@ function clipboardPastedImages(e) {
2122 if ( ! item . type || ! item . type . startsWith ( 'image/' ) ) continue ;
2223 files . push ( item . getAsFile ( ) ) ;
2324 }
24-
25- if ( files . length ) {
26- e . preventDefault ( ) ;
27- e . stopPropagation ( ) ;
28- }
2925 return files ;
3026}
3127
28+ class TextareaEditor {
29+ constructor ( editor ) {
30+ this . editor = editor ;
31+ }
3232
33- function insertAtCursor ( field , value ) {
34- if ( field . selectionStart || field . selectionStart === 0 ) {
35- const startPos = field . selectionStart ;
36- const endPos = field . selectionEnd ;
37- field . value = field . value . substring ( 0 , startPos ) + value + field . value . substring ( endPos , field . value . length ) ;
38- field . selectionStart = startPos + value . length ;
39- field . selectionEnd = startPos + value . length ;
40- } else {
41- field . value += value ;
33+ insertPlaceholder ( value ) {
34+ const editor = this . editor ;
35+ const startPos = editor . selectionStart ;
36+ const endPos = editor . selectionEnd ;
37+ editor . value = editor . value . substring ( 0 , startPos ) + value + editor . value . substring ( endPos ) ;
38+ editor . selectionStart = startPos ;
39+ editor . selectionEnd = startPos + value . length ;
40+ editor . focus ( ) ;
41+ }
42+
43+ replacePlaceholder ( oldVal , newVal ) {
44+ const editor = this . editor ;
45+ const startPos = editor . selectionStart ;
46+ const endPos = editor . selectionEnd ;
47+ if ( editor . value . substring ( startPos , endPos ) === oldVal ) {
48+ editor . value = editor . value . substring ( 0 , startPos ) + newVal + editor . value . substring ( endPos ) ;
49+ editor . selectionEnd = startPos + newVal . length ;
50+ } else {
51+ editor . value = editor . value . replace ( oldVal , newVal ) ;
52+ editor . selectionEnd -= oldVal . length ;
53+ editor . selectionEnd += newVal . length ;
54+ }
55+ editor . selectionStart = editor . selectionEnd ;
56+ editor . focus ( ) ;
4257 }
4358}
4459
45- function replaceAndKeepCursor ( field , oldval , newval ) {
46- if ( field . selectionStart || field . selectionStart === 0 ) {
47- const startPos = field . selectionStart ;
48- const endPos = field . selectionEnd ;
49- field . value = field . value . replace ( oldval , newval ) ;
50- field . selectionStart = startPos + newval . length - oldval . length ;
51- field . selectionEnd = endPos + newval . length - oldval . length ;
52- } else {
53- field . value = field . value . replace ( oldval , newval ) ;
60+ class CodeMirrorEditor {
61+ constructor ( editor ) {
62+ this . editor = editor ;
63+ }
64+
65+ insertPlaceholder ( value ) {
66+ const editor = this . editor ;
67+ const startPoint = editor . getCursor ( 'start' ) ;
68+ const endPoint = editor . getCursor ( 'end' ) ;
69+ editor . replaceSelection ( value ) ;
70+ endPoint . ch = startPoint . ch + value . length ;
71+ editor . setSelection ( startPoint , endPoint ) ;
72+ editor . focus ( ) ;
73+ }
74+
75+ replacePlaceholder ( oldVal , newVal ) {
76+ const editor = this . editor ;
77+ const endPoint = editor . getCursor ( 'end' ) ;
78+ if ( editor . getSelection ( ) === oldVal ) {
79+ editor . replaceSelection ( newVal ) ;
80+ } else {
81+ editor . setValue ( editor . getValue ( ) . replace ( oldVal , newVal ) ) ;
82+ }
83+ endPoint . ch -= oldVal . length ;
84+ endPoint . ch += newVal . length ;
85+ editor . setSelection ( endPoint , endPoint ) ;
86+ editor . focus ( ) ;
5487 }
5588}
5689
57- export function initCompImagePaste ( $target ) {
58- $target . each ( function ( ) {
59- const dropzone = this . querySelector ( '.dropzone' ) ;
60- if ( ! dropzone ) {
90+
91+ export function initEasyMDEImagePaste ( easyMDE , $dropzone ) {
92+ const uploadUrl = $dropzone . attr ( 'data-upload-url' ) ;
93+ const $files = $dropzone . find ( '.files' ) ;
94+
95+ if ( ! uploadUrl || ! $files . length ) return ;
96+
97+ const uploadClipboardImage = async ( editor , e ) => {
98+ const pastedImages = clipboardPastedImages ( e ) ;
99+ if ( ! pastedImages || pastedImages . length === 0 ) {
61100 return ;
62101 }
63- const uploadUrl = dropzone . getAttribute ( 'data-upload-url' ) ;
64- const dropzoneFiles = dropzone . querySelector ( '.files' ) ;
65- for ( const textarea of this . querySelectorAll ( 'textarea' ) ) {
66- textarea . addEventListener ( 'paste' , async ( e ) => {
67- for ( const img of clipboardPastedImages ( e ) ) {
68- const name = img . name . slice ( 0 , img . name . lastIndexOf ( '.' ) ) ;
69- insertAtCursor ( textarea , `![${ name } ]()` ) ;
70- const data = await uploadFile ( img , uploadUrl ) ;
71- replaceAndKeepCursor ( textarea , `![${ name } ]()` , `` ) ;
72- const input = $ ( `<input id="${ data . uuid } " name="files" type="hidden">` ) . val ( data . uuid ) ;
73- dropzoneFiles . appendChild ( input [ 0 ] ) ;
74- }
75- } , false ) ;
76- }
77- } ) ;
78- }
102+ e . preventDefault ( ) ;
103+ e . stopPropagation ( ) ;
79104
80- export function initEasyMDEImagePaste ( easyMDE , dropzone , files ) {
81- const uploadUrl = dropzone . getAttribute ( 'data-upload-url' ) ;
82- easyMDE . codemirror . on ( 'paste' , async ( _ , e ) => {
83- for ( const img of clipboardPastedImages ( e ) ) {
105+ for ( const img of pastedImages ) {
84106 const name = img . name . slice ( 0 , img . name . lastIndexOf ( '.' ) ) ;
107+
108+ const placeholder = `` ;
109+ editor . insertPlaceholder ( placeholder ) ;
85110 const data = await uploadFile ( img , uploadUrl ) ;
86- const pos = easyMDE . codemirror . getCursor ( ) ;
87- easyMDE . codemirror . replaceRange ( `` , pos ) ;
88- const input = $ ( `<input id=" ${ data . uuid } " name="files" type="hidden">` ) . val ( data . uuid ) ;
89- files . append ( input ) ;
111+ editor . replacePlaceholder ( placeholder , `` ) ;
112+
113+ const $ input = $ ( `<input name="files" type="hidden">` ) . attr ( 'id' , data . uuid ) . val ( data . uuid ) ;
114+ $ files. append ( $ input) ;
90115 }
116+ } ;
117+
118+ easyMDE . codemirror . on ( 'paste' , async ( _ , e ) => {
119+ return uploadClipboardImage ( new CodeMirrorEditor ( easyMDE . codemirror ) , e ) ;
120+ } ) ;
121+
122+ $ ( easyMDE . element ) . on ( 'paste' , async ( e ) => {
123+ return uploadClipboardImage ( new TextareaEditor ( easyMDE . element ) , e . originalEvent ) ;
91124 } ) ;
92125}
0 commit comments