@moda-editor/core 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/commands.d.ts +78 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +299 -0
- package/dist/commands.js.map +1 -0
- package/dist/conformance.d.ts +59 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +1609 -0
- package/dist/conformance.js.map +1 -0
- package/dist/core.d.ts +37 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +117 -0
- package/dist/core.js.map +1 -0
- package/dist/editor/editor.d.ts +104 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +204 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/extension.d.ts +170 -0
- package/dist/editor/extension.d.ts.map +1 -0
- package/dist/editor/extension.js +2 -0
- package/dist/editor/extension.js.map +1 -0
- package/dist/features/ace.d.ts +9 -0
- package/dist/features/ace.d.ts.map +1 -0
- package/dist/features/ace.js +144 -0
- package/dist/features/ace.js.map +1 -0
- package/dist/features/alignment.d.ts +9 -0
- package/dist/features/alignment.d.ts.map +1 -0
- package/dist/features/alignment.js +28 -0
- package/dist/features/alignment.js.map +1 -0
- package/dist/features/blockquote.d.ts +9 -0
- package/dist/features/blockquote.d.ts.map +1 -0
- package/dist/features/blockquote.js +65 -0
- package/dist/features/blockquote.js.map +1 -0
- package/dist/features/code-block.d.ts +77 -0
- package/dist/features/code-block.d.ts.map +1 -0
- package/dist/features/code-block.js +986 -0
- package/dist/features/code-block.js.map +1 -0
- package/dist/features/doc.d.ts +15 -0
- package/dist/features/doc.d.ts.map +1 -0
- package/dist/features/doc.js +79 -0
- package/dist/features/doc.js.map +1 -0
- package/dist/features/feature.d.ts +26 -0
- package/dist/features/feature.d.ts.map +1 -0
- package/dist/features/feature.js +8 -0
- package/dist/features/feature.js.map +1 -0
- package/dist/features/hard-break.d.ts +9 -0
- package/dist/features/hard-break.d.ts.map +1 -0
- package/dist/features/hard-break.js +48 -0
- package/dist/features/hard-break.js.map +1 -0
- package/dist/features/heading.d.ts +3 -0
- package/dist/features/heading.d.ts.map +1 -0
- package/dist/features/heading.js +31 -0
- package/dist/features/heading.js.map +1 -0
- package/dist/features/horizontal-rule.d.ts +9 -0
- package/dist/features/horizontal-rule.d.ts.map +1 -0
- package/dist/features/horizontal-rule.js +64 -0
- package/dist/features/horizontal-rule.js.map +1 -0
- package/dist/features/image.d.ts +12 -0
- package/dist/features/image.d.ts.map +1 -0
- package/dist/features/image.js +116 -0
- package/dist/features/image.js.map +1 -0
- package/dist/features/index.d.ts +31 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +65 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/inline-style.d.ts +12 -0
- package/dist/features/inline-style.d.ts.map +1 -0
- package/dist/features/inline-style.js +126 -0
- package/dist/features/inline-style.js.map +1 -0
- package/dist/features/link.d.ts +29 -0
- package/dist/features/link.d.ts.map +1 -0
- package/dist/features/link.js +198 -0
- package/dist/features/link.js.map +1 -0
- package/dist/features/lists.d.ts +14 -0
- package/dist/features/lists.d.ts.map +1 -0
- package/dist/features/lists.js +178 -0
- package/dist/features/lists.js.map +1 -0
- package/dist/features/marks.d.ts +6 -0
- package/dist/features/marks.d.ts.map +1 -0
- package/dist/features/marks.js +68 -0
- package/dist/features/marks.js.map +1 -0
- package/dist/features/script.d.ts +2 -0
- package/dist/features/script.d.ts.map +1 -0
- package/dist/features/script.js +55 -0
- package/dist/features/script.js.map +1 -0
- package/dist/features/table.d.ts +20 -0
- package/dist/features/table.d.ts.map +1 -0
- package/dist/features/table.js +195 -0
- package/dist/features/table.js.map +1 -0
- package/dist/features/task-list.d.ts +10 -0
- package/dist/features/task-list.d.ts.map +1 -0
- package/dist/features/task-list.js +68 -0
- package/dist/features/task-list.js.map +1 -0
- package/dist/features/testkit.d.ts +32 -0
- package/dist/features/testkit.d.ts.map +1 -0
- package/dist/features/testkit.js +92 -0
- package/dist/features/testkit.js.map +1 -0
- package/dist/history.d.ts +40 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +192 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/model/node.d.ts +47 -0
- package/dist/model/node.d.ts.map +1 -0
- package/dist/model/node.js +30 -0
- package/dist/model/node.js.map +1 -0
- package/dist/model/schema.d.ts +105 -0
- package/dist/model/schema.d.ts.map +1 -0
- package/dist/model/schema.js +46 -0
- package/dist/model/schema.js.map +1 -0
- package/dist/model/traverse.d.ts +36 -0
- package/dist/model/traverse.d.ts.map +1 -0
- package/dist/model/traverse.js +123 -0
- package/dist/model/traverse.js.map +1 -0
- package/dist/mount.d.ts +24 -0
- package/dist/mount.d.ts.map +1 -0
- package/dist/mount.js +45 -0
- package/dist/mount.js.map +1 -0
- package/dist/parse/html.d.ts +8 -0
- package/dist/parse/html.d.ts.map +1 -0
- package/dist/parse/html.js +247 -0
- package/dist/parse/html.js.map +1 -0
- package/dist/parse/sanitize.d.ts +20 -0
- package/dist/parse/sanitize.d.ts.map +1 -0
- package/dist/parse/sanitize.js +116 -0
- package/dist/parse/sanitize.js.map +1 -0
- package/dist/presets/highlight.d.ts +23 -0
- package/dist/presets/highlight.d.ts.map +1 -0
- package/dist/presets/highlight.js +170 -0
- package/dist/presets/highlight.js.map +1 -0
- package/dist/presets/starter.d.ts +14 -0
- package/dist/presets/starter.d.ts.map +1 -0
- package/dist/presets/starter.js +18 -0
- package/dist/presets/starter.js.map +1 -0
- package/dist/state/apply.d.ts +64 -0
- package/dist/state/apply.d.ts.map +1 -0
- package/dist/state/apply.js +528 -0
- package/dist/state/apply.js.map +1 -0
- package/dist/state/navigate.d.ts +5 -0
- package/dist/state/navigate.d.ts.map +1 -0
- package/dist/state/navigate.js +81 -0
- package/dist/state/navigate.js.map +1 -0
- package/dist/state/selection.d.ts +44 -0
- package/dist/state/selection.d.ts.map +1 -0
- package/dist/state/selection.js +63 -0
- package/dist/state/selection.js.map +1 -0
- package/dist/state/state.d.ts +39 -0
- package/dist/state/state.d.ts.map +1 -0
- package/dist/state/state.js +123 -0
- package/dist/state/state.js.map +1 -0
- package/dist/state/transaction.d.ts +234 -0
- package/dist/state/transaction.d.ts.map +1 -0
- package/dist/state/transaction.js +988 -0
- package/dist/state/transaction.js.map +1 -0
- package/dist/styles.css +948 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/view/dom.d.ts +26 -0
- package/dist/view/dom.d.ts.map +1 -0
- package/dist/view/dom.js +249 -0
- package/dist/view/dom.js.map +1 -0
- package/dist/view/input.d.ts +45 -0
- package/dist/view/input.d.ts.map +1 -0
- package/dist/view/input.js +901 -0
- package/dist/view/input.js.map +1 -0
- package/dist/view/mount.d.ts +26 -0
- package/dist/view/mount.d.ts.map +1 -0
- package/dist/view/mount.js +119 -0
- package/dist/view/mount.js.map +1 -0
- package/dist/view/render.d.ts +64 -0
- package/dist/view/render.d.ts.map +1 -0
- package/dist/view/render.js +203 -0
- package/dist/view/render.js.map +1 -0
- package/dist/view/serialize.d.ts +4 -0
- package/dist/view/serialize.d.ts.map +1 -0
- package/dist/view/serialize.js +37 -0
- package/dist/view/serialize.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { DocNode, EditorNode } from "../model/node.js";
|
|
2
|
+
import type { MarkSpec, NodeSpec } from "../model/schema.js";
|
|
3
|
+
import type { Point, Range } from "../state/selection.js";
|
|
4
|
+
import type { EditorState } from "../state/state.js";
|
|
5
|
+
import type { Transaction } from "../state/transaction.js";
|
|
6
|
+
import type { Editor } from "./editor.js";
|
|
7
|
+
/**
|
|
8
|
+
* 확장 모델 — Extension이 기능 번들, Node/Mark는 Schema spec으로 흡수.
|
|
9
|
+
*
|
|
10
|
+
* Tiptap은 Extension 하나에 스키마+커맨드+플러그인을 다 섞어 각 조각을
|
|
11
|
+
* 따로 검증하기 어렵다. moda-editor는 Extension을 "번들"로만 취급하고
|
|
12
|
+
* 코어가 레이어별로 분리 실행한다:
|
|
13
|
+
* nodes/marks → Schema 조립
|
|
14
|
+
* commands → 커맨드 레지스트리 (editor.commands.<name>)
|
|
15
|
+
* keymap → 키 입력 처리
|
|
16
|
+
* inputRules → 텍스트 입력 규칙
|
|
17
|
+
* plugins → 트랜잭션 필터/후처리/전용 상태
|
|
18
|
+
* 각 레이어가 독립적이라 스키마만 떼어 검증하거나 커맨드만 단위 테스트할
|
|
19
|
+
* 수 있다.
|
|
20
|
+
*/
|
|
21
|
+
/** 커맨드 실행 컨텍스트 — tr을 채우고 dispatch로 확정한다 */
|
|
22
|
+
export interface CommandContext {
|
|
23
|
+
readonly state: EditorState;
|
|
24
|
+
readonly tr: Transaction;
|
|
25
|
+
/** 채워진 tr을 디스패치한다 — false 반환 커맨드는 호출하면 안 된다 */
|
|
26
|
+
dispatch(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 커맨드 — true면 처리 완료. keymap 체인에서 false는 다음 바인딩으로
|
|
30
|
+
* 폴스루를 의미한다 (PM keymap 관례). 추가 인자는 commands 레지스트리
|
|
31
|
+
* 경유 호출 시 전달된다 (toggleBold() vs setHeading(2)).
|
|
32
|
+
*/
|
|
33
|
+
export type Command = (ctx: CommandContext, ...args: unknown[]) => boolean;
|
|
34
|
+
/** "Mod-b" | "Enter" | "Shift-ArrowUp" → Command */
|
|
35
|
+
export type Keymap = Record<string, Command>;
|
|
36
|
+
/**
|
|
37
|
+
* 입력 규칙 — 타이핑으로 텍스트가 삽입된 직후, 커서에서 끝나는 패턴을
|
|
38
|
+
* 변환한다 (마크다운 `# `→heading, `**x**`→bold 등).
|
|
39
|
+
* input.ts가 insertText 스텝을 쌓은 뒤 같은 tr 위에서 실행하므로
|
|
40
|
+
* 삽입+변환이 하나의 트랜잭션(= 하나의 undo 단위)이 된다.
|
|
41
|
+
*/
|
|
42
|
+
export interface InputRule {
|
|
43
|
+
/** 블록 시작~커서 사이 텍스트에 매칭 — 매치가 커서에서 끝날 때만 발동 */
|
|
44
|
+
pattern: RegExp;
|
|
45
|
+
/**
|
|
46
|
+
* 매치 변환 — tr에 변환 스텝을 쌓는다.
|
|
47
|
+
* range는 누적 스텝 적용 후 좌표의 매치 범위(focus=캐럿),
|
|
48
|
+
* doc은 누적 스텝 적용 후 문서(핸들러 자신의 스텝 전 상태).
|
|
49
|
+
* ctx.dispatch는 no-op — 디스패치는 호출부가 tr 전체를 한 번에 한다.
|
|
50
|
+
* false를 반환하면 다음 규칙으로 폴스루, 그 외는 소비된 것으로 본다.
|
|
51
|
+
*/
|
|
52
|
+
handler: (ctx: CommandContext, match: RegExpMatchArray, range: Range, doc: DocNode) => boolean | void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 블록 문자 좌표 컨텍스트 — 입력 훅이 텍스트 자식 블록 안의
|
|
56
|
+
* 캐럿/범위를 플랫 텍스트 좌표로 다루게 하는 뷰. 앵커와 포커스가
|
|
57
|
+
* 모두 같은 블록 안에 있을 때만 만들어진다 (블록을 걸치는 범위는
|
|
58
|
+
* 훅이 받지 않는다).
|
|
59
|
+
*/
|
|
60
|
+
export interface BlockTextCtx extends CommandContext {
|
|
61
|
+
/** 캐럿을 품은 블록과 doc path */
|
|
62
|
+
readonly block: EditorNode;
|
|
63
|
+
readonly blockPath: readonly number[];
|
|
64
|
+
/** 블록의 텍스트 자식들을 합친 전체 문자열 */
|
|
65
|
+
readonly text: string;
|
|
66
|
+
/** 정규화된 텍스트 범위(doc 좌표) — anchor ≤ focus */
|
|
67
|
+
readonly anchor: Point;
|
|
68
|
+
readonly focus: Point;
|
|
69
|
+
/** 블록 문자 오프셋 → doc Point */
|
|
70
|
+
charPoint(offset: number): Point;
|
|
71
|
+
/** doc Point → 블록 문자 오프셋 */
|
|
72
|
+
offsetOf(p: Point): number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 범위 컨텍스트 — 텍스트 셀렉션의 정규화 좌표만 제공하는 입력 훅
|
|
76
|
+
* 컨텍스트. 블록 경계와 무관해 범위가 블록을 걸쳐도 유효하다.
|
|
77
|
+
*/
|
|
78
|
+
export interface RangeCtx extends CommandContext {
|
|
79
|
+
readonly anchor: Point;
|
|
80
|
+
readonly focus: Point;
|
|
81
|
+
}
|
|
82
|
+
/** 붙여넣기 페이로드 — 클립보드의 대표 두 형식 */
|
|
83
|
+
export interface PasteData {
|
|
84
|
+
readonly html: string | undefined;
|
|
85
|
+
readonly text: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 파일 붙여넣기/드롭 컨텍스트 — paste/drop DOM 이벤트 레벨 훅용.
|
|
89
|
+
* beforeinput보다 먼저 오는 이벤트라 별도 ctx다. 비동기 업로드처럼
|
|
90
|
+
* tr을 즉시 채우지 않는 흐름을 위해 커맨드·디스패치 접근이 가능한
|
|
91
|
+
* 에디터 파사드를 넘긴다.
|
|
92
|
+
*/
|
|
93
|
+
export interface FileDropCtx {
|
|
94
|
+
readonly editor: Editor;
|
|
95
|
+
readonly files: readonly File[];
|
|
96
|
+
/** 드롭 좌표 해석 포인트 — paste 이벤트면 null */
|
|
97
|
+
readonly at: Point | null;
|
|
98
|
+
readonly source: "paste" | "drop";
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 뷰 입력 훅 — beforeinput 단계에 기능이 끼어드는 계약.
|
|
102
|
+
* 각 훅은 처리하면 true를 반환하고 ctx.dispatch()로 tr을 확정한다
|
|
103
|
+
* (커맨드와 같은 규칙). false면 다음 훅 → 기본 동작으로 폴스루한다.
|
|
104
|
+
* 실행 순서는 확장 배열 순서 — keymap과 같은 폴스루 모델이다.
|
|
105
|
+
* 코어는 이 훅을 통해 코드블록 자동 쌍처럼 기능 고유의 타이핑
|
|
106
|
+
* 동작을 input.ts에 심지 않고 기능 모듈에 둔다.
|
|
107
|
+
*/
|
|
108
|
+
export interface InputHooks {
|
|
109
|
+
/**
|
|
110
|
+
* 텍스트 삽입 전 — 자동 쌍·타입오버 같은 글자 가로채기.
|
|
111
|
+
* inputType은 beforeinput의 값("insertText"/"insertCompositionText"
|
|
112
|
+
* 등) — IME 커밋을 리터럴로 취급할지 기능이 판단한다.
|
|
113
|
+
*/
|
|
114
|
+
insertText?(ctx: BlockTextCtx, data: string, inputType: string): boolean;
|
|
115
|
+
/** collapsed 캐럿에서의 개행 — 자동 들여쓰기·블록 탈출 등 */
|
|
116
|
+
insertParagraph?(ctx: BlockTextCtx): boolean;
|
|
117
|
+
/** collapsed 캐럿에서의 Backspace — 쌍 삭제 등 */
|
|
118
|
+
deleteBackward?(ctx: BlockTextCtx): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* 클립보드 붙여넣기 — insertFromPaste 단계. 선택 위 URL 감싸기
|
|
121
|
+
* (링크)·코드블록 순수 텍스트 삽입 같은 기능별 정책을 구현한다.
|
|
122
|
+
* 기본 동작: HTML 파싱 → insertSlice, 없으면 텍스트 삽입.
|
|
123
|
+
*/
|
|
124
|
+
insertFromPaste?(ctx: RangeCtx, data: PasteData): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* 파일 붙여넣기/드롭 — paste/drop DOM 이벤트에서 파일을 받는다
|
|
127
|
+
* (이미지 업로드 등). true면 소비 — 이벤트를 preventDefault한다.
|
|
128
|
+
* files는 필터링 전 원본 목록 — 기능이 자기 타입만 골라 쓴다.
|
|
129
|
+
*/
|
|
130
|
+
files?(ctx: FileDropCtx): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* 렌더 커밋/셀렉션 변경 후 DOM 오버레이 갱신 — 괄호 하이라이트·
|
|
133
|
+
* 활성 줄 표시 등. doc을 바꾸면 안 된다 (읽기 + DOM 마킹만).
|
|
134
|
+
*/
|
|
135
|
+
paintOverlay?(el: HTMLElement, state: EditorState): void;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 플러그인 — 트랜잭션 파이프라인 훅 + 전용 상태.
|
|
139
|
+
* PM plugin과 같은 역할이지만 뷰 계층(view/decorations)은 어댑터가
|
|
140
|
+
* 가지므로 코어 플러그인은 상태 쪽 책임만 가진다.
|
|
141
|
+
*/
|
|
142
|
+
export interface Plugin {
|
|
143
|
+
readonly key: string;
|
|
144
|
+
/** false 반환 시 해당 tr은 폐기된다 (읽기 전용/가드 용도) */
|
|
145
|
+
filterTransaction?(tr: Transaction, state: EditorState): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* tr 적용 직후 후속 트랜잭션 생성 — 반환한 tr이 이어서 디스패치된다.
|
|
148
|
+
* 순수 함수여야 하며 무한 후속 생성은 금지다.
|
|
149
|
+
*/
|
|
150
|
+
appendTransaction?(tr: Transaction, prevState: EditorState, state: EditorState): Transaction | null;
|
|
151
|
+
/** 플러그인 전용 상태 초기값 — pluginState[key]로 읽는다 */
|
|
152
|
+
init?(state: EditorState): unknown;
|
|
153
|
+
/** tr 적용 시 전용 상태 갱신 — 반환값이 새 pluginState[key] */
|
|
154
|
+
apply?(tr: Transaction, value: unknown, prevState: EditorState, state: EditorState): unknown;
|
|
155
|
+
}
|
|
156
|
+
/** 기능 번들 — 개발자가 주입하는 단위 */
|
|
157
|
+
export interface Extension {
|
|
158
|
+
readonly name: string;
|
|
159
|
+
/** 높을수록 먼저 적용 — 스키마/키맵 충돌 해소 (기본 100) */
|
|
160
|
+
readonly priority?: number;
|
|
161
|
+
readonly nodes?: Record<string, NodeSpec>;
|
|
162
|
+
readonly marks?: Record<string, MarkSpec>;
|
|
163
|
+
readonly commands?: Record<string, Command>;
|
|
164
|
+
readonly keymap?: Keymap;
|
|
165
|
+
readonly inputRules?: readonly InputRule[];
|
|
166
|
+
readonly plugins?: readonly Plugin[];
|
|
167
|
+
/** 뷰 입력 훅 — beforeinput 단계 인터셉터 + DOM 오버레이 */
|
|
168
|
+
readonly input?: InputHooks;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=extension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../../src/editor/extension.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../src/editor/extension.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ace — 코드 에디터식 캐럿 피드백 계층.
|
|
3
|
+
* DOM 셀렉션 앵커가 앉은 최상위 블록에 `me-line-active`를 달아
|
|
4
|
+
* Ace의 active-line 배경·거터 강조를 CSS가 그리고, 라인번호 거터·
|
|
5
|
+
* 코드 줄번호·언어 라벨은 .me-gutter 오버레이 DOM으로 그린다
|
|
6
|
+
* (편집 영역 안의 생성 콘텐츠는 Chrome 캐럿 경계를 깨뜨린다).
|
|
7
|
+
*/
|
|
8
|
+
export declare const aceFeature: import("./feature.js").Feature;
|
|
9
|
+
//# sourceMappingURL=ace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ace.d.ts","sourceRoot":"","sources":["../../src/features/ace.ts"],"names":[],"mappings":"AAsJA;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,gCAsCrB,CAAC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { defineFeature } from "./feature.js";
|
|
2
|
+
const gutterSig = new WeakMap();
|
|
3
|
+
const gutterTargets = new WeakMap();
|
|
4
|
+
/**
|
|
5
|
+
* 라인번호·언어 라벨 오버레이 — contenteditable "안"의 ::before/
|
|
6
|
+
* ::marker·절대위치 요소는 Chrome의 Home/End 줄 경계 계산을 깨뜨려
|
|
7
|
+
* 캐럿이 줄 끝으로 못 간다 (삭제·이동이 안 되는 것처럼 보이는 원인).
|
|
8
|
+
* 번호는 에디터 밖 .me-gutter 레이어에 실제 DOM으로 그려 이를 우회한다.
|
|
9
|
+
* 위치는 각 블록의 getBoundingClientRect로 맞추고, doc 참조가
|
|
10
|
+
* 바뀌거나 치수가 변할 때만 재계산한다.
|
|
11
|
+
*/
|
|
12
|
+
function syncGutter(el, state, activeBlock, activeLine) {
|
|
13
|
+
const root = el.parentElement;
|
|
14
|
+
if (!root)
|
|
15
|
+
return;
|
|
16
|
+
let gut = root.querySelector(":scope > .me-gutter");
|
|
17
|
+
if (!gut) {
|
|
18
|
+
gut = el.ownerDocument.createElement("div");
|
|
19
|
+
gut.className = "me-gutter";
|
|
20
|
+
gut.setAttribute("aria-hidden", "true");
|
|
21
|
+
root.appendChild(gut);
|
|
22
|
+
// 창 리사이즈·비동기 폰트 로드 등 doc과 무관한 리플로우도 재배치
|
|
23
|
+
new ResizeObserver(() => gutterSig.delete(el)).observe(el);
|
|
24
|
+
}
|
|
25
|
+
const cur = {
|
|
26
|
+
doc: state.doc,
|
|
27
|
+
h: el.scrollHeight,
|
|
28
|
+
top: el.offsetTop,
|
|
29
|
+
left: el.offsetLeft,
|
|
30
|
+
n: el.childElementCount,
|
|
31
|
+
st: el.scrollTop,
|
|
32
|
+
};
|
|
33
|
+
const sig = gutterSig.get(el);
|
|
34
|
+
const relayout = !sig ||
|
|
35
|
+
sig.doc !== cur.doc ||
|
|
36
|
+
sig.h !== cur.h ||
|
|
37
|
+
sig.top !== cur.top ||
|
|
38
|
+
sig.left !== cur.left ||
|
|
39
|
+
sig.n !== cur.n ||
|
|
40
|
+
sig.st !== cur.st;
|
|
41
|
+
if (relayout) {
|
|
42
|
+
gutterSig.set(el, cur);
|
|
43
|
+
const base = root.getBoundingClientRect();
|
|
44
|
+
const elR = el.getBoundingClientRect();
|
|
45
|
+
const targets = [];
|
|
46
|
+
let used = 0;
|
|
47
|
+
const emit = (cls, text, top, left, lh, target) => {
|
|
48
|
+
let d = gut.children[used];
|
|
49
|
+
if (!d) {
|
|
50
|
+
d = el.ownerDocument.createElement("div");
|
|
51
|
+
gut.appendChild(d);
|
|
52
|
+
}
|
|
53
|
+
d.className = cls;
|
|
54
|
+
if (d.textContent !== text)
|
|
55
|
+
d.textContent = text;
|
|
56
|
+
d.style.top = `${top}px`;
|
|
57
|
+
d.style.left = `${left}px`;
|
|
58
|
+
d.style.lineHeight = lh ?? "";
|
|
59
|
+
targets[used] = target;
|
|
60
|
+
used++;
|
|
61
|
+
};
|
|
62
|
+
const kids = Array.from(el.children);
|
|
63
|
+
for (let i = 0; i < kids.length; i++) {
|
|
64
|
+
const c = kids[i];
|
|
65
|
+
if (c.tagName === "PRE") {
|
|
66
|
+
const pr = c.getBoundingClientRect();
|
|
67
|
+
const lang = c.getAttribute("data-language");
|
|
68
|
+
if (lang) {
|
|
69
|
+
emit("me-glang", lang, pr.top - base.top + 4, pr.right - base.left - 8, null, null);
|
|
70
|
+
}
|
|
71
|
+
// 코드 줄 번호 — .me-cl 줄 래퍼마다 1씩 (기존 CSS 카운터 계약)
|
|
72
|
+
const lines = c.querySelectorAll(".me-cl");
|
|
73
|
+
for (let j = 0; j < lines.length; j++) {
|
|
74
|
+
const cl = lines[j];
|
|
75
|
+
const lr = cl.getBoundingClientRect();
|
|
76
|
+
emit("me-gnum me-gcode", String(j + 1), lr.top - base.top, pr.left - base.left, null, cl);
|
|
77
|
+
}
|
|
78
|
+
continue; // pre 자체에는 블록 번호를 찍지 않는다 (:not(pre) 계약)
|
|
79
|
+
}
|
|
80
|
+
const r = c.getBoundingClientRect();
|
|
81
|
+
// 번호를 블록 첫 줄 세로에 맞춘다 — 제목·리스트 높이 차이 흡수
|
|
82
|
+
const lh = el.ownerDocument.defaultView
|
|
83
|
+
?.getComputedStyle(c)
|
|
84
|
+
.lineHeight;
|
|
85
|
+
emit("me-gnum", String(i + 1), r.top - base.top, elR.left - base.left, lh && lh !== "normal" ? lh : null, c);
|
|
86
|
+
}
|
|
87
|
+
while (gut.children.length > used) {
|
|
88
|
+
gut.lastElementChild?.remove();
|
|
89
|
+
}
|
|
90
|
+
gutterTargets.set(gut, targets);
|
|
91
|
+
}
|
|
92
|
+
// 활성 번호 강조 — doc이 같아도 캐럿은 움직이므로 매 paint 갱신
|
|
93
|
+
const targets = gutterTargets.get(gut) ?? [];
|
|
94
|
+
for (let i = 0; i < gut.children.length; i++) {
|
|
95
|
+
const t = targets[i];
|
|
96
|
+
gut.children[i].classList.toggle("is-active", t != null && (t === activeBlock || t === activeLine));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Ace — 코드 에디터식 캐럿 피드백 계층.
|
|
101
|
+
* DOM 셀렉션 앵커가 앉은 최상위 블록에 `me-line-active`를 달아
|
|
102
|
+
* Ace의 active-line 배경·거터 강조를 CSS가 그리고, 라인번호 거터·
|
|
103
|
+
* 코드 줄번호·언어 라벨은 .me-gutter 오버레이 DOM으로 그린다
|
|
104
|
+
* (편집 영역 안의 생성 콘텐츠는 Chrome 캐럿 경계를 깨뜨린다).
|
|
105
|
+
*/
|
|
106
|
+
export const aceFeature = defineFeature({
|
|
107
|
+
name: "ace",
|
|
108
|
+
description: "Ace 스타일 — 활성 라인 하이라이트 + 거터·코드 줄번호 오버레이",
|
|
109
|
+
input: {
|
|
110
|
+
paintOverlay(el, state) {
|
|
111
|
+
const s = el.ownerDocument.getSelection?.();
|
|
112
|
+
const node = s?.anchorNode ?? null;
|
|
113
|
+
let active = null;
|
|
114
|
+
let activeLine = null;
|
|
115
|
+
if (node && node !== el && el.contains(node)) {
|
|
116
|
+
// 셀렉션 앵커에서 올라가 에디터의 직계 자식을 찾는다 — 직계
|
|
117
|
+
// 자식이 곧 최상위 doc 블록이다. 콜아웃 같은 노드 뷰는 래퍼가
|
|
118
|
+
// data-me-path를 갖지 않아도 직계 자식이므로 그대로 취한다
|
|
119
|
+
const near = node.nodeType === 1
|
|
120
|
+
? node
|
|
121
|
+
: node.parentElement;
|
|
122
|
+
let host = near;
|
|
123
|
+
while (host && host.parentElement !== el) {
|
|
124
|
+
host = host.parentElement;
|
|
125
|
+
}
|
|
126
|
+
active = host;
|
|
127
|
+
// 코드 줄 — 번호 강조 대상 (line 배경은 code-block이 칠한다)
|
|
128
|
+
activeLine = near?.closest(".me-cl") ?? null;
|
|
129
|
+
}
|
|
130
|
+
// 모든 DOM 변형을 selectionchange 디스패치 밖으로 — 사이클
|
|
131
|
+
// 안의 클래스/스타일 변경이 Chrome의 캐럿 줄 경계 캐시를 깨뜨려
|
|
132
|
+
// Home/End가 멈춘다. 마이크로태스크면 리스너 완료 뒤라 충분하다
|
|
133
|
+
queueMicrotask(() => {
|
|
134
|
+
for (const c of Array.from(el.children)) {
|
|
135
|
+
if (c !== active)
|
|
136
|
+
c.classList.remove("me-line-active");
|
|
137
|
+
}
|
|
138
|
+
active?.classList.add("me-line-active");
|
|
139
|
+
syncGutter(el, state, active, activeLine);
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=ace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ace.js","sourceRoot":"","sources":["../../src/features/ace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from "../editor/extension.js";
|
|
2
|
+
/**
|
|
3
|
+
* 블록 정렬 — align attr을 가진 블록(paragraph/heading 등)의
|
|
4
|
+
* 가로 정렬. align attr이 없는 블록 스펙이면 무동작이다.
|
|
5
|
+
*/
|
|
6
|
+
/** 정렬 — 캐럿 텍스트블록의 align attr (paragraph/heading 등) */
|
|
7
|
+
export declare function setAlign(align: "left" | "center" | "right"): Command;
|
|
8
|
+
export declare const alignmentFeature: import("./feature.js").Feature;
|
|
9
|
+
//# sourceMappingURL=alignment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alignment.d.ts","sourceRoot":"","sources":["../../src/features/alignment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAKtD;;;GAGG;AAEH,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAUpE;AAED,eAAO,MAAM,gBAAgB,gCAO3B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { nodeAt } from "../model/traverse.js";
|
|
2
|
+
import { defineFeature } from "./feature.js";
|
|
3
|
+
import { caretBlockPath } from "../commands.js";
|
|
4
|
+
/**
|
|
5
|
+
* 블록 정렬 — align attr을 가진 블록(paragraph/heading 등)의
|
|
6
|
+
* 가로 정렬. align attr이 없는 블록 스펙이면 무동작이다.
|
|
7
|
+
*/
|
|
8
|
+
/** 정렬 — 캐럿 텍스트블록의 align attr (paragraph/heading 등) */
|
|
9
|
+
export function setAlign(align) {
|
|
10
|
+
return ({ state, tr, dispatch }) => {
|
|
11
|
+
const blockPath = caretBlockPath(state);
|
|
12
|
+
const block = blockPath ? nodeAt(state.doc, blockPath) : undefined;
|
|
13
|
+
const spec = block && state.schema.nodeSpec(block.type);
|
|
14
|
+
if (!blockPath || !block || !spec?.attrs?.["align"])
|
|
15
|
+
return false;
|
|
16
|
+
tr.setNodeAttr(blockPath, "align", align);
|
|
17
|
+
dispatch();
|
|
18
|
+
return true;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export const alignmentFeature = defineFeature({
|
|
22
|
+
name: "align",
|
|
23
|
+
description: "블록 정렬 — align attr 기반 좌/중/우 정렬 (setAlign)",
|
|
24
|
+
commands: {
|
|
25
|
+
setAlign: (ctx, align) => setAlign(align)(ctx),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=alignment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alignment.js","sourceRoot":"","sources":["../../src/features/alignment.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;GAGG;AAEH,sDAAsD;AACtD,MAAM,UAAU,QAAQ,CAAC,KAAkC;IACzD,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACjC,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QAClE,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,QAAQ,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;IAC5C,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,2CAA2C;IACxD,QAAQ,EAAE;QACR,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CACvB,QAAQ,CAAC,KAAoC,CAAC,CAAC,GAAG,CAAC;KACtD;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Command } from "../editor/extension.js";
|
|
2
|
+
/**
|
|
3
|
+
* 인용구 — blockquote 컨테이너와 `> ` 입력 규칙.
|
|
4
|
+
* 안이면 인용구를 풀고, 밖이면 현재 블록을 감싼다.
|
|
5
|
+
*/
|
|
6
|
+
/** 인용구 토글 — 안이면 인용구를 풀고, 밖이면 현재 블록을 감싼다 */
|
|
7
|
+
export declare const toggleQuote: Command;
|
|
8
|
+
export declare const blockquoteFeature: import("./feature.js").Feature;
|
|
9
|
+
//# sourceMappingURL=blockquote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockquote.d.ts","sourceRoot":"","sources":["../../src/features/blockquote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAMtD;;;GAGG;AAEH,2CAA2C;AAC3C,eAAO,MAAM,WAAW,EAAE,OA6BzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,gCAyB5B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { nodeAt } from "../model/traverse.js";
|
|
2
|
+
import { textSelection } from "../state/selection.js";
|
|
3
|
+
import { defineFeature } from "./feature.js";
|
|
4
|
+
import { caretBlockPath, wrapBlock } from "../commands.js";
|
|
5
|
+
/**
|
|
6
|
+
* 인용구 — blockquote 컨테이너와 `> ` 입력 규칙.
|
|
7
|
+
* 안이면 인용구를 풀고, 밖이면 현재 블록을 감싼다.
|
|
8
|
+
*/
|
|
9
|
+
/** 인용구 토글 — 안이면 인용구를 풀고, 밖이면 현재 블록을 감싼다 */
|
|
10
|
+
export const toggleQuote = ({ state, tr, dispatch }) => {
|
|
11
|
+
const sel = state.selection;
|
|
12
|
+
const blockPath = caretBlockPath(state);
|
|
13
|
+
if (!blockPath || sel.type !== "text")
|
|
14
|
+
return false;
|
|
15
|
+
const parentPath = blockPath.slice(0, -1);
|
|
16
|
+
const parent = parentPath.length ? nodeAt(state.doc, parentPath) : undefined;
|
|
17
|
+
if (parent?.type === "blockquote") {
|
|
18
|
+
// 인용구 첫 블록을 인용구 자리로 옮긴다 (v1 — 단일 블록 인용구 관례)
|
|
19
|
+
const first = parent.content?.[0];
|
|
20
|
+
if (!first)
|
|
21
|
+
return false;
|
|
22
|
+
tr.replaceNode(parentPath, first);
|
|
23
|
+
dispatch();
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
const block = nodeAt(state.doc, blockPath);
|
|
27
|
+
if (!block || block.type === "blockquote")
|
|
28
|
+
return false;
|
|
29
|
+
tr.replaceNode(blockPath, { type: "blockquote", content: [block] });
|
|
30
|
+
const tIdx = nodeAt(state.doc, sel.anchor.path)?.type === "text"
|
|
31
|
+
? sel.anchor.path[sel.anchor.path.length - 1]
|
|
32
|
+
: 0;
|
|
33
|
+
tr.setSelection(textSelection({
|
|
34
|
+
path: [...blockPath, 0, tIdx],
|
|
35
|
+
offset: sel.anchor.offset,
|
|
36
|
+
}));
|
|
37
|
+
dispatch();
|
|
38
|
+
return true;
|
|
39
|
+
};
|
|
40
|
+
export const blockquoteFeature = defineFeature({
|
|
41
|
+
name: "blockquote",
|
|
42
|
+
description: "인용구 — `> ` 입력 규칙, toggleQuote 커맨드",
|
|
43
|
+
nodes: {
|
|
44
|
+
blockquote: {
|
|
45
|
+
content: "block+",
|
|
46
|
+
group: "block",
|
|
47
|
+
toDOM: () => ({ tag: "blockquote" }),
|
|
48
|
+
parseDOM: [{ tag: "blockquote" }],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
commands: {
|
|
52
|
+
toggleQuote,
|
|
53
|
+
},
|
|
54
|
+
inputRules: [
|
|
55
|
+
// 인용구 — `> ` (표준 마크다운)
|
|
56
|
+
{
|
|
57
|
+
pattern: /^> $/,
|
|
58
|
+
handler: ({ tr }, _m, range, doc) => wrapBlock(tr, range, doc, () => ({
|
|
59
|
+
type: "blockquote",
|
|
60
|
+
content: [],
|
|
61
|
+
})),
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
});
|
|
65
|
+
//# sourceMappingURL=blockquote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blockquote.js","sourceRoot":"","sources":["../../src/features/blockquote.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Command } from "../editor/extension.js";
|
|
2
|
+
import type { EditorNode } from "../model/node.js";
|
|
3
|
+
import type { EditorState } from "../state/state.js";
|
|
4
|
+
/**
|
|
5
|
+
* 코드블록 — ` ``` ` 입력 규칙, 구문 하이라이트, Ace/VS Code 관례의
|
|
6
|
+
* 코드 편집 명령(들여쓰기·주석 토글·줄 이동/복제·괄호 매칭·화살표
|
|
7
|
+
* 탈출). 코드 텍스트는 마크 없는 순수 텍스트다.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 코드블록 토글 — 안이면 본문으로, 밖이면 선택을 코드블록으로.
|
|
11
|
+
* 선택이 여러 최상위 텍스트블록을 걸치면 전부 하나의 코드블록으로
|
|
12
|
+
* 합친다 — 블록 사이는 \n으로 잇는다(코드블록은 줄바꿈을 텍스트에
|
|
13
|
+
* 내장). 마크는 벗긴다 (코드는 항상 순수 텍스트).
|
|
14
|
+
*/
|
|
15
|
+
export declare const toggleCodeBlock: Command;
|
|
16
|
+
/** 캐럿 코드블록의 language attr 설정 — data-language 라벨로 렌더 */
|
|
17
|
+
export declare function setCodeLanguage(language: string): Command;
|
|
18
|
+
/**
|
|
19
|
+
* 문자열/주석 토큰 안의 문자 오프셋 판정 — spec.codeHighlighter로
|
|
20
|
+
* 토큰화해 그 구간에 있으면 true를 돌린다 (Ace가 페어링·매칭을
|
|
21
|
+
* 끌 때 쓰는 isCodeLike 관례). 하이라이터가 없으면 null.
|
|
22
|
+
*/
|
|
23
|
+
export declare function codeStringMask(state: EditorState, block: EditorNode): ((off: number) => boolean) | null;
|
|
24
|
+
/**
|
|
25
|
+
* Tab — 코드블록 들여쓰기. collapsed면 캐럿에 \t 삽입,
|
|
26
|
+
* 범위 선택이면 걸친 줄 전부의 앞에 \t를 단다 (VS Code 관례).
|
|
27
|
+
* 코드블록 밖이면 false — 리스트/표 키바인딩으로 폴스루.
|
|
28
|
+
*/
|
|
29
|
+
export declare const indentCode: Command;
|
|
30
|
+
/**
|
|
31
|
+
* Shift-Tab — 코드블록 내어쓰기. 걸친 각 줄의 앞에서 \t 하나 또는
|
|
32
|
+
* 스페이스 최대 tabSize개를 지운다. 코드블록 밖이면 false로 폴스루.
|
|
33
|
+
*/
|
|
34
|
+
export declare const dedentCode: Command;
|
|
35
|
+
/**
|
|
36
|
+
* ArrowDown/ArrowUp — 코드블록 가장자리 줄 탈출 (Tiptap
|
|
37
|
+
* exitOnArrowDown/Up 관례). 마지막 줄에서 ArrowDown을 누르면 블록
|
|
38
|
+
* 뒤로, 첫 줄에서 ArrowUp이면 블록 앞으로 나간다 — 이웃 블록이
|
|
39
|
+
* 없으면 빈 문단을 만든다. Notion의 코드블록 화살표 탈출과 같다.
|
|
40
|
+
*/
|
|
41
|
+
export declare function exitCodeArrow(direction: "up" | "down"): Command;
|
|
42
|
+
/** 캐럿 코드블록의 텍스트 — 복사 버튼 등 UI용. 밖이면 null */
|
|
43
|
+
export declare function codeTextAt(state: EditorState): string | null;
|
|
44
|
+
/** 코드블록 안 캐럿의 줄/열 (Ace 상태바 Ln:Col 관례). 밖이면 null */
|
|
45
|
+
export declare function codeCaret(state: EditorState): {
|
|
46
|
+
line: number;
|
|
47
|
+
col: number;
|
|
48
|
+
} | null;
|
|
49
|
+
/**
|
|
50
|
+
* Mod-/ — 코드블록 줄 주석 토글 (Ace toggleCommentLines 관례).
|
|
51
|
+
* 걸친 줄이 전부 주석이면 해제, 아니면 주석을 단다 — 마커는
|
|
52
|
+
* 선행 공백 뒤에 붙어 들여쓰기가 보존된다 (VS Code 관례).
|
|
53
|
+
* 블록 주석 언어(css/html 등)는 줄마다 블록 마커로 감싼다.
|
|
54
|
+
*/
|
|
55
|
+
export declare const toggleCodeComment: Command;
|
|
56
|
+
/**
|
|
57
|
+
* Alt-↑/↓ — 선택이 걸친 줄들을 위/아래 한 줄 이동 (Ace movelines·
|
|
58
|
+
* VS Code 관례). 첫/마지막 줄 가장자리에선 false로 폴스루한다.
|
|
59
|
+
*/
|
|
60
|
+
export declare function moveCodeLines(direction: "up" | "down"): Command;
|
|
61
|
+
/**
|
|
62
|
+
* Mod-Shift-D — 선택이 걸친 줄들을 바로 아래에 복제
|
|
63
|
+
* (Ace duplicateSelection 관례). 사본이 선택된다.
|
|
64
|
+
*/
|
|
65
|
+
export declare const duplicateCodeLines: Command;
|
|
66
|
+
/**
|
|
67
|
+
* 캐럿 인접 괄호와 짝의 문자 오프셋 (Ace bracket matching 관례).
|
|
68
|
+
* 캐럿 앞/뒤의 ()[]{}를 보고 같은 종류만 세는 깊이 스캔으로 짝을
|
|
69
|
+
* 찾는다 — 문자열/주석 토큰 안쪽의 괄호는 코드로 세지 않는다.
|
|
70
|
+
* 없으면 null.
|
|
71
|
+
*/
|
|
72
|
+
export declare function codeBracketAt(state: EditorState): {
|
|
73
|
+
a: number;
|
|
74
|
+
b: number;
|
|
75
|
+
} | null;
|
|
76
|
+
export declare const codeBlockFeature: import("./feature.js").Feature;
|
|
77
|
+
//# sourceMappingURL=code-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../src/features/code-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAUnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYrD;;;;GAIG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,OA6C7B,CAAC;AAEF,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASzD;AA6HD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,UAAU,GAChB,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,CAwBnC;AAgBD;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,OAyCxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,OA0CxB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAkC/D;AAED,2CAA2C;AAC3C,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CACvB,KAAK,EAAE,WAAW,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMtC;AAqFD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,OAiH/B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAyD/D;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAsBhC,CAAC;AASF;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,GACjB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAwCjC;AAmBD,eAAO,MAAM,gBAAgB,gCA8S3B,CAAC"}
|