@aeriz/wysiwyg 1.0.2 → 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 +634 -96
- package/angular/README.md +112 -0
- package/angular/aeriz-editor.directive.ts +243 -0
- package/angular/aeriz-wysiwyg.module.ts +14 -0
- package/angular/index.ts +5 -0
- package/dist/adapters/jquery.cjs +1 -0
- package/dist/adapters/jquery.js +91 -0
- package/dist/adapters/react.cjs +1 -0
- package/dist/adapters/react.js +66 -0
- package/dist/adapters/shared.cjs +1 -0
- package/dist/adapters/shared.js +87 -0
- package/dist/adapters/svelte.cjs +1 -0
- package/dist/adapters/svelte.js +29 -0
- package/dist/adapters/vue.cjs +1 -0
- package/dist/adapters/vue.js +110 -0
- package/dist/adapters/vue2.cjs +1 -0
- package/dist/adapters/vue2.js +117 -0
- package/dist/adapters/wc.cjs +1 -0
- package/dist/adapters/wc.js +207 -0
- package/dist/aeriz-wysiwyg-adapter.js +169 -0
- package/dist/aeriz-wysiwyg-adapter.min.js +1 -0
- package/dist/aeriz-wysiwyg-jquery.js +275 -0
- package/dist/aeriz-wysiwyg-jquery.min.js +1 -0
- package/dist/aeriz-wysiwyg-wc.js +401 -0
- package/dist/aeriz-wysiwyg-wc.min.js +1 -0
- package/dist/aeriz-wysiwyg.cjs +8759 -0
- package/dist/aeriz-wysiwyg.css +587 -163
- package/dist/aeriz-wysiwyg.esm.js +4249 -1381
- package/dist/aeriz-wysiwyg.esm.min.js +4456 -1995
- package/dist/aeriz-wysiwyg.js +4249 -1381
- package/dist/aeriz-wysiwyg.min.cjs +56 -0
- package/dist/aeriz-wysiwyg.min.css +1 -1
- package/dist/aeriz-wysiwyg.min.js +54 -21
- package/dist/server.cjs +34 -0
- package/dist/server.js +798 -0
- package/dist-types/adapters/jquery.d.ts +34 -0
- package/dist-types/adapters/jquery.d.ts.map +1 -0
- package/dist-types/adapters/react.d.ts +28 -0
- package/dist-types/adapters/react.d.ts.map +1 -0
- package/dist-types/adapters/shared.d.ts +83 -0
- package/dist-types/adapters/shared.d.ts.map +1 -0
- package/dist-types/adapters/svelte.d.ts +38 -0
- package/dist-types/adapters/svelte.d.ts.map +1 -0
- package/dist-types/adapters/vue.d.ts +189 -0
- package/dist-types/adapters/vue.d.ts.map +1 -0
- package/dist-types/adapters/vue2.d.ts +175 -0
- package/dist-types/adapters/vue2.d.ts.map +1 -0
- package/dist-types/adapters/wc.d.ts +96 -0
- package/dist-types/adapters/wc.d.ts.map +1 -0
- package/dist-types/cjs/adapters/jquery.d.cts +34 -0
- package/dist-types/cjs/adapters/react.d.cts +28 -0
- package/dist-types/cjs/adapters/shared.d.cts +83 -0
- package/dist-types/cjs/adapters/svelte.d.cts +38 -0
- package/dist-types/cjs/adapters/vue.d.cts +189 -0
- package/dist-types/cjs/adapters/vue2.d.cts +175 -0
- package/dist-types/cjs/adapters/wc.d.cts +96 -0
- package/dist-types/cjs/core/AerizEditor.d.cts +530 -0
- package/dist-types/cjs/core/AerizViewer.d.cts +61 -0
- package/dist-types/cjs/core/block-meta.d.cts +98 -0
- package/dist-types/cjs/core/block-policy.d.cts +43 -0
- package/dist-types/cjs/core/blocks.d.cts +411 -0
- package/dist-types/cjs/core/fonts.d.cts +60 -0
- package/dist-types/cjs/core/highlight.d.cts +44 -0
- package/dist-types/cjs/core/history.d.cts +86 -0
- package/dist-types/cjs/core/html-mini.d.cts +65 -0
- package/dist-types/cjs/core/i18n.d.cts +221 -0
- package/dist-types/cjs/core/import-html.d.cts +40 -0
- package/dist-types/cjs/core/import-markdown.d.cts +33 -0
- package/dist-types/cjs/core/input-rules.d.cts +46 -0
- package/dist-types/cjs/core/markdown-export.d.cts +30 -0
- package/dist-types/cjs/core/plain-text.d.cts +17 -0
- package/dist-types/cjs/core/render-string.d.cts +68 -0
- package/dist-types/cjs/core/selection.d.cts +46 -0
- package/dist-types/cjs/core/snapshot.d.cts +51 -0
- package/dist-types/cjs/core/table-ops.d.cts +30 -0
- package/dist-types/cjs/index.d.cts +22 -0
- package/dist-types/cjs/server/index.d.cts +37 -0
- package/dist-types/cjs/types/index.d.cts +61 -0
- package/dist-types/cjs/ui/Toolbar.d.cts +21 -0
- package/dist-types/cjs/ui/dialogs.d.cts +74 -0
- package/dist-types/cjs/ui/icons.d.cts +2 -0
- package/dist-types/cjs/ui/popovers.d.cts +70 -0
- package/dist-types/core/AerizEditor.d.ts +210 -17
- package/dist-types/core/AerizEditor.d.ts.map +1 -1
- package/dist-types/core/AerizViewer.d.ts +16 -4
- package/dist-types/core/AerizViewer.d.ts.map +1 -1
- package/dist-types/core/block-meta.d.ts +98 -0
- package/dist-types/core/block-meta.d.ts.map +1 -0
- 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 +109 -11
- package/dist-types/core/blocks.d.ts.map +1 -1
- package/dist-types/core/fonts.d.ts +11 -0
- package/dist-types/core/fonts.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/html-mini.d.ts +65 -0
- package/dist-types/core/html-mini.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/markdown-export.d.ts +30 -0
- package/dist-types/core/markdown-export.d.ts.map +1 -0
- package/dist-types/core/plain-text.d.ts +17 -0
- package/dist-types/core/plain-text.d.ts.map +1 -0
- package/dist-types/core/render-string.d.ts +68 -0
- package/dist-types/core/render-string.d.ts.map +1 -0
- 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 +51 -0
- package/dist-types/core/snapshot.d.ts.map +1 -0
- 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 +21 -10
- package/dist-types/index.d.ts.map +1 -1
- package/dist-types/server/index.d.ts +37 -0
- package/dist-types/server/index.d.ts.map +1 -0
- package/dist-types/types/index.d.ts +21 -0
- package/dist-types/types/index.d.ts.map +1 -1
- package/dist-types/ui/Toolbar.d.ts +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 +1 -1
- package/dist-types/ui/popovers.d.ts.map +1 -1
- package/package.json +213 -58
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { HtmlStyleMode, SerializeHtmlOptions } from '../types/index.cjs';
|
|
2
|
+
import type { Block, BlockSnapshot } from './blocks.cjs';
|
|
3
|
+
export interface ViewerOptions {
|
|
4
|
+
/** 마운트할 호스트 element */
|
|
5
|
+
element: HTMLElement;
|
|
6
|
+
/** 초기 블록 상태 (1차 입력 경로). HTML 이 아닌 상태 모델을 사용. */
|
|
7
|
+
initialBlocks?: BlockSnapshot[];
|
|
8
|
+
/** 초기 테마 */
|
|
9
|
+
theme?: 'light' | 'dark';
|
|
10
|
+
/** `getHTML()` 의 스타일 전략. 기본 `'inline'`. */
|
|
11
|
+
htmlStyles?: HtmlStyleMode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 편집 불가 모드의 읽기 전용 뷰어.
|
|
15
|
+
*
|
|
16
|
+
* 입력은 HTML 문자열이 아닌 BlockSnapshot 배열(상태 모델)이다.
|
|
17
|
+
* 각 snapshot 은 BlockType 레지스트리를 통해 새 element 로 렌더되며, 결과는
|
|
18
|
+
* AerizEditor 와 같은 `.aeriz-wysiwyg .aw-content` 트리에 들어가 동일한
|
|
19
|
+
* CSS 규칙(테마 변수 포함)이 그대로 적용된다.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const editor = new AerizEditor({ element: editorMount });
|
|
23
|
+
* const viewer = new AerizViewer({ element: viewerMount });
|
|
24
|
+
* editor.onStateChange(() => viewer.setBlocks(editor.serialize()));
|
|
25
|
+
*/
|
|
26
|
+
export declare class AerizViewer {
|
|
27
|
+
readonly root: HTMLDivElement;
|
|
28
|
+
readonly content: HTMLDivElement;
|
|
29
|
+
private readonly blockIds;
|
|
30
|
+
private readonly idFor;
|
|
31
|
+
/**
|
|
32
|
+
* 생성 시 받은 options 객체를 그대로 들고 있는다. `htmlStyles` 를 여기서
|
|
33
|
+
* 매번 다시 읽으므로, 호출자가 이 객체를 갱신하면 재생성 없이 출력 전략이
|
|
34
|
+
* 바뀐다 (AerizEditor 와 같은 규약).
|
|
35
|
+
*/
|
|
36
|
+
private readonly options;
|
|
37
|
+
private destroyed;
|
|
38
|
+
constructor(options: ViewerOptions);
|
|
39
|
+
/**
|
|
40
|
+
* BlockSnapshot 배열로부터 본문을 다시 렌더한다.
|
|
41
|
+
* 동일한 BlockType 레지스트리로 element 를 만들어 채우므로 외부 HTML 파싱
|
|
42
|
+
* 경로를 거치지 않는다.
|
|
43
|
+
*/
|
|
44
|
+
setBlocks(blocks: BlockSnapshot[]): void;
|
|
45
|
+
/** 현재 본문의 BlockSnapshot 배열을 반환한다. */
|
|
46
|
+
getBlocks(): BlockSnapshot[];
|
|
47
|
+
/** 임의의 노드를 받아 그 노드가 속한 블록을 반환한다. 본문 밖이면 null. */
|
|
48
|
+
getBlockOf(node: Node): Block | null;
|
|
49
|
+
/**
|
|
50
|
+
* 본문 HTML 을 반환한다. 전략은 `AerizEditor.getHTML()` 과 동일하다.
|
|
51
|
+
*
|
|
52
|
+
* - `'inline'` (기본) — 외부 컨텍스트(이메일, 다른 페이지의 HTML 영역 등)
|
|
53
|
+
* 에서도 동일한 시각으로 보이도록 portable 인라인 스타일을 베이크한다.
|
|
54
|
+
* - `'class'` — 클래스만 남긴다. `style` 속성을 지우는 sanitizer 대응.
|
|
55
|
+
*/
|
|
56
|
+
getHTML(options?: SerializeHtmlOptions): string;
|
|
57
|
+
setTheme(theme: 'light' | 'dark'): void;
|
|
58
|
+
destroy(): void;
|
|
59
|
+
private listBlocksInternal;
|
|
60
|
+
}
|
|
61
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 블록 렌더링에 쓰이는 순수 헬퍼와 상수.
|
|
3
|
+
*
|
|
4
|
+
* DOM 을 참조하지 않는다. 브라우저 렌더 경로(`blocks.ts`) 와 DOM 없는 문자열
|
|
5
|
+
* 렌더 경로(`render-string.ts`) 가 **같은** 값을 쓰도록 여기 한 곳에 둔다.
|
|
6
|
+
* 두 경로가 갈라지면 서버 재렌더 결과와 에디터 출력이 미묘하게 달라지므로,
|
|
7
|
+
* 양쪽이 공유해야 하는 것은 반드시 이 모듈로 올린다.
|
|
8
|
+
*/
|
|
9
|
+
/** 바이트 수를 사람이 읽는 크기 문자열로. */
|
|
10
|
+
export declare function formatBytes(bytes: number): string;
|
|
11
|
+
/** 표시용 짧은 타입 라벨. 파일명 확장자 우선, 없으면 MIME subtype. */
|
|
12
|
+
export declare function fileExtensionLabel(name?: string, mime?: string): string;
|
|
13
|
+
/** URL 의 hostname (subdomain 포함) 만 추출. 실패 시 빈 문자열. */
|
|
14
|
+
export declare function hostnameFromUrl(url: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Google 의 무료 favicon 서비스 URL 을 반환. CORS / 인증 불필요. URL 파싱
|
|
17
|
+
* 실패 시 빈 문자열.
|
|
18
|
+
*/
|
|
19
|
+
export declare function defaultFaviconUrl(url: string): string;
|
|
20
|
+
/** 파일 첨부 카드 좌측 문서 아이콘. */
|
|
21
|
+
export declare const FILE_ICON_SVG: string;
|
|
22
|
+
/** 파일 첨부 카드 우측 다운로드 아이콘. */
|
|
23
|
+
export declare const FILE_ACTION_SVG: string;
|
|
24
|
+
/** 유튜브 iframe 의 `allow` 목록. */
|
|
25
|
+
export declare const YOUTUBE_IFRAME_ALLOW = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
|
|
26
|
+
/** 유튜브 임베드 base URL. 쿠키를 덜 쓰는 nocookie 도메인을 사용한다. */
|
|
27
|
+
export declare const YOUTUBE_EMBED_BASE = "https://www.youtube-nocookie.com/embed/";
|
|
28
|
+
/** 파일명이 없는 첨부의 기본 표시 이름. */
|
|
29
|
+
export declare const FILE_FALLBACK_NAME = "\uD30C\uC77C";
|
|
30
|
+
/** 블록의 안정 식별자를 담는 속성명. */
|
|
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;
|
|
98
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -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.cjs';
|
|
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
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
export type BlockKind = 'paragraph' | 'heading' | 'bulletList' | 'orderedList' | 'taskList' | 'blockquote' | 'codeBlock' | 'image' | 'table' | 'hr' | 'linkCard' | 'youtube' | 'file' | 'importedHtml' | 'unknown';
|
|
2
|
+
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
3
|
+
/** 단락 — 메타데이터 없음. */
|
|
4
|
+
export interface ParagraphAttrs {
|
|
5
|
+
}
|
|
6
|
+
/** 제목 — 1~6 의 level 만 가짐. */
|
|
7
|
+
export interface HeadingAttrs {
|
|
8
|
+
level: HeadingLevel;
|
|
9
|
+
}
|
|
10
|
+
/** 글머리 목록(unordered) — kind 자체가 ordered=false 를 의미. 추가 메타 없음. */
|
|
11
|
+
export interface BulletListAttrs {
|
|
12
|
+
}
|
|
13
|
+
/** 번호 목록(ordered) — kind 자체가 ordered=true 를 의미. 추가 메타 없음. */
|
|
14
|
+
export interface OrderedListAttrs {
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 체크리스트 — 항목별 완료 여부는 `<li data-checked>` 로 html 안에 담긴다.
|
|
18
|
+
* 블록 단위 메타는 없다.
|
|
19
|
+
*/
|
|
20
|
+
export interface TaskListAttrs {
|
|
21
|
+
}
|
|
22
|
+
/** 인용구 — 메타데이터 없음. */
|
|
23
|
+
export interface BlockquoteAttrs {
|
|
24
|
+
}
|
|
25
|
+
/** 코드 블록 — 언어 식별자(syntax highlight 에 사용). */
|
|
26
|
+
export interface CodeBlockAttrs {
|
|
27
|
+
/** 'javascript' / 'python' 등의 언어 식별자. 없으면 plaintext. */
|
|
28
|
+
language?: string;
|
|
29
|
+
}
|
|
30
|
+
/** 이미지 블록(<figure><img>). */
|
|
31
|
+
export interface ImageAttrs {
|
|
32
|
+
src?: string;
|
|
33
|
+
alt?: string;
|
|
34
|
+
/**
|
|
35
|
+
* 그림 아래 설명(`<figcaption>`) 의 **텍스트**.
|
|
36
|
+
*
|
|
37
|
+
* `alt` 와는 다른 값이다 — `alt` 는 그림을 못 보는 사람에게 그림을 대신
|
|
38
|
+
* 설명하는 글이고, 캡션은 보는 사람에게도 함께 읽히는 본문의 일부다
|
|
39
|
+
* (출처 · 촬영 정보 · 부연). 둘을 한 필드로 합치면 어느 쪽도 제 역할을
|
|
40
|
+
* 못 한다.
|
|
41
|
+
*
|
|
42
|
+
* 서식이 들어간 캡션(링크 등) 은 `snapshot.html` 에 그대로 실린다. 이
|
|
43
|
+
* 필드는 `html` 이 비어 있을 때 골격을 조립하기 위한 평문이다.
|
|
44
|
+
*/
|
|
45
|
+
caption?: string;
|
|
46
|
+
/** wrapper(figure) 의 인라인 style — width / margin 등 outer 스타일 보존. */
|
|
47
|
+
wrapperStyle?: string;
|
|
48
|
+
}
|
|
49
|
+
/** 표 블록. 서버 저장 시 행/열 수만 기록 — 실제 cell 컨텐츠는 html 에 담김. */
|
|
50
|
+
export interface TableAttrs {
|
|
51
|
+
rows: number;
|
|
52
|
+
cols: number;
|
|
53
|
+
}
|
|
54
|
+
/** 구분선 — 메타데이터 없음. */
|
|
55
|
+
export interface HrAttrs {
|
|
56
|
+
}
|
|
57
|
+
/** 링크 카드 블록. */
|
|
58
|
+
export interface LinkCardAttrs {
|
|
59
|
+
href?: string;
|
|
60
|
+
/** 제목 / 표시 텍스트. 없으면 href 의 호스트명 사용. */
|
|
61
|
+
text?: string;
|
|
62
|
+
/** 부제 / 설명 (Open Graph description 등). 없으면 표시 안 함. */
|
|
63
|
+
description?: string;
|
|
64
|
+
/** 미리보기 이미지 (og:image 등). data: URL 또는 https URL. */
|
|
65
|
+
image?: string;
|
|
66
|
+
/** 파비콘 URL — 미설정 시 href 의 도메인으로부터 자동 추론. */
|
|
67
|
+
favicon?: string;
|
|
68
|
+
}
|
|
69
|
+
/** 유튜브 임베드 블록. */
|
|
70
|
+
export interface YoutubeAttrs {
|
|
71
|
+
/** YouTube 영상 ID (예: 'dQw4w9WgXcQ'). */
|
|
72
|
+
videoId?: string;
|
|
73
|
+
/** wrapper(div.aw-youtube-embed) 의 인라인 style — width / margin 등. */
|
|
74
|
+
wrapperStyle?: string;
|
|
75
|
+
}
|
|
76
|
+
/** 파일 첨부 블록. */
|
|
77
|
+
export interface FileAttrs {
|
|
78
|
+
/** 다운로드 URL — 외부 URL 또는 업로드 API 응답. */
|
|
79
|
+
fileSrc?: string;
|
|
80
|
+
/** 표시 / download attribute 에 사용할 원본 파일명. */
|
|
81
|
+
fileName?: string;
|
|
82
|
+
/** 바이트 크기. */
|
|
83
|
+
fileSize?: number;
|
|
84
|
+
/** MIME 타입 — 파일명 확장자가 없을 때 메타로 사용. */
|
|
85
|
+
fileType?: string;
|
|
86
|
+
}
|
|
87
|
+
/** 외부 HTML 가져오기로 만들어진 wrapper 블록. */
|
|
88
|
+
export interface ImportedHtmlAttrs {
|
|
89
|
+
/** body 의 computed style 이 베이크된 wrapper 의 인라인 style. */
|
|
90
|
+
importedStyle?: string;
|
|
91
|
+
/** body 에서 복사한 wrapper 의 class 문자열. */
|
|
92
|
+
importedClass?: string;
|
|
93
|
+
}
|
|
94
|
+
/** 어떤 BlockType 에도 매칭되지 않은 element. */
|
|
95
|
+
export interface UnknownAttrs {
|
|
96
|
+
/**
|
|
97
|
+
* 원래 태그명 (소문자).
|
|
98
|
+
*
|
|
99
|
+
* `unknown` 은 미래 버전의 블록이 강등되어 오는 자리다. 태그를 버리면 그
|
|
100
|
+
* 블록을 만든 버전에서 다시 열었을 때도 `<div>` 로 남아 영영 복구되지
|
|
101
|
+
* 않는다. 안전한 컨테이너 태그만 되살린다 ({@link SAFE_UNKNOWN_TAGS}).
|
|
102
|
+
*/
|
|
103
|
+
tag?: string;
|
|
104
|
+
}
|
|
105
|
+
/** BlockKind → 해당 블록의 attrs 타입 매핑. discriminated union 의 기반. */
|
|
106
|
+
export interface BlockAttrsByKind {
|
|
107
|
+
paragraph: ParagraphAttrs;
|
|
108
|
+
heading: HeadingAttrs;
|
|
109
|
+
bulletList: BulletListAttrs;
|
|
110
|
+
orderedList: OrderedListAttrs;
|
|
111
|
+
taskList: TaskListAttrs;
|
|
112
|
+
blockquote: BlockquoteAttrs;
|
|
113
|
+
codeBlock: CodeBlockAttrs;
|
|
114
|
+
image: ImageAttrs;
|
|
115
|
+
table: TableAttrs;
|
|
116
|
+
hr: HrAttrs;
|
|
117
|
+
linkCard: LinkCardAttrs;
|
|
118
|
+
youtube: YoutubeAttrs;
|
|
119
|
+
file: FileAttrs;
|
|
120
|
+
importedHtml: ImportedHtmlAttrs;
|
|
121
|
+
unknown: UnknownAttrs;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 모든 블록 종류의 attrs 를 합친 "느슨한" 인터페이스. 모든 필드가 optional
|
|
125
|
+
* 이라 BlockType.create 같이 kind 를 모르는 시점의 코드도 받을 수 있다.
|
|
126
|
+
* 외부에서 직렬화된 BlockSnapshot 의 attrs 는 BlockAttrsByKind[kind] 로 더
|
|
127
|
+
* 구체적으로 타입이 잡힌다 — 아래 BlockSnapshot 의 discriminated union 참고.
|
|
128
|
+
*/
|
|
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> {
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* BlockType.matches() 의 반환 타입. 내부 사용은 느슨한 BlockAttrs 로 두고,
|
|
133
|
+
* 외부에서 narrow 하고 싶으면 `MatchOf<'image'>` 같은 별칭 사용.
|
|
134
|
+
*/
|
|
135
|
+
export interface BlockMatch {
|
|
136
|
+
kind: BlockKind;
|
|
137
|
+
attrs: BlockAttrs;
|
|
138
|
+
}
|
|
139
|
+
/** 본문에서 발견된 블록의 런타임 표현. element 참조를 포함. */
|
|
140
|
+
export interface Block {
|
|
141
|
+
id: string;
|
|
142
|
+
kind: BlockKind;
|
|
143
|
+
attrs: BlockAttrs;
|
|
144
|
+
element: HTMLElement;
|
|
145
|
+
}
|
|
146
|
+
/** 인라인 서식 마크 식별자. */
|
|
147
|
+
export type InlineMarkName = 'bold' | 'italic' | 'underline' | 'strike';
|
|
148
|
+
export declare const ALL_INLINE_MARKS: ReadonlyArray<InlineMarkName>;
|
|
149
|
+
/**
|
|
150
|
+
* 블록 정의. 같은 kind 의 BlockType 은 1개만 등록한다.
|
|
151
|
+
*/
|
|
152
|
+
export interface BlockType {
|
|
153
|
+
readonly kind: BlockKind;
|
|
154
|
+
readonly label: string;
|
|
155
|
+
/** 인라인 서식(굵게/기울임/...)이 허용되는 블록인지. UI 활성/비활성 판단에 사용. */
|
|
156
|
+
readonly allowsInlineFormat: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* 이 블록 안에서 허용되는 인라인 마크의 화이트리스트.
|
|
159
|
+
* - 빈 배열 = 어떤 인라인 마크도 적용 불가 (codeBlock / image / hr)
|
|
160
|
+
* - allowsInlineFormat=false 인 블록은 [] 가 기본
|
|
161
|
+
*/
|
|
162
|
+
readonly allowedMarks: ReadonlyArray<InlineMarkName>;
|
|
163
|
+
/** 글자색 / 배경색 적용을 허용하는지. heading / blockquote 는 톤 보존을
|
|
164
|
+
* 위해 false. allowsInlineFormat=false 면 의미 없음 — false 로 둘 것. */
|
|
165
|
+
readonly allowsColor: boolean;
|
|
166
|
+
/** 글자 크기 적용을 허용하는지. heading 은 level 로 결정되므로 false.
|
|
167
|
+
* allowsInlineFormat=false 면 의미 없음 — false 로 둘 것. */
|
|
168
|
+
readonly allowsFontSize: boolean;
|
|
169
|
+
/** 본문 직계 자식 element 가 이 type 인지 판별한다. */
|
|
170
|
+
matches(el: HTMLElement): BlockMatch | null;
|
|
171
|
+
/** 빈 인스턴스 element 를 새로 생성한다. */
|
|
172
|
+
create(attrs?: BlockAttrs): HTMLElement;
|
|
173
|
+
/** "비어 있는" 상태인지. 백스페이스 / 포커스 / placeholder 처리에 사용. */
|
|
174
|
+
isEmpty(el: HTMLElement): boolean;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* 본문 직계 자식 element 를 분류할 때 시도되는 순서.
|
|
178
|
+
* 위에서부터 첫 번째로 매칭되는 BlockType 이 채택된다.
|
|
179
|
+
*/
|
|
180
|
+
export declare const BLOCK_TYPES: ReadonlyArray<BlockType>;
|
|
181
|
+
export declare const BLOCK_TYPE_BY_KIND: Readonly<Record<BlockKind, BlockType>>;
|
|
182
|
+
export interface ClassifyResult {
|
|
183
|
+
type: BlockType;
|
|
184
|
+
match: BlockMatch;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 본문 직계 자식 element 를 BLOCK_TYPES 와 순차 매칭해 분류한다.
|
|
188
|
+
* 어디에도 일치하지 않으면 unknown 으로 본다.
|
|
189
|
+
*/
|
|
190
|
+
export declare function classifyBlockElement(el: HTMLElement): ClassifyResult;
|
|
191
|
+
export { BLOCK_ID_ATTR } from './block-meta.cjs';
|
|
192
|
+
export declare class BlockIdRegistry {
|
|
193
|
+
private counter;
|
|
194
|
+
private readonly seen;
|
|
195
|
+
/** 외부에서 관측된 id (HTML 에 이미 있던 값 등) 를 이후 발급 시 회피하도록 등록. */
|
|
196
|
+
observe(id: string): void;
|
|
197
|
+
/** seen 과 충돌하지 않는 새 id 를 발급해 반환. */
|
|
198
|
+
generate(): string;
|
|
199
|
+
/**
|
|
200
|
+
* 단일 element 발급기. data-block-id 가 있으면 등록 후 그대로 반환,
|
|
201
|
+
* 없으면 신규 발급 후 element 에 기록한다. 같은 id 의 중복 element 처리는
|
|
202
|
+
* 이 함수 단독으로는 못 하므로, 본문 전체 정규화는 {@link assignMissingIds}
|
|
203
|
+
* 를 사용해야 한다.
|
|
204
|
+
*/
|
|
205
|
+
ensure(el: HTMLElement): string;
|
|
206
|
+
get(el: HTMLElement): string | null;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* `root` 의 직계 자식 element 들에 고유한 data-block-id 를 보장한다.
|
|
210
|
+
*
|
|
211
|
+
* - id 가 없는 자식 → 신규 발급
|
|
212
|
+
* - 같은 root 안에서 같은 id 가 두 번 이상 나타나면(예: Enter 키로 단락이
|
|
213
|
+
* 분할되며 브라우저가 attribute 를 클론한 경우) 첫 번째 element 만 기존
|
|
214
|
+
* id 를 유지하고, 그 이후에 등장한 element 는 새 id 로 재발급한다.
|
|
215
|
+
*
|
|
216
|
+
* 호출 후 모든 직계 자식이 root 안에서 unique 한 id 를 갖는다.
|
|
217
|
+
*/
|
|
218
|
+
export declare function assignMissingIds(root: HTMLElement, ids: BlockIdRegistry): void;
|
|
219
|
+
/**
|
|
220
|
+
* `root` 의 직계 자식 중 어떤 블록 element 에도 속하지 않은 텍스트 노드를
|
|
221
|
+
* paragraph 블록으로 감싼다. 비어 있는(공백뿐) 텍스트 노드는 제거한다.
|
|
222
|
+
*
|
|
223
|
+
* contentEditable 동작 중 li 분리 / 백스페이스 처리 등으로 본문 직계에
|
|
224
|
+
* "homeless" 텍스트가 생길 수 있는데, 이를 정규화하여 모든 본문 자식이
|
|
225
|
+
* 항상 유효한 블록 element 가 되도록 보장한다.
|
|
226
|
+
*/
|
|
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;
|
|
236
|
+
/**
|
|
237
|
+
* 사람이 읽을 수 있는 블록 라벨. 포커스된 블록 위 태그 표시 등에 사용.
|
|
238
|
+
* 문자열은 현재 로케일(`setLocale`) 사전에서 가져온다.
|
|
239
|
+
*/
|
|
240
|
+
export declare function getBlockLabel(match: BlockMatch): string;
|
|
241
|
+
export type BlockIdResolver = (el: HTMLElement) => string;
|
|
242
|
+
/**
|
|
243
|
+
* 직렬화된 Block 상태. Live element 참조 없이 JSON 으로 저장/전송 가능하다.
|
|
244
|
+
*
|
|
245
|
+
* - version : 스키마 버전. 직렬화 시 항상 {@link SNAPSHOT_VERSION} 이 기록된다.
|
|
246
|
+
* optional 인 이유는 버전 필드 도입(1.0.3) 이전에 저장된 데이터를
|
|
247
|
+
* 그대로 읽을 수 있어야 하기 때문 — 없으면 1 로 간주한다.
|
|
248
|
+
* 변경 정책은 `src/core/snapshot.ts` 의 SNAPSHOT_VERSION 문서 참고.
|
|
249
|
+
* - id : 원본 Block 의 안정 식별자
|
|
250
|
+
* - kind : 블록 유형 (BlockKind 의 string literal)
|
|
251
|
+
* - attrs : kind 에 대응하는 유형별 메타데이터 (BlockAttrsByKind[kind])
|
|
252
|
+
* - html : 블록 element 내부 HTML (인라인 컨텐츠 전체 직렬화)
|
|
253
|
+
* - style : 블록 element **자신**의 인라인 style. `html` 은 내부만 담으므로
|
|
254
|
+
* 정렬(text-align) 처럼 블록에 직접 걸리는 서식은 이 필드가 없으면
|
|
255
|
+
* 스냅샷 왕복에서 사라진다.
|
|
256
|
+
*
|
|
257
|
+
* 서버 라운드트립을 위한 핵심 직렬화 형태. discriminated union 이라
|
|
258
|
+
* `if (snap.kind === 'heading')` 후 `snap.attrs.level` 처럼 바로 narrow 가능.
|
|
259
|
+
*/
|
|
260
|
+
export type BlockSnapshot = {
|
|
261
|
+
[K in BlockKind]: {
|
|
262
|
+
version?: number;
|
|
263
|
+
id: string;
|
|
264
|
+
kind: K;
|
|
265
|
+
attrs: BlockAttrsByKind[K];
|
|
266
|
+
html: string;
|
|
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>;
|
|
275
|
+
};
|
|
276
|
+
}[BlockKind];
|
|
277
|
+
/** 특정 BlockKind 에 한정된 BlockSnapshot 의 별칭. 외부에서 narrow 한
|
|
278
|
+
* 타입을 명시할 때 유용 (예: `Snapshot<'image'>`). */
|
|
279
|
+
export type Snapshot<K extends BlockKind> = Extract<BlockSnapshot, {
|
|
280
|
+
kind: K;
|
|
281
|
+
}>;
|
|
282
|
+
/** 단일 Block 을 직렬화 가능한 BlockSnapshot 으로 변환. */
|
|
283
|
+
export declare function serializeBlock(block: Block): BlockSnapshot;
|
|
284
|
+
/** Block 배열을 BlockSnapshot 배열로 직렬화. */
|
|
285
|
+
export declare function serializeBlocks(blocks: Block[]): BlockSnapshot[];
|
|
286
|
+
/**
|
|
287
|
+
* BlockSnapshot 을 새 element 로 렌더한다.
|
|
288
|
+
* BlockType.create(attrs) 로 골격을 만든 뒤 snapshot.html 로 인라인 컨텐츠를 채운다.
|
|
289
|
+
* 결과 element 는 data-block-id 가 snapshot.id 로 세팅되어 있다.
|
|
290
|
+
*/
|
|
291
|
+
export declare function renderBlock(snapshot: BlockSnapshot): HTMLElement;
|
|
292
|
+
/**
|
|
293
|
+
* BlockSnapshot 배열을 root 의 자식으로 렌더 (root 의 기존 자식은 모두 제거).
|
|
294
|
+
*
|
|
295
|
+
* 저장소에서 바로 읽은 데이터가 들어올 수 있으므로 {@link upgradeSnapshots} 로
|
|
296
|
+
* 스키마를 정규화한 뒤 렌더한다.
|
|
297
|
+
*/
|
|
298
|
+
export declare function renderBlocks(root: HTMLElement, snapshots: readonly BlockSnapshot[]): void;
|
|
299
|
+
/**
|
|
300
|
+
* 본문(`root`) 의 직계 자식 element 들을 순서대로 Block 리스트로 반환한다.
|
|
301
|
+
*/
|
|
302
|
+
export declare function listBlocks(root: HTMLElement, idFor: BlockIdResolver): Block[];
|
|
303
|
+
/**
|
|
304
|
+
* 임의의 노드를 받아 본문(`root`) 직계 자식 element 까지 거슬러 올라간 뒤
|
|
305
|
+
* 해당 element 를 Block 으로 분류해 반환한다. 본문 밖이면 null.
|
|
306
|
+
*/
|
|
307
|
+
export declare function findBlockFrom(node: Node, root: HTMLElement, idFor: BlockIdResolver): Block | null;
|
|
308
|
+
/**
|
|
309
|
+
* 블록의 인라인 컨텐츠(텍스트와 인라인 element 들)를 추출해 반환한다.
|
|
310
|
+
* 블록 유형 변경 시 기존 컨텐츠를 새 블록으로 옮길 때 사용.
|
|
311
|
+
*
|
|
312
|
+
* - paragraph / heading : 직계 자식 노드 전체
|
|
313
|
+
* - bulletList / orderedList : 첫 li 의 자식 노드들
|
|
314
|
+
* - blockquote : 첫 p 의 자식 노드들 (없으면 자기 자식)
|
|
315
|
+
* - codeBlock : 첫 code 의 자식 노드들 (없으면 자기 자식)
|
|
316
|
+
* - image / table / hr / unknown : []
|
|
317
|
+
*/
|
|
318
|
+
export declare function extractInlineContent(block: Block): Node[];
|
|
319
|
+
/**
|
|
320
|
+
* 새로 생성한 블록 element 의 인라인 컨테이너에 노드를 채워 넣는다.
|
|
321
|
+
* 컨텐츠가 비어있으면 기본 placeholder(br)를 그대로 둔다.
|
|
322
|
+
*
|
|
323
|
+
* 새 블록의 `allowedMarks` 에 없는 인라인 마크(bold/italic/underline/strike)
|
|
324
|
+
* 와 — `allowsInlineFormat=false` 인 블록(예: codeBlock)에서는 font/색상까지 —
|
|
325
|
+
* 제거해 "허용된 서식만 유지" 되도록 한다.
|
|
326
|
+
*/
|
|
327
|
+
export declare function fillInlineContent(newEl: HTMLElement, kind: BlockKind, content: Node[]): void;
|
|
328
|
+
/**
|
|
329
|
+
* `getHTML()` 호출 시점에 에디터의 현재 테마(Css 변수)를 읽어 인라인 스타일에
|
|
330
|
+
* 그대로 베이크하기 위한 색 팔레트.
|
|
331
|
+
*
|
|
332
|
+
* 누락된 값은 안전한 기본값(에디터 다크 테마와 동일한 cyan 계열) 으로 폴백한다.
|
|
333
|
+
*/
|
|
334
|
+
export interface BlockStyleTheme {
|
|
335
|
+
primary?: string;
|
|
336
|
+
fg?: string;
|
|
337
|
+
bg?: string;
|
|
338
|
+
border?: string;
|
|
339
|
+
fgMuted?: string;
|
|
340
|
+
/** 'light' / 'dark'. 명시 시 syntax highlight token 색을 그 모드 팔레트로
|
|
341
|
+
* 베이크. 미지정 시 fg/bg lightness 로 자동 추정. */
|
|
342
|
+
mode?: 'light' | 'dark';
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* `getComputedStyle(host)` 에서 에디터 테마 변수(--aw-primary 등) 를 읽어
|
|
346
|
+
* BlockStyleTheme 객체로 반환한다. host 가 DOM 에 붙어 있어야 의미 있는 값.
|
|
347
|
+
*/
|
|
348
|
+
export declare function readBlockStyleTheme(host: Element): BlockStyleTheme;
|
|
349
|
+
/**
|
|
350
|
+
* `root` 트리에 인라인 스타일을 입힌다. (clone 트리에 사용)
|
|
351
|
+
*
|
|
352
|
+
* - 에디터의 현재 테마 색을 `theme` 으로 받아 baked 인라인으로 출력 → 에디터에서
|
|
353
|
+
* 보이는 그대로 외부 컨텍스트에서도 동일하게 보인다.
|
|
354
|
+
* - theme 미지정 시 cyan 계열 기본값으로 폴백.
|
|
355
|
+
*/
|
|
356
|
+
export declare function applyBlockInlineStyles(root: HTMLElement, theme?: BlockStyleTheme): void;
|
|
357
|
+
/** 정렬 값 → 클래스명. `styles: 'class'` 출력에서 text-align 을 대체한다. */
|
|
358
|
+
export declare const ALIGN_CLASS_BY_VALUE: Readonly<Record<string, string>>;
|
|
359
|
+
/**
|
|
360
|
+
* 클래스 기반 출력용 정규화. (`getHTML({ styles: 'class' })` 에서 사용)
|
|
361
|
+
*
|
|
362
|
+
* `style` 속성을 지우는 서버 sanitizer 아래에서도 서식이 살아남게 하는 것이
|
|
363
|
+
* 목적이다. 두 가지를 한다.
|
|
364
|
+
*
|
|
365
|
+
* 1. 본문 직계 블록에 `aw-block` + `aw-block-{kind}` 클래스를 붙인다 — 배포된
|
|
366
|
+
* `aeriz-wysiwyg.min.css` 없이 자체 스타일을 입히려는 소비자의 훅.
|
|
367
|
+
* 2. `text-align` 인라인 선언을 `aw-align-*` 클래스로 옮긴다. 정렬은 값의
|
|
368
|
+
* 가짓수가 네 개로 한정돼 클래스로 완전히 표현되는 유일한 서식이다.
|
|
369
|
+
*
|
|
370
|
+
* 색 · 글자 크기 · 글꼴 · 표 셀 배경은 임의의 값을 갖기 때문에 클래스로 옮길 수
|
|
371
|
+
* 없고 `style` 속성에 남는다. sanitizer 는 `style` 을 통째로 지우는 대신
|
|
372
|
+
* 프로퍼티 단위 허용목록을 쓰면 된다 — 실제로 나오는 프로퍼티 목록은
|
|
373
|
+
* SPEC.md 의 "출력 HTML 허용목록" 절에 확정 명세로 정리돼 있다.
|
|
374
|
+
*/
|
|
375
|
+
export declare function applyBlockClassNames(root: HTMLElement): void;
|
|
376
|
+
/**
|
|
377
|
+
* `aw-align-*` 클래스를 인라인 `text-align` 으로 되돌린다.
|
|
378
|
+
*
|
|
379
|
+
* 정렬의 **내부 표현은 언제나 인라인 style** 이고 클래스는 출력 인코딩일
|
|
380
|
+
* 뿐이라는 불변식을 유지한다. 이 되돌리기가 없으면 class 모드로 저장한 문서를
|
|
381
|
+
* 다시 불러왔을 때
|
|
382
|
+
* - 툴바가 현재 정렬을 알아보지 못하고,
|
|
383
|
+
* - 기본 inline 전략으로 내보낼 때 정렬이 통째로 사라진다
|
|
384
|
+
* (applyBlockInlineStyles 는 클래스를 모른다).
|
|
385
|
+
*
|
|
386
|
+
* 이미 인라인 값이 있으면 그쪽을 우선한다 — 더 구체적인 지정이다.
|
|
387
|
+
*/
|
|
388
|
+
export declare function restoreAlignFromClasses(root: HTMLElement): void;
|
|
389
|
+
/**
|
|
390
|
+
* `getHTML()` 출력에서 편집 보조 element / 속성을 제거한다.
|
|
391
|
+
*
|
|
392
|
+
* 이미지·유튜브 블록의 리사이즈 핸들과 정렬 컨트롤은 에디터 안에서만 의미가
|
|
393
|
+
* 있는 UI 이고, `contenteditable` 도 발행된 문서에서는 불필요하다. 둘 다
|
|
394
|
+
* `normalizeContent()` 가 다시 만들어 주므로 `setHTML(getHTML())` 라운드트립은
|
|
395
|
+
* 그대로 성립한다.
|
|
396
|
+
*/
|
|
397
|
+
export declare function stripEditorOnlyNodes(root: HTMLElement): void;
|
|
398
|
+
/**
|
|
399
|
+
* `getHTML()` 출력에서 에디터 전용 메타데이터 속성을 제거한다.
|
|
400
|
+
* data-block-id 만 보존(외부 반입 시 동일 id 유지에 유용).
|
|
401
|
+
*/
|
|
402
|
+
export declare function stripEditorOnlyAttrs(root: HTMLElement): void;
|
|
403
|
+
/**
|
|
404
|
+
* `el` 시작 위치에 캐럿을 둔다. 컨테이너 블록(UL/OL/BLOCKQUOTE/PRE/TABLE)의
|
|
405
|
+
* 경우 안쪽의 텍스트 컨테이너(li/p/code/td)까지 파고 들어가, 다음 키 입력이
|
|
406
|
+
* 컨테이너 자체가 아닌 안쪽에서 일어나도록 한다. hr 은 컨텐츠가 없으므로 그
|
|
407
|
+
* 뒤에 둔다.
|
|
408
|
+
*/
|
|
409
|
+
export declare function placeCaretAtStart(el: HTMLElement): void;
|
|
410
|
+
export declare function isElementBlank(el: HTMLElement): boolean;
|
|
411
|
+
// (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
|