라이브 에디터 콜아웃 줄 삭제 수정

This commit is contained in:
2026-06-04 11:09:40 +09:00
parent 83f66a4b93
commit 675e6bca78
12 changed files with 111 additions and 11 deletions

View File

@@ -33,7 +33,7 @@ const props = defineProps({
}
})
const emit = defineEmits(['commit'])
const emit = defineEmits(['commit', 'delete-line', 'insert-below', 'merge-with-previous', 'leave-block'])
/**
* 콜아웃 마크다운 줄을 반영한다.
@@ -62,6 +62,15 @@ const commitCallout = (body) => {
const onBodyCommit = (body) => {
commitCallout(body)
}
/**
* 콜아웃 아래로 이탈한다.
* @param {Object} payload - 이탈 페이로드
* @returns {void}
*/
const onExitBelow = (payload) => {
emit('insert-below', payload)
}
</script>
<template>
@@ -87,6 +96,10 @@ const onBodyCommit = (body) => {
:source-line="bodySourceLine"
:model-value="modelValue"
@commit="onBodyCommit"
@delete-line="emit('delete-line', $event)"
@insert-below="onExitBelow"
@merge-with-previous="emit('merge-with-previous', $event)"
@leave-block="emit('leave-block', $event)"
/>
</div>
</ProseCallout>

View File

@@ -26,7 +26,7 @@ const props = defineProps({
}
})
const emit = defineEmits(['commit', 'insert-below'])
const emit = defineEmits(['commit', 'insert-below', 'delete-line'])
const languageDraft = ref(props.language)
const lineNumbersEnabled = ref(props.showLineNumbers)
@@ -161,6 +161,7 @@ const toggleLineNumbers = () => {
@input="onBodyInput"
@commit="onBodyCommit"
@insert-below="onExitBelow"
@delete-line="emit('delete-line', $event)"
/>
</ProseCodeBlock>
</template>

View File

@@ -736,9 +736,14 @@ const onKeydown = (event) => {
if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === 'k') {
if (props.sourceLine !== null) {
const lineContext = getCaretLineContext()
const sourceLine = resolvedEnterMode.value === 'multiline'
? props.sourceLine + lineContext.lineIndex
: props.sourceLine
event.preventDefault()
event.stopPropagation()
emit('delete-line', props.sourceLine)
emit('delete-line', sourceLine)
}
return
@@ -861,6 +866,7 @@ const onKeydown = (event) => {
if (event.key === 'Enter' && !event.shiftKey && parseSlashInput(readEditorValue())) {
event.preventDefault()
event.stopPropagation()
event.stopImmediatePropagation?.()
emit('slash-apply', {
sourceLine: props.sourceLine,
value: readEditorValue()

View File

@@ -1271,6 +1271,26 @@ const onCalloutBlockCommit = (block, replacementLines) => {
commitInlineBlockLines(block, replacementLines)
}
/**
* 콜아웃 마지막 줄에서 아래로 이탈한다.
* @param {Object} block - 콜아웃 블록
* @param {string|Object} payload - insert-below 페이로드
* @returns {void}
*/
const onCalloutBlockInsertBelow = (block, payload) => {
const { value } = normalizeInsertBelowPayload(payload)
const openingLine = getMarkdownLine(block.meta.startLine)
onCalloutBlockCommit(block, [
openingLine,
...String(value ?? '').replace(/\r/g, '').split('\n'),
':::'
])
pendingFocusPosition.value = 'start'
pendingFocusOffset.value = 0
onInsertBelowBlock(block, { lines: [''] })
}
/**
* 토글 편집 반영
* @param {Object} block - 토글 블록
@@ -1782,6 +1802,39 @@ const onDeleteLine = (lineIndex) => {
return
}
const fencedBlock = blocks.value.find((block) => {
const startLine = block.meta?.startLine
const endLine = block.meta?.endLine
return ['callout', 'code', 'toggle'].includes(block.type)
&& typeof startLine === 'number'
&& typeof endLine === 'number'
&& lineIndex > startLine
&& lineIndex < endLine
})
if (fencedBlock) {
const startLine = fencedBlock.meta.startLine
const endLine = fencedBlock.meta.endLine
const bodyLineCount = Math.max(0, endLine - startLine - 1)
if (bodyLineCount <= 1) {
pendingFocusLine.value = startLine > 0 ? startLine - 1 : 0
pendingFocusPosition.value = startLine > 0 ? 'end' : 'start'
emit('block-content-change', {
startLine,
endLine,
replacementLines: []
})
return
}
pendingFocusLine.value = lineIndex > startLine + 1 ? lineIndex - 1 : lineIndex
pendingFocusPosition.value = lineIndex > startLine + 1 ? 'end' : 'start'
emit('delete-line', lineIndex)
return
}
const focusLine = lineIndex > 0 ? lineIndex - 1 : 0
pendingFocusLine.value = focusLine
@@ -2555,6 +2608,9 @@ onBeforeUnmount(() => {
:body-source-line="block.meta.startLine + 1"
:model-value="block.text"
@commit="onCalloutBlockCommit(block, $event)"
@delete-line="onDeleteLine"
@insert-below="onCalloutBlockInsertBelow(block, $event)"
@merge-with-previous="onMergeWithPreviousLine(block.meta.startLine + 1, $event)"
/>
<ProseCallout
v-else-if="block.type === 'callout'"
@@ -2579,6 +2635,7 @@ onBeforeUnmount(() => {
:model-value="block.text"
@commit="onToggleBlockCommit(block, $event)"
@insert-below="onToggleBlockInsertBelow(block, $event)"
@delete-line="onDeleteLine"
/>
<ProseToggle v-else-if="block.type === 'toggle'" :title="block.title || '더 보기'" :default-open="block.defaultOpen" animated>
<template v-for="(segment, segmentIndex) in parseInlineSegments(block.text)" :key="`${block.id}-toggle-${segmentIndex}`">
@@ -2771,6 +2828,7 @@ onBeforeUnmount(() => {
:model-value="block.text"
@commit="onCodeBlockCommit(block, $event)"
@insert-below="onCodeBlockInsertBelow(block, $event)"
@delete-line="onDeleteLine"
/>
<ProseCodeBlock
v-else-if="block.type === 'code'"

View File

@@ -31,7 +31,7 @@ const props = defineProps({
}
})
const emit = defineEmits(['commit', 'insert-below'])
const emit = defineEmits(['commit', 'insert-below', 'delete-line'])
const titleEditorRef = ref(null)
const bodyEditorRef = ref(null)
@@ -141,6 +141,7 @@ const onExitBelow = (payload) => {
:model-value="modelValue"
@commit="onBodyCommit"
@insert-below="onExitBelow"
@delete-line="emit('delete-line', $event)"
/>
</ProseToggle>
</template>