1export function createEditor({2 element,3 source,4 diagramType,5 language,6 ariaLabel = 'Diagram source editor',7 onChange,8 onSave,9}) {10 let suppressChanges = 011 const textarea = document.createElement('textarea')12 textarea.className = 'source-editor-textarea'13 textarea.value = source14 textarea.dataset.language = language ?? diagramType15 textarea.setAttribute('aria-label', ariaLabel)16 textarea.setAttribute('autocapitalize', 'off')17 textarea.setAttribute('autocomplete', 'off')18 textarea.setAttribute('autocorrect', 'off')19 textarea.setAttribute('spellcheck', 'false')20 textarea.setAttribute('wrap', 'off')2122 const handleInput = () => {23 if (suppressChanges === 0) onChange()24 }25 const handleKeydown = event => {26 if (!(event.metaKey || event.ctrlKey) || event.key.toLowerCase() !== 's') return27 event.preventDefault()28 event.stopPropagation()29 onSave()30 }31 textarea.addEventListener('input', handleInput)32 textarea.addEventListener('keydown', handleKeydown)33 element.replaceChildren(textarea)3435 return {36 backend: 'textarea',37 getValue: () => textarea.value,38 setDocument({ source: nextSource, diagramType: nextType = diagramType, language: nextLanguage = language }) {39 suppressChanges += 140 try {41 const start = Math.min(textarea.selectionStart, nextSource.length)42 const end = Math.min(textarea.selectionEnd, nextSource.length)43 textarea.value = nextSource44 textarea.dataset.language = nextLanguage ?? nextType45 textarea.setSelectionRange(start, end)46 } finally {47 suppressChanges -= 148 }49 },50 focus: () => textarea.focus(),51 layout() {},52 dispose() {53 textarea.removeEventListener('input', handleInput)54 textarea.removeEventListener('keydown', handleKeydown)55 textarea.remove()56 },57 }58}