공개 본문 문단 편집 분리
This commit is contained in:
@@ -18,11 +18,7 @@ import {
|
||||
parseOrderedListMarker,
|
||||
stripListMarker
|
||||
} from '../../lib/markdown-live-edit.js'
|
||||
import { buildCodeFenceOpener } from '../../lib/markdown-code-block.js'
|
||||
import {
|
||||
buildCalloutOpenerLine,
|
||||
CALLOUT_BACKGROUND_OPTIONS
|
||||
} from '../../lib/markdown-callout.js'
|
||||
import { CALLOUT_BACKGROUND_OPTIONS } from '../../lib/markdown-callout.js'
|
||||
import {
|
||||
formatQuoteLine,
|
||||
getQuoteContentStartLine,
|
||||
@@ -35,6 +31,7 @@ import { useContentMarkdownBlocks } from '../../composables/useContentMarkdownBl
|
||||
import { useContentMarkdownImageDrag } from '../../composables/useContentMarkdownImageDrag.js'
|
||||
import { useContentMarkdownLiveSelection } from '../../composables/useContentMarkdownLiveSelection.js'
|
||||
import { useContentMarkdownFencedBlocks } from '../../composables/useContentMarkdownFencedBlocks.js'
|
||||
import { useContentMarkdownParagraphs } from '../../composables/useContentMarkdownParagraphs.js'
|
||||
import ContentMarkdownCodeBlockEditor from './ContentMarkdownCodeBlockEditor.vue'
|
||||
import ProseCodeBlock from './ProseCodeBlock.vue'
|
||||
import ProseHtml from './ProseHtml.vue'
|
||||
@@ -91,9 +88,6 @@ const emit = defineEmits([
|
||||
const CONTENT_LIST_MARKER_COLOR = '#2eb6ea'
|
||||
/** @type {import('vue').Ref<Record<string, number>>} 갤러리 이미지 자연 비율 */
|
||||
const galleryImageAspectRatios = ref({})
|
||||
/** @type {number} 문단 분리 연속 호출 방지 */
|
||||
let lastParagraphSplitAt = 0
|
||||
|
||||
const {
|
||||
activeLightboxImages,
|
||||
activeLightboxImage,
|
||||
@@ -185,6 +179,17 @@ const {
|
||||
insertBelowBlock: (block, options) => onInsertBelowBlock(block, options)
|
||||
})
|
||||
|
||||
const {
|
||||
onParagraphInlineCommit,
|
||||
onSpacerInlineCommit,
|
||||
onParagraphLiveInput,
|
||||
onParagraphSplit
|
||||
} = useContentMarkdownParagraphs({
|
||||
pendingFocusLine,
|
||||
pendingFocusPosition,
|
||||
commitInlineBlockLines: (block, replacementLines) => commitInlineBlockLines(block, replacementLines)
|
||||
})
|
||||
|
||||
/**
|
||||
* 빈 줄 공백 블록 높이를 반환한다.
|
||||
* @param {Object} block - 렌더링 블록
|
||||
@@ -489,140 +494,6 @@ const onInsertAboveBlock = (block) => {
|
||||
})
|
||||
}
|
||||
|
||||
const onParagraphInlineCommit = (block, text) => {
|
||||
const value = String(text ?? '').replace(/\r/g, '')
|
||||
const lines = value.split('\n').map((line) => line.trimEnd())
|
||||
|
||||
if (lines.length <= 1) {
|
||||
commitInlineBlockLines(block, [lines[0] ?? ''])
|
||||
return
|
||||
}
|
||||
|
||||
commitInlineBlockLines(block, lines.filter((line) => line.length > 0))
|
||||
}
|
||||
|
||||
/**
|
||||
* 빈 줄(스페이서) 편집 반영
|
||||
* @param {Object} block - 블록
|
||||
* @param {string} text - 편집된 텍스트
|
||||
* @returns {void}
|
||||
*/
|
||||
const onSpacerInlineCommit = (block, text) => {
|
||||
if (!String(text ?? '').trim()) {
|
||||
return
|
||||
}
|
||||
|
||||
commitInlineBlockLines(block, [text])
|
||||
}
|
||||
|
||||
/**
|
||||
* 문단 입력 중 블록 단축 변환을 처리한다.
|
||||
* @param {Object} block - 문단 블록
|
||||
* @param {string} text - 입력 텍스트
|
||||
* @returns {void}
|
||||
*/
|
||||
const onParagraphLiveInput = (block, text) => {
|
||||
if (String(text ?? '').trim() !== '>') {
|
||||
return
|
||||
}
|
||||
|
||||
pendingFocusLine.value = block.meta.startLine
|
||||
pendingFocusPosition.value = 'start'
|
||||
commitInlineBlockLines(block, ['> '])
|
||||
}
|
||||
|
||||
/**
|
||||
* 문단 Enter 분리 결과 줄 배열을 만든다.
|
||||
* @param {string} head - 커서 앞 텍스트
|
||||
* @param {string} tail - 커서 뒤 텍스트
|
||||
* @returns {string[]} 분리된 줄
|
||||
*/
|
||||
const buildParagraphSplitLines = (head, tail) => {
|
||||
const h = String(head ?? '').replace(/\n/g, ' ')
|
||||
const t = String(tail ?? '').replace(/\n/g, ' ')
|
||||
|
||||
if (!t.length) {
|
||||
return [h, '']
|
||||
}
|
||||
|
||||
if (!h.length) {
|
||||
return ['', t]
|
||||
}
|
||||
|
||||
return [h, t]
|
||||
}
|
||||
|
||||
/**
|
||||
* 문단 Enter 입력을 블록 단축 입력으로 변환할지 확인한다.
|
||||
* @param {Object} block - 문단 블록
|
||||
* @param {string} before - 커서 앞 텍스트
|
||||
* @param {string} after - 커서 뒤 텍스트
|
||||
* @returns {boolean} 변환 처리 여부
|
||||
*/
|
||||
const applyParagraphShortcutSplit = (block, before, after) => {
|
||||
const head = String(before ?? '').trim()
|
||||
const tail = String(after ?? '')
|
||||
|
||||
if (tail.trim()) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (/^```[A-Za-z0-9_-]*$/.test(head)) {
|
||||
const opener = head === '```' ? buildCodeFenceOpener({ language: '', showLineNumbers: false }) : head
|
||||
|
||||
pendingFocusLine.value = block.meta.startLine + 1
|
||||
pendingFocusPosition.value = 'start'
|
||||
commitInlineBlockLines(block, [opener, '', '```'])
|
||||
return true
|
||||
}
|
||||
|
||||
if (head === '!!!' || head === ':::callout') {
|
||||
pendingFocusLine.value = block.meta.startLine + 1
|
||||
pendingFocusPosition.value = 'start'
|
||||
commitInlineBlockLines(block, [
|
||||
buildCalloutOpenerLine({
|
||||
calloutEmojiEnabled: false,
|
||||
calloutEmoji: '💡',
|
||||
calloutBackground: 'blue',
|
||||
title: ''
|
||||
}),
|
||||
'',
|
||||
'',
|
||||
':::'
|
||||
])
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 문단 Enter 분리 — 마크다운에 빈 줄을 넣어 다음 문단을 만든다.
|
||||
* @param {Object} block - 블록
|
||||
* @param {{ before: string, after: string }} payload - 커서 앞·뒤 텍스트
|
||||
* @returns {void}
|
||||
*/
|
||||
const onParagraphSplit = (block, { before, after }) => {
|
||||
const now = Date.now()
|
||||
|
||||
if (now - lastParagraphSplitAt < 120) {
|
||||
return
|
||||
}
|
||||
|
||||
lastParagraphSplitAt = now
|
||||
|
||||
if (applyParagraphShortcutSplit(block, before, after)) {
|
||||
return
|
||||
}
|
||||
|
||||
const replacementLines = buildParagraphSplitLines(before, after)
|
||||
const focusLine = block.meta.startLine + Math.max(replacementLines.length - 1, 1)
|
||||
|
||||
pendingFocusLine.value = focusLine
|
||||
pendingFocusPosition.value = 'start'
|
||||
commitInlineBlockLines(block, replacementLines)
|
||||
}
|
||||
|
||||
/**
|
||||
* 블록 아래에 줄을 삽입한다.
|
||||
* @param {Object} block - 블록
|
||||
|
||||
Reference in New Issue
Block a user