@aeriz/wysiwyg 1.0.3 → 1.0.4
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/README.md +37 -13
- package/dist/adapters/shared.cjs +1 -1
- package/dist/adapters/shared.js +11 -11
- package/dist/aeriz-wysiwyg-adapter.js +1 -1
- package/dist/aeriz-wysiwyg-adapter.min.js +1 -1
- package/dist/aeriz-wysiwyg-jquery.js +1 -1
- package/dist/aeriz-wysiwyg-jquery.min.js +1 -1
- package/dist/aeriz-wysiwyg-wc.js +1 -1
- package/dist/aeriz-wysiwyg-wc.min.js +1 -1
- package/dist/aeriz-wysiwyg.cjs +3773 -1926
- package/dist/aeriz-wysiwyg.css +554 -38
- package/dist/aeriz-wysiwyg.esm.js +3773 -1926
- package/dist/aeriz-wysiwyg.esm.min.js +4271 -2658
- package/dist/aeriz-wysiwyg.js +3773 -1926
- package/dist/aeriz-wysiwyg.min.cjs +36 -34
- package/dist/aeriz-wysiwyg.min.css +1 -1
- package/dist/aeriz-wysiwyg.min.js +40 -38
- package/dist/server.cjs +24 -22
- package/dist/server.js +444 -312
- package/dist-types/adapters/shared.d.ts.map +1 -1
- package/dist-types/cjs/core/AerizEditor.d.cts +180 -7
- package/dist-types/cjs/core/block-meta.d.cts +66 -0
- package/dist-types/cjs/core/block-policy.d.cts +43 -0
- package/dist-types/cjs/core/blocks.d.cts +47 -4
- package/dist-types/cjs/core/history.d.cts +86 -0
- package/dist-types/cjs/core/i18n.d.cts +12 -0
- package/dist-types/cjs/core/import-html.d.cts +1 -0
- package/dist-types/cjs/core/import-markdown.d.cts +0 -4
- package/dist-types/cjs/core/input-rules.d.cts +46 -0
- package/dist-types/cjs/core/selection.d.cts +46 -0
- package/dist-types/cjs/core/table-ops.d.cts +30 -0
- package/dist-types/cjs/index.d.cts +2 -0
- package/dist-types/core/AerizEditor.d.ts +180 -7
- package/dist-types/core/AerizEditor.d.ts.map +1 -1
- package/dist-types/core/block-meta.d.ts +66 -0
- package/dist-types/core/block-meta.d.ts.map +1 -1
- package/dist-types/core/block-policy.d.ts +43 -0
- package/dist-types/core/block-policy.d.ts.map +1 -0
- package/dist-types/core/blocks.d.ts +47 -4
- package/dist-types/core/blocks.d.ts.map +1 -1
- package/dist-types/core/history.d.ts +86 -0
- package/dist-types/core/history.d.ts.map +1 -0
- package/dist-types/core/i18n.d.ts +12 -0
- package/dist-types/core/i18n.d.ts.map +1 -1
- package/dist-types/core/import-html.d.ts +1 -0
- package/dist-types/core/import-html.d.ts.map +1 -1
- package/dist-types/core/import-markdown.d.ts +0 -4
- package/dist-types/core/import-markdown.d.ts.map +1 -1
- package/dist-types/core/input-rules.d.ts +46 -0
- package/dist-types/core/input-rules.d.ts.map +1 -0
- package/dist-types/core/plain-text.d.ts.map +1 -1
- package/dist-types/core/render-string.d.ts.map +1 -1
- package/dist-types/core/selection.d.ts +46 -0
- package/dist-types/core/selection.d.ts.map +1 -0
- package/dist-types/core/snapshot.d.ts.map +1 -1
- package/dist-types/core/table-ops.d.ts +30 -0
- package/dist-types/core/table-ops.d.ts.map +1 -0
- package/dist-types/index.d.ts +2 -0
- package/dist-types/index.d.ts.map +1 -1
- package/dist-types/ui/Toolbar.d.ts.map +1 -1
- package/dist-types/ui/dialogs.d.ts.map +1 -1
- package/dist-types/ui/icons.d.ts.map +1 -1
- package/dist-types/ui/popovers.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 키보드와 타이핑을 블록 유형으로 옮기는 표.
|
|
3
|
+
*
|
|
4
|
+
* 블록 유형을 고르는 길은 둘이다 — 메뉴에서 고르거나, 쓰던 흐름 그대로
|
|
5
|
+
* 신호를 주거나. 후자가 여기다. 두 갈래를 한 파일에 두는 이유는 둘이 같은
|
|
6
|
+
* 목적지(BlockKind) 를 가리키기 때문이고, 한쪽만 고치면 곧바로 어긋난다.
|
|
7
|
+
*
|
|
8
|
+
* 문법은 마크다운 가져오기(`import-markdown.ts`) 와 같은 것을 쓴다. 한쪽에서
|
|
9
|
+
* 되는 표기가 다른 쪽에서 안 되면 사용자가 규칙을 두 벌 외워야 한다.
|
|
10
|
+
*/
|
|
11
|
+
import type { BlockAttrs, BlockKind } from './blocks.cjs';
|
|
12
|
+
/** 블록 유형을 가리키는 목적지. */
|
|
13
|
+
export interface BlockTarget {
|
|
14
|
+
kind: BlockKind;
|
|
15
|
+
attrs?: BlockAttrs;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* `Ctrl/Cmd + Alt + 키` → 바꿀 블록 유형.
|
|
19
|
+
*
|
|
20
|
+
* 숫자는 제목 레벨과 그대로 맞춘다(1 → 제목 1). 0 이 본문인 것도 같은 이유다
|
|
21
|
+
* — "제목 아님" 자리다. 목록·인용구는 툴바 툴팁이 예전부터 광고해 온 7/8/9
|
|
22
|
+
* 자리를 그대로 쓴다.
|
|
23
|
+
*
|
|
24
|
+
* `Ctrl + 숫자` 가 아니라 `Ctrl + Alt + 숫자` 인 이유는 브라우저의 탭 전환
|
|
25
|
+
* 단축키와 겹치지 않기 위해서다.
|
|
26
|
+
*/
|
|
27
|
+
export declare const BLOCK_SHORTCUTS: Readonly<Record<string, BlockTarget>>;
|
|
28
|
+
/**
|
|
29
|
+
* 블록 첫 글자들이 마크다운 방아쇠인지 본다. 아니면 null.
|
|
30
|
+
*
|
|
31
|
+
* 방아쇠는 **본문 블록의 맨 앞**에서만 인식한다 (호출자 책임). 이미 쓴 문단
|
|
32
|
+
* 중간에서 "- " 를 고치다가 블록이 통째로 바뀌면 사고다.
|
|
33
|
+
*/
|
|
34
|
+
export declare function matchInputRule(text: string): BlockTarget | null;
|
|
35
|
+
/**
|
|
36
|
+
* 목록 **항목 안**에서 체크박스 표기를 알아본다. 완료 여부를 함께 돌려준다.
|
|
37
|
+
*
|
|
38
|
+
* `- [ ] ` 를 통째로 방아쇠로 삼을 수는 없다 — 앞의 `- ` 에서 이미 글머리
|
|
39
|
+
* 목록으로 바뀌기 때문에 뒤 절반은 영영 도달하지 않는다. 그래서 "글머리
|
|
40
|
+
* 목록 항목 맨 앞의 `[ ] `" 를 따로 본다. 사용자가 치는 순서(`- ` → `[ ] `)
|
|
41
|
+
* 를 그대로 따라가는 셈이고, 결과도 기대한 것과 같다.
|
|
42
|
+
*/
|
|
43
|
+
export declare function matchTaskItemRule(text: string): {
|
|
44
|
+
checked: boolean;
|
|
45
|
+
} | null;
|
|
46
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** 문자 오프셋으로 표현한 선택 영역. */
|
|
2
|
+
export interface SelectionOffsets {
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `<code>` element 안의 셀렉션을 텍스트 오프셋으로 저장한다.
|
|
8
|
+
* 하이라이트가 innerHTML 을 다시 쓰기 직전에 부른다.
|
|
9
|
+
*/
|
|
10
|
+
export declare function saveCodeSelection(codeEl: HTMLElement): SelectionOffsets | null;
|
|
11
|
+
/** {@link saveCodeSelection} 로 저장한 위치에 캐럿을 되돌린다. */
|
|
12
|
+
export declare function restoreCodeSelection(codeEl: HTMLElement, saved: SelectionOffsets): void;
|
|
13
|
+
/**
|
|
14
|
+
* `root` 안의 현재 셀렉션을 문자 오프셋으로 캡처한다.
|
|
15
|
+
* 셀렉션이 `root` 밖이면 null.
|
|
16
|
+
*/
|
|
17
|
+
export declare function captureSelectionOffsets(root: HTMLElement): SelectionOffsets | null;
|
|
18
|
+
/**
|
|
19
|
+
* 문자 오프셋으로 저장해 둔 셀렉션을 되살린다.
|
|
20
|
+
* 문서가 짧아져 오프셋이 넘치면 가장 가까운 위치(문서 끝) 에 둔다.
|
|
21
|
+
*/
|
|
22
|
+
export declare function restoreSelectionOffsets(root: HTMLElement, saved: SelectionOffsets): void;
|
|
23
|
+
/**
|
|
24
|
+
* 캐럿이 블록의 맨 끝에 있는지.
|
|
25
|
+
*
|
|
26
|
+
* 캐럿 뒤에 남은 **글자**가 없으면 끝으로 본다. 빈 단락의 `<br>` 이나 캐럿
|
|
27
|
+
* 고정용 zero-width 문자는 글자로 치지 않는다 — 사용자 눈에는 아무것도 없는
|
|
28
|
+
* 자리이기 때문이다.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isCaretAtBlockEnd(blockEl: HTMLElement): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 블록 시작부터 캐럿까지의 **보이는 글자**.
|
|
33
|
+
*
|
|
34
|
+
* 마크다운 입력 규칙이 방아쇠(`# ` 등) 를 알아보는 근거다. 노드 구조로
|
|
35
|
+
* 판정하지 않는 이유 — 빈 단락에는 placeholder `<br>` 이 남아 있고 첫 입력의
|
|
36
|
+
* 노드 배치가 브라우저마다 달라서, "첫 텍스트 노드" 같은 조건은 실제
|
|
37
|
+
* 브라우저에서 조용히 빗나간다.
|
|
38
|
+
*
|
|
39
|
+
* 판정에 쓴 Range 를 함께 돌려준다 — 방아쇠를 지우려면 정확히 그 범위가
|
|
40
|
+
* 필요하고, 다시 계산하면 그 사이 캐럿이 움직였을 때 엉뚱한 곳을 지운다.
|
|
41
|
+
*/
|
|
42
|
+
export declare function textBeforeCaret(blockEl: HTMLElement): {
|
|
43
|
+
text: string;
|
|
44
|
+
range: Range;
|
|
45
|
+
} | null;
|
|
46
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 표 셀의 기하와 이동.
|
|
3
|
+
*
|
|
4
|
+
* 표 편집은 "지금 어느 셀인가" 를 계속 되묻는 일이다 — 캐럿이 놓인 셀, 드래그
|
|
5
|
+
* 로 걸친 셀 범위, 마우스가 가장자리에 닿았는지, Tab 을 눌렀을 때 다음 셀.
|
|
6
|
+
* 그 판정들만 여기 모은다. 에디터 인스턴스 상태를 보지 않는 순수 계산이라
|
|
7
|
+
* 따로 두면 표 동작을 고칠 때 에디터 본체를 읽지 않아도 된다.
|
|
8
|
+
*
|
|
9
|
+
* **rowspan / colspan 은 고려하지 않는다.** 이 에디터는 둘 다 만들지 않으며,
|
|
10
|
+
* 병합 셀을 지원하게 되면 여기 있는 인덱스 계산은 전부 다시 짜야 한다.
|
|
11
|
+
*/
|
|
12
|
+
/** 임의의 노드에서 가장 가까운 td/th element. 없으면 null. */
|
|
13
|
+
export declare function nearestCell(node: Node): HTMLTableCellElement | null;
|
|
14
|
+
/**
|
|
15
|
+
* 다음 표 셀. 행 끝이면 다음 행의 첫 셀, 표의 마지막 셀이면 **새 행을 만들어**
|
|
16
|
+
* 그 첫 셀을 돌려준다 — Tab 만으로 표를 끝까지 채울 수 있도록.
|
|
17
|
+
*/
|
|
18
|
+
export declare function nextTableCell(cell: HTMLTableCellElement, table: HTMLTableElement): HTMLTableCellElement | null;
|
|
19
|
+
/** 이전 표 셀. 첫 셀이면 null. */
|
|
20
|
+
export declare function previousTableCell(cell: HTMLTableCellElement): HTMLTableCellElement | null;
|
|
21
|
+
/**
|
|
22
|
+
* `startCell` 과 `endCell` 을 모서리로 하는 사각 영역의 모든 td/th.
|
|
23
|
+
*
|
|
24
|
+
* thead 와 tbody 가 섞여 있어도 `querySelectorAll('tr')` 의 document order 로
|
|
25
|
+
* 단일 행 인덱스를 매긴다 — 사용자 눈에 보이는 순서와 같다.
|
|
26
|
+
*/
|
|
27
|
+
export declare function cellsInRectangle(table: HTMLTableElement, startCell: HTMLTableCellElement, endCell: HTMLTableCellElement): HTMLTableCellElement[];
|
|
28
|
+
/** 셀의 우/하 가장자리에 포인터가 있으면 'right' / 'bottom'. 아니면 null. */
|
|
29
|
+
export declare function detectCellEdge(cell: HTMLTableCellElement, x: number, y: number): 'right' | 'bottom' | null;
|
|
30
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -6,6 +6,8 @@ export type { ViewerOptions } from './core/AerizViewer.cjs';
|
|
|
6
6
|
export { ALIGN_CLASS_BY_VALUE, ALL_INLINE_MARKS, BLOCK_ID_ATTR, BLOCK_TYPES, BLOCK_TYPE_BY_KIND, BlockIdRegistry, applyBlockClassNames, applyBlockInlineStyles, assignMissingIds, classifyBlockElement, extractInlineContent, fillInlineContent, findBlockFrom, getBlockLabel, isElementBlank, listBlocks, normalizeContent, placeCaretAtStart, readBlockStyleTheme, renderBlock, renderBlocks, serializeBlock, serializeBlocks, restoreAlignFromClasses, stripEditorOnlyAttrs, stripEditorOnlyNodes, } from './core/blocks.cjs';
|
|
7
7
|
export type { BlockStyleTheme } from './core/blocks.cjs';
|
|
8
8
|
export type { Block, BlockAttrs, BlockAttrsByKind, BlockIdResolver, BlockKind, BlockMatch, BlockSnapshot, BlockType, BlockquoteAttrs, BulletListAttrs, ClassifyResult, CodeBlockAttrs, FileAttrs, HeadingAttrs, HeadingLevel, HrAttrs, ImageAttrs, ImportedHtmlAttrs, InlineMarkName, LinkCardAttrs, OrderedListAttrs, ParagraphAttrs, Snapshot, TableAttrs, UnknownAttrs, YoutubeAttrs, } from './core/blocks.cjs';
|
|
9
|
+
export { getLocale, setLocale, t } from './core/i18n.cjs';
|
|
10
|
+
export type { Locale, Strings } from './core/i18n.cjs';
|
|
9
11
|
export type { EditorOptions, HtmlStyleMode, SerializeHtmlOptions, ToolbarConfig, ToolbarItem, ToolbarItemName, } from './types/index.cjs';
|
|
10
12
|
export { DEFAULT_TOOLBAR } from './types/index.cjs';
|
|
11
13
|
export { SNAPSHOT_VERSION, snapshotVersionOf, upgradeSnapshot, upgradeSnapshots, } from './core/snapshot.cjs';
|
|
@@ -23,7 +23,11 @@ export declare class AerizEditor {
|
|
|
23
23
|
private readonly dropIndicator;
|
|
24
24
|
private readonly handles;
|
|
25
25
|
private readonly blockLabelPill;
|
|
26
|
+
private readonly pillGlyphEl;
|
|
27
|
+
private readonly pillTextEl;
|
|
26
28
|
private readonly statusBar;
|
|
29
|
+
private readonly undoBtn;
|
|
30
|
+
private readonly redoBtn;
|
|
27
31
|
private readonly statusBlockEl;
|
|
28
32
|
private readonly statusBlocksEl;
|
|
29
33
|
private readonly statusCharsEl;
|
|
@@ -35,10 +39,33 @@ export declare class AerizEditor {
|
|
|
35
39
|
private readonly listeners;
|
|
36
40
|
private readonly handleSelectionChange;
|
|
37
41
|
private readonly handleResize;
|
|
42
|
+
/** document 에 붙는다 — destroy() 에서 반드시 떼야 인스턴스가 GC 된다. */
|
|
43
|
+
private readonly handleDocumentMouseUp;
|
|
38
44
|
private state;
|
|
39
45
|
private destroyed;
|
|
40
46
|
private syncQueued;
|
|
41
47
|
private lastSerialized;
|
|
48
|
+
/** 포인터가 올라가 있는 블록. 그 블록의 컨트롤만 드러낸다. */
|
|
49
|
+
private hoveredBlockId;
|
|
50
|
+
/** hover 판정을 프레임당 1 회로 묶기 위한 rAF 핸들. */
|
|
51
|
+
private hoverRaf;
|
|
52
|
+
/** 라벨 pill 의 등장 애니메이션을 블록이 **바뀔 때만** 다시 재생하기 위한 표식. */
|
|
53
|
+
private pillBlockId;
|
|
54
|
+
/**
|
|
55
|
+
* 편집 이력. 브라우저 기본 undo 는 우리가 직접 한 DOM 조작(블록 이동 · 표
|
|
56
|
+
* 편집 · 유형 변경) 을 모르기 때문에 자체 스택을 둔다.
|
|
57
|
+
*/
|
|
58
|
+
private history;
|
|
59
|
+
/**
|
|
60
|
+
* 이력 되돌리기가 만든 DOM 변경인지. 이 동안의 변경은 다시 기록하지 않는다
|
|
61
|
+
* (되돌리기가 스스로를 이력에 쌓으면 되돌리기를 되돌릴 수 없다).
|
|
62
|
+
*/
|
|
63
|
+
private applyingHistory;
|
|
64
|
+
/**
|
|
65
|
+
* 다음 기록의 성격. 구조를 바꾸는 조작은 타이핑과 합쳐지지 않도록
|
|
66
|
+
* 조작 직전에 이 값을 올려 둔다.
|
|
67
|
+
*/
|
|
68
|
+
private pendingChangeKind;
|
|
42
69
|
/** 사용자가 색 다이얼로그에서 직접 고른 색상의 LRU. 에디터 인스턴스 메모리에만 유지. */
|
|
43
70
|
private recentCustomColors;
|
|
44
71
|
constructor(options: EditorOptions);
|
|
@@ -96,7 +123,48 @@ export declare class AerizEditor {
|
|
|
96
123
|
* takeRecords 로 흡수한 뒤 onChange + queueSync.
|
|
97
124
|
*/
|
|
98
125
|
private flush;
|
|
126
|
+
/**
|
|
127
|
+
* 지금 본문을 이력에 기록한다.
|
|
128
|
+
*
|
|
129
|
+
* 되돌리기가 만든 변경은 기록하지 않는다 — 자기 자신을 이력에 쌓으면
|
|
130
|
+
* 되돌리기를 되돌릴 수 없다.
|
|
131
|
+
*/
|
|
132
|
+
private recordHistory;
|
|
133
|
+
/**
|
|
134
|
+
* 유형이 막 바뀐 블록을 한 번 반짝인다.
|
|
135
|
+
*
|
|
136
|
+
* 유형 변경은 결과가 화면 아래쪽(들여쓰기 · 글꼴 · 배경) 에서 조용히 일어나
|
|
137
|
+
* "눌리긴 한 건가" 싶을 때가 있다. 짧은 하이라이트 하나로 어느 블록이
|
|
138
|
+
* 바뀌었는지가 분명해진다.
|
|
139
|
+
*
|
|
140
|
+
* 표식은 `data-block-flash` 속성이다 — class 로 걸면 사용자 컨텐츠의 class 에
|
|
141
|
+
* 섞여 `getHTML()` 로 새어 나갈 수 있다. data-block-* 는 출력 단계에서
|
|
142
|
+
* 통째로 제거되는 에디터 전용 네임스페이스다.
|
|
143
|
+
*
|
|
144
|
+
* 속성을 넣고 뺄 때마다 옵저버 레코드를 흡수한다. 이걸 빠뜨리면 이 표식
|
|
145
|
+
* 하나가 "문서가 바뀌었다" 로 잡혀 이력에 항목이 하나 더 쌓이고, 되돌리기가
|
|
146
|
+
* 눈에 보이는 변화 없이 한 번 헛돈다 (실제로 그랬다).
|
|
147
|
+
*/
|
|
148
|
+
private flashBlock;
|
|
149
|
+
/**
|
|
150
|
+
* 이어지는 한 번의 변경을 **구조 변경**으로 표시한다.
|
|
151
|
+
*
|
|
152
|
+
* 블록 이동 · 유형 변경 · 표 편집처럼 사용자가 "한 번에 하나씩" 되돌리길
|
|
153
|
+
* 기대하는 조작 직전에 부른다. 이 표시가 없으면 직전 타이핑과 한 항목으로
|
|
154
|
+
* 합쳐져 Ctrl+Z 한 번에 둘 다 사라진다.
|
|
155
|
+
*/
|
|
156
|
+
private markStructuralChange;
|
|
157
|
+
/** 되돌리기. 되돌릴 것이 없으면 아무 일도 하지 않는다. */
|
|
158
|
+
undo(): void;
|
|
159
|
+
/** 다시 실행. */
|
|
160
|
+
redo(): void;
|
|
161
|
+
private applyHistoryEntry;
|
|
99
162
|
private handleToolbarAction;
|
|
163
|
+
/**
|
|
164
|
+
* 선택 영역의 인라인 서식을 지운다. 블록 유형은 건드리지 않는다 —
|
|
165
|
+
* "서식 지우기" 로 제목이 본문이 되면 되돌릴 방법을 찾기 어렵다.
|
|
166
|
+
*/
|
|
167
|
+
private clearInlineFormat;
|
|
100
168
|
/**
|
|
101
169
|
* 인라인 마크(bold/italic/underline/strike) 토글. 활성 블록의 allowedMarks
|
|
102
170
|
* 에 포함되지 않은 마크면 무시. styleWithCSS=true 모드로 deprecated 태그
|
|
@@ -201,6 +269,25 @@ export declare class AerizEditor {
|
|
|
201
269
|
*/
|
|
202
270
|
private handleTableResizeStart;
|
|
203
271
|
private handleTableResizeMove;
|
|
272
|
+
/**
|
|
273
|
+
* 체크리스트 항목의 체크 표시 토글.
|
|
274
|
+
*
|
|
275
|
+
* 체크박스는 실제 element 가 아니라 `<li>` 의 `::before` 다 — 폼 요소를
|
|
276
|
+
* contentEditable 안에 두면 캐럿이 그 안으로 들어가고 서버 sanitizer 가
|
|
277
|
+
* 지워 버린다. 그래서 클릭 좌표가 그 표시 영역 안인지 직접 따진다.
|
|
278
|
+
*
|
|
279
|
+
* `click` 이 아니라 `mousedown` 에서 처리한다 — click 까지 기다리면 그
|
|
280
|
+
* 사이에 캐럿이 항목 안으로 들어가 화면이 한 번 흔들린다.
|
|
281
|
+
*/
|
|
282
|
+
private handleTaskToggle;
|
|
283
|
+
/**
|
|
284
|
+
* 이미지 캡션(`<figcaption>`) 에 캐럿을 둔다. 없으면 만든다.
|
|
285
|
+
*
|
|
286
|
+
* 버튼은 토글이 아니다 — 다시 눌러 캡션을 지우면 사용자가 쓴 글이 말없이
|
|
287
|
+
* 사라진다. 캡션을 없애는 방법은 글자를 지우는 것이고, 빈 캡션은 캐럿이
|
|
288
|
+
* 떠난 뒤 `normalizeContent` 가 알아서 걷어낸다.
|
|
289
|
+
*/
|
|
290
|
+
private focusImageCaption;
|
|
204
291
|
/**
|
|
205
292
|
* 이미지/유튜브 좌상단 정렬 컨트롤 클릭 핸들러. data-align 에 따라 wrapper
|
|
206
293
|
* 의 marginLeft / marginRight 를 조정 — left/center/right.
|
|
@@ -303,20 +390,99 @@ export declare class AerizEditor {
|
|
|
303
390
|
* `url` 필드를 사용. 둘 다 없으면 undefined → 다이얼로그 업로드 탭 비활성.
|
|
304
391
|
*/
|
|
305
392
|
private resolveImageUploadFn;
|
|
306
|
-
/**
|
|
307
|
-
* `src` 의 이미지를 figure>img 블록으로 본문에 삽입.
|
|
308
|
-
* 활성 블록이 있으면 그 블록을 image 로 변환, 없으면 본문 끝에 추가.
|
|
309
|
-
*/
|
|
310
|
-
private insertImageBlock;
|
|
311
393
|
private queueSync;
|
|
312
394
|
private sync;
|
|
313
395
|
private handleKeyDown;
|
|
314
396
|
/**
|
|
315
|
-
*
|
|
316
|
-
*
|
|
397
|
+
* 마크다운 입력 규칙.
|
|
398
|
+
*
|
|
399
|
+
* 본문 블록 맨 앞에 `# ` / `- ` / `1. ` / `> ` / ``` 을 치면 그 자리에서
|
|
400
|
+
* 블록 유형이 바뀌고 방아쇠 문자는 사라진다. 메뉴를 열지 않고 글을 쓰던
|
|
401
|
+
* 흐름 그대로 유형을 고르는 길이다.
|
|
402
|
+
*
|
|
403
|
+
* 조건을 좁게 잡는다 — **본문 블록**에서, **캐럿이 그 텍스트 바로 뒤**에
|
|
404
|
+
* 있을 때만. 그렇지 않으면 이미 쓴 문단 중간에서 "- " 를 고치다가 블록이
|
|
405
|
+
* 통째로 바뀌는 사고가 난다.
|
|
406
|
+
*/
|
|
407
|
+
private handleInputRule;
|
|
408
|
+
/**
|
|
409
|
+
* 글머리 목록 항목에서 `[ ] ` / `[x] ` 를 알아보고 체크리스트로 바꾼다.
|
|
410
|
+
*
|
|
411
|
+
* `setBlockType` 을 쓰지 않는다 — 그 경로는 항목들을 `<br>` 로 이어 붙여
|
|
412
|
+
* 한 덩어리로 만들기 때문에, 항목이 여럿인 목록에서 줄이 뭉개진다. 목록
|
|
413
|
+
* 구조는 그대로 두고 클래스만 올린다.
|
|
414
|
+
*/
|
|
415
|
+
private applyTaskItemRule;
|
|
416
|
+
/**
|
|
417
|
+
* 블록 단축키. 처리했으면 `true`.
|
|
418
|
+
*
|
|
419
|
+
* 유형 변경은 `Ctrl/Cmd + Alt + 숫자` 다 — 구글 문서 · 노션이 같은 자리를
|
|
420
|
+
* 쓰기 때문에 손이 이미 알고 있는 배열이고, 브라우저 기본 단축키
|
|
421
|
+
* (Ctrl+숫자 = 탭 전환) 와 겹치지 않는다. 어느 유형의 블록에서든 다른
|
|
422
|
+
* 유형으로 바로 넘어간다.
|
|
423
|
+
*
|
|
424
|
+
* Ctrl+Alt+0 본문 Ctrl+Alt+1~6 제목 1~6
|
|
425
|
+
* Ctrl+Alt+7 번호 목록 Ctrl+Alt+8 글머리 목록
|
|
426
|
+
* Ctrl+Alt+9 인용구 Ctrl+Alt+C 코드 블록
|
|
427
|
+
* Ctrl+Shift+↑/↓ 블록 이동 Ctrl+Shift+D 블록 삭제
|
|
428
|
+
*
|
|
429
|
+
* 이동과 삭제는 캐럿이 어디 있든 **블록 단위**로 동작한다. 지금까지는
|
|
430
|
+
* 드래그 핸들을 잡는 것 말고는 블록을 옮길 방법이 없었다.
|
|
431
|
+
*/
|
|
432
|
+
private handleBlockShortcut;
|
|
433
|
+
/**
|
|
434
|
+
* 활성 블록을 위/아래 형제와 자리바꿈한다. 문서 끝에서는 아무 일도 하지
|
|
435
|
+
* 않는다 — 경고 없이 조용히 멈추는 편이 캐럿을 잃는 것보다 낫다.
|
|
436
|
+
*/
|
|
437
|
+
private moveActiveBlock;
|
|
438
|
+
/**
|
|
439
|
+
* 활성 블록을 지우고 캐럿을 이웃 블록으로 옮긴다.
|
|
440
|
+
*
|
|
441
|
+
* 마지막 블록을 지우면 `normalizeContent` 가 빈 본문 블록을 다시 만든다 —
|
|
442
|
+
* 본문이 블록 없는 상태로 남지 않는다.
|
|
443
|
+
*/
|
|
444
|
+
private deleteActiveBlock;
|
|
445
|
+
/**
|
|
446
|
+
* Tab 처리. 처리했으면 `true`.
|
|
447
|
+
*
|
|
448
|
+
* - 표 안: 다음(Shift 면 이전) 셀로 캐럿 이동. 마지막 셀에서 Tab 은 새 행을
|
|
449
|
+
* 만든다 — 표를 채워 넣을 때 손이 마우스로 갈 일이 없어진다.
|
|
450
|
+
* - 목록 안: `indent` / `outdent` 로 한 단계 들여쓰기. 중첩 목록을 만들
|
|
451
|
+
* 방법이 이것 말고는 없었다(마크다운으로 가져온 중첩 목록은 편집만 가능).
|
|
452
|
+
*/
|
|
453
|
+
private handleTabKey;
|
|
454
|
+
/**
|
|
455
|
+
* Backspace 처리. 처리했으면 `true`.
|
|
456
|
+
*
|
|
457
|
+
* 비어 있는 제목 · 인용구 · 코드 블록 · 목록의 맨 앞에서 Backspace 를 누르면
|
|
458
|
+
* **본문 블록으로 되돌린다.** 유형을 잘못 골랐을 때 되돌리는 가장 자연스러운
|
|
459
|
+
* 동작이고, 브라우저 기본 동작(앞 블록에 병합) 이 만들어 내는 이상한 중첩
|
|
460
|
+
* (제목 안에 목록이 들어가는 등) 도 함께 피한다.
|
|
461
|
+
*/
|
|
462
|
+
private handleBackspaceKey;
|
|
463
|
+
/**
|
|
464
|
+
* 활성 블록 뒤에 새 빈 **본문 블록**을 만들고 캐럿을 그 안에 둔다.
|
|
465
|
+
* 인용구 / 코드 블록의 Enter 탈출, 제목 끝 Enter 에 사용.
|
|
317
466
|
*/
|
|
318
467
|
private exitBlockOnEnter;
|
|
319
468
|
private syncBlockHandles;
|
|
469
|
+
/**
|
|
470
|
+
* 컨트롤(드래그 핸들 · 단락 추가) 은 **지금 다루고 있는 블록** 에만 보인다.
|
|
471
|
+
* 포인터가 놓인 블록과 캐럿이 있는 블록 두 가지가 그 대상이다.
|
|
472
|
+
*
|
|
473
|
+
* 예전에는 본문에 포인터만 올라가면 모든 블록의 핸들이 한꺼번에 흐리게
|
|
474
|
+
* 떠올랐다. 글이 길어질수록 왼쪽에 점 세 개짜리 기둥이 생겨서, 정작 어느
|
|
475
|
+
* 블록을 잡는 손잡이인지가 안 보였다.
|
|
476
|
+
*/
|
|
477
|
+
private syncHandleVisibility;
|
|
478
|
+
private readonly handleHoverMove;
|
|
479
|
+
private readonly handleHoverLeave;
|
|
480
|
+
private setHoveredBlock;
|
|
481
|
+
/**
|
|
482
|
+
* 뷰포트 y 좌표가 걸치는 블록의 id. 좌표가 블록들 사이의 여백이면 가장
|
|
483
|
+
* 가까운 블록으로 붙인다 — 문단 사이 간격에서 컨트롤이 깜빡이지 않게.
|
|
484
|
+
*/
|
|
485
|
+
private blockIdAtViewportY;
|
|
320
486
|
private repositionHandles;
|
|
321
487
|
private positionHandle;
|
|
322
488
|
private createBlockHandle;
|
|
@@ -351,6 +517,13 @@ export declare class AerizEditor {
|
|
|
351
517
|
* - 우측: 총 블록 수, 본문 글자 수(공백 제외)
|
|
352
518
|
*/
|
|
353
519
|
private syncStatusBar;
|
|
520
|
+
/**
|
|
521
|
+
* 되돌리기 / 다시 실행 버튼의 활성 상태.
|
|
522
|
+
*
|
|
523
|
+
* 누를 수 없는 버튼이 누를 수 있는 것처럼 보이면, 눌러 보고 아무 일도 안
|
|
524
|
+
* 일어나는 경험을 준다. 이력 끝에 닿았다는 사실 자체가 정보다.
|
|
525
|
+
*/
|
|
526
|
+
private syncHistoryButtons;
|
|
354
527
|
private syncBlockMarkers;
|
|
355
528
|
private applyToolbarState;
|
|
356
529
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AerizEditor.d.ts","sourceRoot":"","sources":["../../src/core/AerizEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"AerizEditor.d.ts","sourceRoot":"","sources":["../../src/core/AerizEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAmExC,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAA6B,MAAM,UAAU,CAAC;AAsBvG,YAAY,EACV,KAAK,EACL,UAAU,EACV,SAAS,EACT,UAAU,EACV,aAAa,EACb,SAAS,EACT,cAAc,EACd,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AAc/D,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAQ;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IAEjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyD;IAC/E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;IAC5D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAgC;IACtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IACrE,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuC;IAE7E,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAM;IAC5B,uCAAuC;IACvC,OAAO,CAAC,cAAc,CAAuB;IAC7C,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAuB;IACvC,uDAAuD;IACvD,OAAO,CAAC,WAAW,CAAuB;IAC1C;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAW;IAC1B;;;OAGG;IACH,OAAO,CAAC,eAAe,CAAS;IAChC;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAwB;IACjD,uDAAuD;IACvD,OAAO,CAAC,kBAAkB,CAAgB;gBAE9B,OAAO,EAAE,aAAa;IA0LlC;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,OAAO,GAAE,oBAAyB,GAAG,MAAM;IAgBnD,yCAAyC;IACzC,UAAU,IAAI,MAAM;IAIpB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc3B,KAAK,IAAI,IAAI;IAIb,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAIvC,QAAQ,IAAI,WAAW;IAIvB,SAAS,IAAI,KAAK,EAAE;IAIpB;;;OAGG;IACH,SAAS,IAAI,aAAa,EAAE;IAI5B;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAMvC,cAAc,IAAI,KAAK,GAAG,IAAI;IAQ9B;;;;;OAKG;IACH,YAAY,CACV,IAAI,EAAE,SAAS,EACf,KAAK,CAAC,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,IAAI;IAgBP,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,WAAW;IAMnB,aAAa,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAKxD,OAAO,IAAI,IAAI;IAsBf;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAeb;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAcrB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,UAAU;IAYlB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAI5B,qCAAqC;IACrC,IAAI,IAAI,IAAI;IAIZ,aAAa;IACb,IAAI,IAAI,IAAI;IAIZ,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,mBAAmB;IAmI3B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;OAMG;IACH,OAAO,CAAC,SAAS;IAUjB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAcvB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IASlB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,UAAU;IAsClB,2CAA2C;IAC3C,OAAO,CAAC,kBAAkB;IAW1B;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,YAAY,CAAqC;IACzD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,gBAAgB;IAQxB,qCAAqC;IACrC,OAAO,CAAC,kBAAkB;IAK1B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0B1B,gCAAgC;IAChC,OAAO,CAAC,YAAY;IAwBpB,+CAA+C;IAC/C,OAAO,CAAC,SAAS;IAoBjB,8CAA8C;IAC9C,OAAO,CAAC,YAAY;IAwBpB,yCAAyC;IACzC,OAAO,CAAC,SAAS;IAYjB;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,qBAAqB;IAgB7B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAOvB;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAUhC,yCAAyC;IACzC,OAAO,CAAC,YAAY;IAiBpB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,WAAW,CAOH;IAEhB;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IA0E9B,OAAO,CAAC,qBAAqB;IAe7B;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAsBzB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAgC7B;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB;IAuBxB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,YAAY;IAKpB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAOvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;;;;;;OAQG;IACH,OAAO,CAAC,aAAa;IAmErB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAwCzB;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAa/B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IASjC;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IAuEpC;;;OAGG;IACH,OAAO,CAAC,gCAAgC;IAqDxC;;;;OAIG;IACH,OAAO,CAAC,gCAAgC;IAsBxC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,IAAI;IA+BZ,OAAO,CAAC,aAAa;IAuErB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,eAAe;IAuBvB;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAoCzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,mBAAmB;IA8B3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IA2BpB;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,gBAAgB;IAqBxB;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAQ9B;IAEF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAE/B;IAEF,OAAO,CAAC,eAAe;IAMvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,iBAAiB;IAqEzB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,iBAAiB;IAIzB;;;;;;OAMG;IACH;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IA6C1B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAgCrB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,iBAAiB;CA6B1B"}
|
|
@@ -29,4 +29,70 @@ export declare const YOUTUBE_EMBED_BASE = "https://www.youtube-nocookie.com/embe
|
|
|
29
29
|
export declare const FILE_FALLBACK_NAME = "\uD30C\uC77C";
|
|
30
30
|
/** 블록의 안정 식별자를 담는 속성명. */
|
|
31
31
|
export declare const BLOCK_ID_ATTR = "data-block-id";
|
|
32
|
+
/**
|
|
33
|
+
* 눈에 보이지 않는 폭 없는 문자들 — ZWSP · ZWNJ · ZWJ · BOM.
|
|
34
|
+
*
|
|
35
|
+
* 에디터가 캐럿을 붙잡아 두려고 심는 U+200B 가 대표적이다. 글자 수를 세거나
|
|
36
|
+
* "이 블록이 비었나" 를 판단할 때 이것들을 글자로 치면 사용자가 보는 것과
|
|
37
|
+
* 다른 답이 나온다. 세 군데(글자 수 · 캐럿 판정 · 평문 추출)에서 같은 판정을
|
|
38
|
+
* 써야 해서 여기 한 번만 적는다.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ZERO_WIDTH_RE: RegExp;
|
|
41
|
+
/**
|
|
42
|
+
* 스냅샷이 블록 element **자신**에서 함께 실어 나르는 속성.
|
|
43
|
+
*
|
|
44
|
+
* `html` 은 블록의 **안쪽**만 담고 `style` 은 따로 필드가 있다. 그래서 블록에
|
|
45
|
+
* 직접 걸린 나머지 속성은 아무 데도 실리지 않아 저장 한 번에 사라졌다.
|
|
46
|
+
* 잃으면 실제로 곤란한 것만 골라 담는다.
|
|
47
|
+
*
|
|
48
|
+
* - `id` : 문서 안 앵커 링크(`#section-1`) 가 끊긴다
|
|
49
|
+
* - `class`: 가져온 문서의 스타일 훅이 사라진다
|
|
50
|
+
* - `dir` : 아랍어 · 히브리어 문단의 쓰기 방향이 뒤집힌다
|
|
51
|
+
* - `lang` : 스크린 리더 발음과 하이픈 규칙이 바뀐다
|
|
52
|
+
* - `title`: 마우스를 올렸을 때 뜨는 설명
|
|
53
|
+
*
|
|
54
|
+
* **허용목록인 것이 핵심이다.** 전부 실어 나르면 `onclick` 같은 이벤트 핸들러
|
|
55
|
+
* 속성이 저장을 거쳐 되살아난다 — 저장된 글은 다른 사람에게 렌더된다.
|
|
56
|
+
*/
|
|
57
|
+
export declare const PRESERVED_BLOCK_ATTRS: ReadonlyArray<string>;
|
|
58
|
+
/**
|
|
59
|
+
* `unknown` 블록으로 되살릴 수 있는 태그.
|
|
60
|
+
*
|
|
61
|
+
* 저장된 값에서 온 태그명을 그대로 `createElement` 에 넘기면 안 된다 —
|
|
62
|
+
* `script` 를 만들어 내용을 넣고 문서에 붙이면 **실행된다** (innerHTML 경로와
|
|
63
|
+
* 달리 createElement 경로는 막히지 않는다). 내용을 담기만 하는 컨테이너
|
|
64
|
+
* 태그만 허용하고, 나머지는 `<div>` 로 떨어뜨린다.
|
|
65
|
+
*/
|
|
66
|
+
export declare const SAFE_UNKNOWN_TAGS: ReadonlySet<string>;
|
|
67
|
+
/** 저장된 태그명을 되살릴 수 있는 것으로 정규화한다. 알 수 없으면 `'div'`. */
|
|
68
|
+
export declare function safeUnknownTag(raw: string | undefined | null): string;
|
|
69
|
+
/**
|
|
70
|
+
* 클래스 이름들을 순서를 지키며 하나로 합친다 (중복 제거).
|
|
71
|
+
*
|
|
72
|
+
* 어떤 블록은 클래스가 곧 정체성이다 — `aw-task-list` 가 없으면 체크리스트가
|
|
73
|
+
* 글머리 목록으로 잡힌다. 그런데 스냅샷에 저장된 사용자 클래스도 함께 살려야
|
|
74
|
+
* 한다. 둘 중 하나를 고르면 반드시 무언가를 잃으므로 합친다.
|
|
75
|
+
*/
|
|
76
|
+
export declare function mergeClassNames(...values: ReadonlyArray<string | undefined | null>): string;
|
|
77
|
+
/** 체크리스트 `<ul>` 을 글머리 목록과 구분하는 클래스. */
|
|
78
|
+
export declare const TASK_LIST_CLASS = "aw-task-list";
|
|
79
|
+
/** 체크리스트 항목의 완료 여부를 담는 속성명. */
|
|
80
|
+
export declare const TASK_CHECKED_ATTR = "data-checked";
|
|
81
|
+
/**
|
|
82
|
+
* 링크 / 다운로드 URL 을 검사한다. 안전하면 원문 그대로, 아니면 빈 문자열.
|
|
83
|
+
*
|
|
84
|
+
* 스킴이 없는 값(상대 경로 · `#앵커` · `?쿼리`) 은 그대로 통과한다 — 문서
|
|
85
|
+
* 안에서 쓰는 정상적인 링크다.
|
|
86
|
+
*/
|
|
87
|
+
export declare function safeLinkUrl(raw: string | undefined | null): string;
|
|
88
|
+
/**
|
|
89
|
+
* 이미지 src 를 검사한다. 안전하면 원문 그대로, 아니면 빈 문자열.
|
|
90
|
+
* `data:image/...` 는 허용한다 — 이미지 다이얼로그의 임베드 탭이 만드는 값이다.
|
|
91
|
+
*/
|
|
92
|
+
export declare function safeImageUrl(raw: string | undefined | null): string;
|
|
93
|
+
/**
|
|
94
|
+
* YouTube 영상 ID 의 형태 검사. 임베드 URL 에 그대로 이어 붙이는 값이라
|
|
95
|
+
* `../` 나 따옴표가 섞이면 URL 자체가 다른 곳을 가리키게 된다.
|
|
96
|
+
*/
|
|
97
|
+
export declare function safeYouTubeId(raw: string | undefined | null): string;
|
|
32
98
|
//# sourceMappingURL=block-meta.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block-meta.d.ts","sourceRoot":"","sources":["../../src/core/block-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6BAA6B;AAC7B,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED,0BAA0B;AAC1B,eAAO,MAAM,aAAa,QAGK,CAAC;AAEhC,4BAA4B;AAC5B,eAAO,MAAM,eAAe,QAGyD,CAAC;AAEtF,+BAA+B;AAC/B,eAAO,MAAM,oBAAoB,6FAC2D,CAAC;AAE7F,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,4CAA4C,CAAC;AAE5E,4BAA4B;AAC5B,eAAO,MAAM,kBAAkB,iBAAO,CAAC;AAEvC,0BAA0B;AAC1B,eAAO,MAAM,aAAa,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"block-meta.d.ts","sourceRoot":"","sources":["../../src/core/block-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6BAA6B;AAC7B,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED,sDAAsD;AACtD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED,0BAA0B;AAC1B,eAAO,MAAM,aAAa,QAGK,CAAC;AAEhC,4BAA4B;AAC5B,eAAO,MAAM,eAAe,QAGyD,CAAC;AAEtF,+BAA+B;AAC/B,eAAO,MAAM,oBAAoB,6FAC2D,CAAC;AAE7F,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,4CAA4C,CAAC;AAE5E,4BAA4B;AAC5B,eAAO,MAAM,kBAAkB,iBAAO,CAAC;AAEvC,0BAA0B;AAC1B,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAY,CAAC;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAMvD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAIhD,CAAC;AAEH,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAIrE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,MAAM,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,GAClD,MAAM,CASR;AAED,uCAAuC;AACvC,eAAO,MAAM,eAAe,iBAAiB,CAAC;AAE9C,+BAA+B;AAC/B,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AA2DhD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAOlE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CASnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGpE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 블록이 무엇을 허용하는지, 그리고 화면에 어떻게 소개되는지.
|
|
3
|
+
*
|
|
4
|
+
* 툴바의 항목 표시 여부, 단축키가 먹히는지, 유형을 바꿀 때 어떤 서식을
|
|
5
|
+
* 남길지가 모두 같은 판정에서 나와야 한다. 한 곳에서만 답하게 두면
|
|
6
|
+
* "툴바에서는 안 보이는데 단축키로는 먹는" 종류의 어긋남이 생기지 않는다.
|
|
7
|
+
*
|
|
8
|
+
* 판정의 근거는 대부분 `BlockType` 에 이미 선언돼 있다 (`allowedMarks` ·
|
|
9
|
+
* `allowsColor` · `allowsFontSize` · `allowsInlineFormat`). 여기 있는 함수는
|
|
10
|
+
* 그 선언을 "활성 블록" 이라는 물음으로 바꿔 주는 얇은 층이다.
|
|
11
|
+
*/
|
|
12
|
+
import type { Block, BlockMatch, InlineMarkName } from './blocks.js';
|
|
13
|
+
/**
|
|
14
|
+
* 활성 블록이 특정 인라인 마크를 허용하는지.
|
|
15
|
+
*
|
|
16
|
+
* paragraph / 목록 / 체크리스트 / table — 모든 마크
|
|
17
|
+
* heading — italic 만 (제목은 이미 굵고, 밑줄·취소선은 시맨틱에 안 맞는다)
|
|
18
|
+
* blockquote — bold / underline / strike (인용구는 이미 italic 으로 렌더된다)
|
|
19
|
+
* codeBlock 및 원자 블록 — 없음
|
|
20
|
+
*/
|
|
21
|
+
export declare function isMarkAllowed(active: Block | null, mark: InlineMarkName): boolean;
|
|
22
|
+
/** 인라인 서식(글꼴 등) 적용을 허용하는지. */
|
|
23
|
+
export declare function isInlineFormatAllowed(active: Block | null): boolean;
|
|
24
|
+
/** 글자 크기 조정을 허용하는지. heading 은 level 이 크기를 정하므로 false. */
|
|
25
|
+
export declare function isFontSizeAllowed(active: Block | null): boolean;
|
|
26
|
+
/** 글자색 / 배경색 적용을 허용하는지. heading · blockquote 는 톤 보존을 위해 false. */
|
|
27
|
+
export declare function isColorAllowed(active: Block | null): boolean;
|
|
28
|
+
export declare function isAlignAllowed(active: Block | null): boolean;
|
|
29
|
+
/** 표 전용 도구(셀 배경 · 표 편집) 를 켤 조건. */
|
|
30
|
+
export declare function isTableActive(active: Block | null): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* 블록 라벨.
|
|
33
|
+
*
|
|
34
|
+
* 블록은 언제나 자기 kind 의 정식 라벨을 단다. 비어 있다고 해서 유형이 없는
|
|
35
|
+
* 것이 아니다 — Enter 로 갓 생긴 빈 블록은 **본문 블록**이고 그렇게 보여야
|
|
36
|
+
* 한다. 예전에는 이런 블록에 '?' 를 달았는데, 사용자에게 "아직 유형이 정해지지
|
|
37
|
+
* 않은 블록" 이라는 없는 상태를 만들어 보여 준 셈이었다.
|
|
38
|
+
*
|
|
39
|
+
* 어떤 BlockType 에도 매칭되지 않은 element(`unknown`) 만 태그명을 쓴다.
|
|
40
|
+
*/
|
|
41
|
+
export declare function blockLabelFor(el: HTMLElement, match: BlockMatch): string;
|
|
42
|
+
export declare function blockGlyphFor(match: BlockMatch): string;
|
|
43
|
+
//# sourceMappingURL=block-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-policy.d.ts","sourceRoot":"","sources":["../../src/core/block-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,KAAK,EAAa,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAS7E;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,GAAG,IAAI,EACpB,IAAI,EAAE,cAAc,GACnB,OAAO,CAET;AAED,8BAA8B;AAC9B,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAEnE;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAE/D;AAED,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAE5D;AAeD,wBAAgB,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAE5D;AAED,mCAAmC;AACnC,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,GAAG,IAAI,GAAG,OAAO,CAE3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAGxE;AA2BD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAGvD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type BlockKind = 'paragraph' | 'heading' | 'bulletList' | 'orderedList' | 'blockquote' | 'codeBlock' | 'image' | 'table' | 'hr' | 'linkCard' | 'youtube' | 'file' | 'importedHtml' | 'unknown';
|
|
1
|
+
export type BlockKind = 'paragraph' | 'heading' | 'bulletList' | 'orderedList' | 'taskList' | 'blockquote' | 'codeBlock' | 'image' | 'table' | 'hr' | 'linkCard' | 'youtube' | 'file' | 'importedHtml' | 'unknown';
|
|
2
2
|
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
3
|
/** 단락 — 메타데이터 없음. */
|
|
4
4
|
export interface ParagraphAttrs {
|
|
@@ -13,6 +13,12 @@ export interface BulletListAttrs {
|
|
|
13
13
|
/** 번호 목록(ordered) — kind 자체가 ordered=true 를 의미. 추가 메타 없음. */
|
|
14
14
|
export interface OrderedListAttrs {
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* 체크리스트 — 항목별 완료 여부는 `<li data-checked>` 로 html 안에 담긴다.
|
|
18
|
+
* 블록 단위 메타는 없다.
|
|
19
|
+
*/
|
|
20
|
+
export interface TaskListAttrs {
|
|
21
|
+
}
|
|
16
22
|
/** 인용구 — 메타데이터 없음. */
|
|
17
23
|
export interface BlockquoteAttrs {
|
|
18
24
|
}
|
|
@@ -25,6 +31,18 @@ export interface CodeBlockAttrs {
|
|
|
25
31
|
export interface ImageAttrs {
|
|
26
32
|
src?: string;
|
|
27
33
|
alt?: string;
|
|
34
|
+
/**
|
|
35
|
+
* 그림 아래 설명(`<figcaption>`) 의 **텍스트**.
|
|
36
|
+
*
|
|
37
|
+
* `alt` 와는 다른 값이다 — `alt` 는 그림을 못 보는 사람에게 그림을 대신
|
|
38
|
+
* 설명하는 글이고, 캡션은 보는 사람에게도 함께 읽히는 본문의 일부다
|
|
39
|
+
* (출처 · 촬영 정보 · 부연). 둘을 한 필드로 합치면 어느 쪽도 제 역할을
|
|
40
|
+
* 못 한다.
|
|
41
|
+
*
|
|
42
|
+
* 서식이 들어간 캡션(링크 등) 은 `snapshot.html` 에 그대로 실린다. 이
|
|
43
|
+
* 필드는 `html` 이 비어 있을 때 골격을 조립하기 위한 평문이다.
|
|
44
|
+
*/
|
|
45
|
+
caption?: string;
|
|
28
46
|
/** wrapper(figure) 의 인라인 style — width / margin 등 outer 스타일 보존. */
|
|
29
47
|
wrapperStyle?: string;
|
|
30
48
|
}
|
|
@@ -75,6 +93,14 @@ export interface ImportedHtmlAttrs {
|
|
|
75
93
|
}
|
|
76
94
|
/** 어떤 BlockType 에도 매칭되지 않은 element. */
|
|
77
95
|
export interface UnknownAttrs {
|
|
96
|
+
/**
|
|
97
|
+
* 원래 태그명 (소문자).
|
|
98
|
+
*
|
|
99
|
+
* `unknown` 은 미래 버전의 블록이 강등되어 오는 자리다. 태그를 버리면 그
|
|
100
|
+
* 블록을 만든 버전에서 다시 열었을 때도 `<div>` 로 남아 영영 복구되지
|
|
101
|
+
* 않는다. 안전한 컨테이너 태그만 되살린다 ({@link SAFE_UNKNOWN_TAGS}).
|
|
102
|
+
*/
|
|
103
|
+
tag?: string;
|
|
78
104
|
}
|
|
79
105
|
/** BlockKind → 해당 블록의 attrs 타입 매핑. discriminated union 의 기반. */
|
|
80
106
|
export interface BlockAttrsByKind {
|
|
@@ -82,6 +108,7 @@ export interface BlockAttrsByKind {
|
|
|
82
108
|
heading: HeadingAttrs;
|
|
83
109
|
bulletList: BulletListAttrs;
|
|
84
110
|
orderedList: OrderedListAttrs;
|
|
111
|
+
taskList: TaskListAttrs;
|
|
85
112
|
blockquote: BlockquoteAttrs;
|
|
86
113
|
codeBlock: CodeBlockAttrs;
|
|
87
114
|
image: ImageAttrs;
|
|
@@ -99,7 +126,7 @@ export interface BlockAttrsByKind {
|
|
|
99
126
|
* 외부에서 직렬화된 BlockSnapshot 의 attrs 는 BlockAttrsByKind[kind] 로 더
|
|
100
127
|
* 구체적으로 타입이 잡힌다 — 아래 BlockSnapshot 의 discriminated union 참고.
|
|
101
128
|
*/
|
|
102
|
-
export interface BlockAttrs extends Partial<HeadingAttrs>, Partial<BulletListAttrs>, Partial<OrderedListAttrs>, Partial<CodeBlockAttrs>, Partial<ImageAttrs>, Partial<TableAttrs>, Partial<LinkCardAttrs>, Partial<YoutubeAttrs>, Partial<FileAttrs>, Partial<ImportedHtmlAttrs> {
|
|
129
|
+
export interface BlockAttrs extends Partial<HeadingAttrs>, Partial<BulletListAttrs>, Partial<OrderedListAttrs>, Partial<CodeBlockAttrs>, Partial<ImageAttrs>, Partial<TableAttrs>, Partial<LinkCardAttrs>, Partial<YoutubeAttrs>, Partial<FileAttrs>, Partial<ImportedHtmlAttrs>, Partial<UnknownAttrs> {
|
|
103
130
|
}
|
|
104
131
|
/**
|
|
105
132
|
* BlockType.matches() 의 반환 타입. 내부 사용은 느슨한 BlockAttrs 로 두고,
|
|
@@ -197,9 +224,18 @@ export declare function assignMissingIds(root: HTMLElement, ids: BlockIdRegistry
|
|
|
197
224
|
* "homeless" 텍스트가 생길 수 있는데, 이를 정규화하여 모든 본문 자식이
|
|
198
225
|
* 항상 유효한 블록 element 가 되도록 보장한다.
|
|
199
226
|
*/
|
|
200
|
-
export
|
|
227
|
+
export interface NormalizeOptions {
|
|
228
|
+
/**
|
|
229
|
+
* 본문이 항상 캐럿을 받을 수 있는 상태로 끝나도록 빈 본문 블록을 보장할지.
|
|
230
|
+
* 기본 `true` (편집 경로). HTML → 블록 변환처럼 **편집하지 않는** 용도라면
|
|
231
|
+
* `false` 로 꺼서 없던 빈 단락이 결과에 끼어들지 않게 한다.
|
|
232
|
+
*/
|
|
233
|
+
writableTail?: boolean;
|
|
234
|
+
}
|
|
235
|
+
export declare function normalizeContent(root: HTMLElement, options?: NormalizeOptions): void;
|
|
201
236
|
/**
|
|
202
|
-
* 사람이 읽을 수 있는
|
|
237
|
+
* 사람이 읽을 수 있는 블록 라벨. 포커스된 블록 위 태그 표시 등에 사용.
|
|
238
|
+
* 문자열은 현재 로케일(`setLocale`) 사전에서 가져온다.
|
|
203
239
|
*/
|
|
204
240
|
export declare function getBlockLabel(match: BlockMatch): string;
|
|
205
241
|
export type BlockIdResolver = (el: HTMLElement) => string;
|
|
@@ -229,6 +265,13 @@ export type BlockSnapshot = {
|
|
|
229
265
|
attrs: BlockAttrsByKind[K];
|
|
230
266
|
html: string;
|
|
231
267
|
style?: string;
|
|
268
|
+
/**
|
|
269
|
+
* 블록 element 자신의 나머지 속성 (`id` · `class` · `dir` · `lang` ·
|
|
270
|
+
* `title`). `html` 은 안쪽만, `style` 은 따로 담기 때문에 이 필드가 없으면
|
|
271
|
+
* 저장 한 번에 사라진다 — 앵커 링크가 끊기고 RTL 문단의 방향이 뒤집힌다.
|
|
272
|
+
* 허용목록은 `PRESERVED_BLOCK_ATTRS`.
|
|
273
|
+
*/
|
|
274
|
+
attributes?: Record<string, string>;
|
|
232
275
|
};
|
|
233
276
|
}[BlockKind];
|
|
234
277
|
/** 특정 BlockKind 에 한정된 BlockSnapshot 의 별칭. 외부에서 narrow 한
|