@aeriz/wysiwyg 1.0.2 → 1.0.3

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.
Files changed (108) hide show
  1. package/README.md +610 -96
  2. package/angular/README.md +112 -0
  3. package/angular/aeriz-editor.directive.ts +243 -0
  4. package/angular/aeriz-wysiwyg.module.ts +14 -0
  5. package/angular/index.ts +5 -0
  6. package/dist/adapters/jquery.cjs +1 -0
  7. package/dist/adapters/jquery.js +91 -0
  8. package/dist/adapters/react.cjs +1 -0
  9. package/dist/adapters/react.js +66 -0
  10. package/dist/adapters/shared.cjs +1 -0
  11. package/dist/adapters/shared.js +87 -0
  12. package/dist/adapters/svelte.cjs +1 -0
  13. package/dist/adapters/svelte.js +29 -0
  14. package/dist/adapters/vue.cjs +1 -0
  15. package/dist/adapters/vue.js +110 -0
  16. package/dist/adapters/vue2.cjs +1 -0
  17. package/dist/adapters/vue2.js +117 -0
  18. package/dist/adapters/wc.cjs +1 -0
  19. package/dist/adapters/wc.js +207 -0
  20. package/dist/aeriz-wysiwyg-adapter.js +169 -0
  21. package/dist/aeriz-wysiwyg-adapter.min.js +1 -0
  22. package/dist/aeriz-wysiwyg-jquery.js +275 -0
  23. package/dist/aeriz-wysiwyg-jquery.min.js +1 -0
  24. package/dist/aeriz-wysiwyg-wc.js +401 -0
  25. package/dist/aeriz-wysiwyg-wc.min.js +1 -0
  26. package/dist/aeriz-wysiwyg.cjs +6912 -0
  27. package/dist/aeriz-wysiwyg.css +37 -129
  28. package/dist/aeriz-wysiwyg.esm.js +1170 -149
  29. package/dist/aeriz-wysiwyg.esm.min.js +2057 -1209
  30. package/dist/aeriz-wysiwyg.js +1169 -148
  31. package/dist/aeriz-wysiwyg.min.cjs +54 -0
  32. package/dist/aeriz-wysiwyg.min.css +1 -1
  33. package/dist/aeriz-wysiwyg.min.js +44 -13
  34. package/dist/server.cjs +32 -0
  35. package/dist/server.js +666 -0
  36. package/dist-types/adapters/jquery.d.ts +34 -0
  37. package/dist-types/adapters/jquery.d.ts.map +1 -0
  38. package/dist-types/adapters/react.d.ts +28 -0
  39. package/dist-types/adapters/react.d.ts.map +1 -0
  40. package/dist-types/adapters/shared.d.ts +83 -0
  41. package/dist-types/adapters/shared.d.ts.map +1 -0
  42. package/dist-types/adapters/svelte.d.ts +38 -0
  43. package/dist-types/adapters/svelte.d.ts.map +1 -0
  44. package/dist-types/adapters/vue.d.ts +189 -0
  45. package/dist-types/adapters/vue.d.ts.map +1 -0
  46. package/dist-types/adapters/vue2.d.ts +175 -0
  47. package/dist-types/adapters/vue2.d.ts.map +1 -0
  48. package/dist-types/adapters/wc.d.ts +96 -0
  49. package/dist-types/adapters/wc.d.ts.map +1 -0
  50. package/dist-types/cjs/adapters/jquery.d.cts +34 -0
  51. package/dist-types/cjs/adapters/react.d.cts +28 -0
  52. package/dist-types/cjs/adapters/shared.d.cts +83 -0
  53. package/dist-types/cjs/adapters/svelte.d.cts +38 -0
  54. package/dist-types/cjs/adapters/vue.d.cts +189 -0
  55. package/dist-types/cjs/adapters/vue2.d.cts +175 -0
  56. package/dist-types/cjs/adapters/wc.d.cts +96 -0
  57. package/dist-types/cjs/core/AerizEditor.d.cts +357 -0
  58. package/dist-types/cjs/core/AerizViewer.d.cts +61 -0
  59. package/dist-types/cjs/core/block-meta.d.cts +32 -0
  60. package/dist-types/cjs/core/blocks.d.cts +368 -0
  61. package/dist-types/cjs/core/fonts.d.cts +60 -0
  62. package/dist-types/cjs/core/highlight.d.cts +44 -0
  63. package/dist-types/cjs/core/html-mini.d.cts +65 -0
  64. package/dist-types/cjs/core/i18n.d.cts +209 -0
  65. package/dist-types/cjs/core/import-html.d.cts +39 -0
  66. package/dist-types/cjs/core/import-markdown.d.cts +37 -0
  67. package/dist-types/cjs/core/markdown-export.d.cts +30 -0
  68. package/dist-types/cjs/core/plain-text.d.cts +17 -0
  69. package/dist-types/cjs/core/render-string.d.cts +68 -0
  70. package/dist-types/cjs/core/snapshot.d.cts +51 -0
  71. package/dist-types/cjs/index.d.cts +20 -0
  72. package/dist-types/cjs/server/index.d.cts +37 -0
  73. package/dist-types/cjs/types/index.d.cts +61 -0
  74. package/dist-types/cjs/ui/Toolbar.d.cts +21 -0
  75. package/dist-types/cjs/ui/dialogs.d.cts +74 -0
  76. package/dist-types/cjs/ui/icons.d.cts +2 -0
  77. package/dist-types/cjs/ui/popovers.d.cts +70 -0
  78. package/dist-types/core/AerizEditor.d.ts +30 -10
  79. package/dist-types/core/AerizEditor.d.ts.map +1 -1
  80. package/dist-types/core/AerizViewer.d.ts +16 -4
  81. package/dist-types/core/AerizViewer.d.ts.map +1 -1
  82. package/dist-types/core/block-meta.d.ts +32 -0
  83. package/dist-types/core/block-meta.d.ts.map +1 -0
  84. package/dist-types/core/blocks.d.ts +62 -7
  85. package/dist-types/core/blocks.d.ts.map +1 -1
  86. package/dist-types/core/fonts.d.ts +11 -0
  87. package/dist-types/core/fonts.d.ts.map +1 -1
  88. package/dist-types/core/html-mini.d.ts +65 -0
  89. package/dist-types/core/html-mini.d.ts.map +1 -0
  90. package/dist-types/core/import-html.d.ts.map +1 -1
  91. package/dist-types/core/markdown-export.d.ts +30 -0
  92. package/dist-types/core/markdown-export.d.ts.map +1 -0
  93. package/dist-types/core/plain-text.d.ts +17 -0
  94. package/dist-types/core/plain-text.d.ts.map +1 -0
  95. package/dist-types/core/render-string.d.ts +68 -0
  96. package/dist-types/core/render-string.d.ts.map +1 -0
  97. package/dist-types/core/snapshot.d.ts +51 -0
  98. package/dist-types/core/snapshot.d.ts.map +1 -0
  99. package/dist-types/index.d.ts +19 -10
  100. package/dist-types/index.d.ts.map +1 -1
  101. package/dist-types/server/index.d.ts +37 -0
  102. package/dist-types/server/index.d.ts.map +1 -0
  103. package/dist-types/types/index.d.ts +21 -0
  104. package/dist-types/types/index.d.ts.map +1 -1
  105. package/dist-types/ui/Toolbar.d.ts +1 -1
  106. package/dist-types/ui/popovers.d.ts +1 -1
  107. package/dist-types/ui/popovers.d.ts.map +1 -1
  108. package/package.json +213 -58
@@ -0,0 +1,368 @@
1
+ export type BlockKind = 'paragraph' | 'heading' | 'bulletList' | 'orderedList' | '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
+ export interface BlockquoteAttrs {
18
+ }
19
+ /** 코드 블록 — 언어 식별자(syntax highlight 에 사용). */
20
+ export interface CodeBlockAttrs {
21
+ /** 'javascript' / 'python' 등의 언어 식별자. 없으면 plaintext. */
22
+ language?: string;
23
+ }
24
+ /** 이미지 블록(<figure><img>). */
25
+ export interface ImageAttrs {
26
+ src?: string;
27
+ alt?: string;
28
+ /** wrapper(figure) 의 인라인 style — width / margin 등 outer 스타일 보존. */
29
+ wrapperStyle?: string;
30
+ }
31
+ /** 표 블록. 서버 저장 시 행/열 수만 기록 — 실제 cell 컨텐츠는 html 에 담김. */
32
+ export interface TableAttrs {
33
+ rows: number;
34
+ cols: number;
35
+ }
36
+ /** 구분선 — 메타데이터 없음. */
37
+ export interface HrAttrs {
38
+ }
39
+ /** 링크 카드 블록. */
40
+ export interface LinkCardAttrs {
41
+ href?: string;
42
+ /** 제목 / 표시 텍스트. 없으면 href 의 호스트명 사용. */
43
+ text?: string;
44
+ /** 부제 / 설명 (Open Graph description 등). 없으면 표시 안 함. */
45
+ description?: string;
46
+ /** 미리보기 이미지 (og:image 등). data: URL 또는 https URL. */
47
+ image?: string;
48
+ /** 파비콘 URL — 미설정 시 href 의 도메인으로부터 자동 추론. */
49
+ favicon?: string;
50
+ }
51
+ /** 유튜브 임베드 블록. */
52
+ export interface YoutubeAttrs {
53
+ /** YouTube 영상 ID (예: 'dQw4w9WgXcQ'). */
54
+ videoId?: string;
55
+ /** wrapper(div.aw-youtube-embed) 의 인라인 style — width / margin 등. */
56
+ wrapperStyle?: string;
57
+ }
58
+ /** 파일 첨부 블록. */
59
+ export interface FileAttrs {
60
+ /** 다운로드 URL — 외부 URL 또는 업로드 API 응답. */
61
+ fileSrc?: string;
62
+ /** 표시 / download attribute 에 사용할 원본 파일명. */
63
+ fileName?: string;
64
+ /** 바이트 크기. */
65
+ fileSize?: number;
66
+ /** MIME 타입 — 파일명 확장자가 없을 때 메타로 사용. */
67
+ fileType?: string;
68
+ }
69
+ /** 외부 HTML 가져오기로 만들어진 wrapper 블록. */
70
+ export interface ImportedHtmlAttrs {
71
+ /** body 의 computed style 이 베이크된 wrapper 의 인라인 style. */
72
+ importedStyle?: string;
73
+ /** body 에서 복사한 wrapper 의 class 문자열. */
74
+ importedClass?: string;
75
+ }
76
+ /** 어떤 BlockType 에도 매칭되지 않은 element. */
77
+ export interface UnknownAttrs {
78
+ }
79
+ /** BlockKind → 해당 블록의 attrs 타입 매핑. discriminated union 의 기반. */
80
+ export interface BlockAttrsByKind {
81
+ paragraph: ParagraphAttrs;
82
+ heading: HeadingAttrs;
83
+ bulletList: BulletListAttrs;
84
+ orderedList: OrderedListAttrs;
85
+ blockquote: BlockquoteAttrs;
86
+ codeBlock: CodeBlockAttrs;
87
+ image: ImageAttrs;
88
+ table: TableAttrs;
89
+ hr: HrAttrs;
90
+ linkCard: LinkCardAttrs;
91
+ youtube: YoutubeAttrs;
92
+ file: FileAttrs;
93
+ importedHtml: ImportedHtmlAttrs;
94
+ unknown: UnknownAttrs;
95
+ }
96
+ /**
97
+ * 모든 블록 종류의 attrs 를 합친 "느슨한" 인터페이스. 모든 필드가 optional
98
+ * 이라 BlockType.create 같이 kind 를 모르는 시점의 코드도 받을 수 있다.
99
+ * 외부에서 직렬화된 BlockSnapshot 의 attrs 는 BlockAttrsByKind[kind] 로 더
100
+ * 구체적으로 타입이 잡힌다 — 아래 BlockSnapshot 의 discriminated union 참고.
101
+ */
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> {
103
+ }
104
+ /**
105
+ * BlockType.matches() 의 반환 타입. 내부 사용은 느슨한 BlockAttrs 로 두고,
106
+ * 외부에서 narrow 하고 싶으면 `MatchOf<'image'>` 같은 별칭 사용.
107
+ */
108
+ export interface BlockMatch {
109
+ kind: BlockKind;
110
+ attrs: BlockAttrs;
111
+ }
112
+ /** 본문에서 발견된 블록의 런타임 표현. element 참조를 포함. */
113
+ export interface Block {
114
+ id: string;
115
+ kind: BlockKind;
116
+ attrs: BlockAttrs;
117
+ element: HTMLElement;
118
+ }
119
+ /** 인라인 서식 마크 식별자. */
120
+ export type InlineMarkName = 'bold' | 'italic' | 'underline' | 'strike';
121
+ export declare const ALL_INLINE_MARKS: ReadonlyArray<InlineMarkName>;
122
+ /**
123
+ * 블록 정의. 같은 kind 의 BlockType 은 1개만 등록한다.
124
+ */
125
+ export interface BlockType {
126
+ readonly kind: BlockKind;
127
+ readonly label: string;
128
+ /** 인라인 서식(굵게/기울임/...)이 허용되는 블록인지. UI 활성/비활성 판단에 사용. */
129
+ readonly allowsInlineFormat: boolean;
130
+ /**
131
+ * 이 블록 안에서 허용되는 인라인 마크의 화이트리스트.
132
+ * - 빈 배열 = 어떤 인라인 마크도 적용 불가 (codeBlock / image / hr)
133
+ * - allowsInlineFormat=false 인 블록은 [] 가 기본
134
+ */
135
+ readonly allowedMarks: ReadonlyArray<InlineMarkName>;
136
+ /** 글자색 / 배경색 적용을 허용하는지. heading / blockquote 는 톤 보존을
137
+ * 위해 false. allowsInlineFormat=false 면 의미 없음 — false 로 둘 것. */
138
+ readonly allowsColor: boolean;
139
+ /** 글자 크기 적용을 허용하는지. heading 은 level 로 결정되므로 false.
140
+ * allowsInlineFormat=false 면 의미 없음 — false 로 둘 것. */
141
+ readonly allowsFontSize: boolean;
142
+ /** 본문 직계 자식 element 가 이 type 인지 판별한다. */
143
+ matches(el: HTMLElement): BlockMatch | null;
144
+ /** 빈 인스턴스 element 를 새로 생성한다. */
145
+ create(attrs?: BlockAttrs): HTMLElement;
146
+ /** "비어 있는" 상태인지. 백스페이스 / 포커스 / placeholder 처리에 사용. */
147
+ isEmpty(el: HTMLElement): boolean;
148
+ }
149
+ /**
150
+ * 본문 직계 자식 element 를 분류할 때 시도되는 순서.
151
+ * 위에서부터 첫 번째로 매칭되는 BlockType 이 채택된다.
152
+ */
153
+ export declare const BLOCK_TYPES: ReadonlyArray<BlockType>;
154
+ export declare const BLOCK_TYPE_BY_KIND: Readonly<Record<BlockKind, BlockType>>;
155
+ export interface ClassifyResult {
156
+ type: BlockType;
157
+ match: BlockMatch;
158
+ }
159
+ /**
160
+ * 본문 직계 자식 element 를 BLOCK_TYPES 와 순차 매칭해 분류한다.
161
+ * 어디에도 일치하지 않으면 unknown 으로 본다.
162
+ */
163
+ export declare function classifyBlockElement(el: HTMLElement): ClassifyResult;
164
+ export { BLOCK_ID_ATTR } from './block-meta.cjs';
165
+ export declare class BlockIdRegistry {
166
+ private counter;
167
+ private readonly seen;
168
+ /** 외부에서 관측된 id (HTML 에 이미 있던 값 등) 를 이후 발급 시 회피하도록 등록. */
169
+ observe(id: string): void;
170
+ /** seen 과 충돌하지 않는 새 id 를 발급해 반환. */
171
+ generate(): string;
172
+ /**
173
+ * 단일 element 발급기. data-block-id 가 있으면 등록 후 그대로 반환,
174
+ * 없으면 신규 발급 후 element 에 기록한다. 같은 id 의 중복 element 처리는
175
+ * 이 함수 단독으로는 못 하므로, 본문 전체 정규화는 {@link assignMissingIds}
176
+ * 를 사용해야 한다.
177
+ */
178
+ ensure(el: HTMLElement): string;
179
+ get(el: HTMLElement): string | null;
180
+ }
181
+ /**
182
+ * `root` 의 직계 자식 element 들에 고유한 data-block-id 를 보장한다.
183
+ *
184
+ * - id 가 없는 자식 → 신규 발급
185
+ * - 같은 root 안에서 같은 id 가 두 번 이상 나타나면(예: Enter 키로 단락이
186
+ * 분할되며 브라우저가 attribute 를 클론한 경우) 첫 번째 element 만 기존
187
+ * id 를 유지하고, 그 이후에 등장한 element 는 새 id 로 재발급한다.
188
+ *
189
+ * 호출 후 모든 직계 자식이 root 안에서 unique 한 id 를 갖는다.
190
+ */
191
+ export declare function assignMissingIds(root: HTMLElement, ids: BlockIdRegistry): void;
192
+ /**
193
+ * `root` 의 직계 자식 중 어떤 블록 element 에도 속하지 않은 텍스트 노드를
194
+ * paragraph 블록으로 감싼다. 비어 있는(공백뿐) 텍스트 노드는 제거한다.
195
+ *
196
+ * contentEditable 동작 중 li 분리 / 백스페이스 처리 등으로 본문 직계에
197
+ * "homeless" 텍스트가 생길 수 있는데, 이를 정규화하여 모든 본문 자식이
198
+ * 항상 유효한 블록 element 가 되도록 보장한다.
199
+ */
200
+ export declare function normalizeContent(root: HTMLElement): void;
201
+ /**
202
+ * 사람이 읽을 수 있는 한국어 라벨. 포커스된 블록 위 태그 표시 등에 사용.
203
+ */
204
+ export declare function getBlockLabel(match: BlockMatch): string;
205
+ export type BlockIdResolver = (el: HTMLElement) => string;
206
+ /**
207
+ * 직렬화된 Block 상태. Live element 참조 없이 JSON 으로 저장/전송 가능하다.
208
+ *
209
+ * - version : 스키마 버전. 직렬화 시 항상 {@link SNAPSHOT_VERSION} 이 기록된다.
210
+ * optional 인 이유는 버전 필드 도입(1.0.3) 이전에 저장된 데이터를
211
+ * 그대로 읽을 수 있어야 하기 때문 — 없으면 1 로 간주한다.
212
+ * 변경 정책은 `src/core/snapshot.ts` 의 SNAPSHOT_VERSION 문서 참고.
213
+ * - id : 원본 Block 의 안정 식별자
214
+ * - kind : 블록 유형 (BlockKind 의 string literal)
215
+ * - attrs : kind 에 대응하는 유형별 메타데이터 (BlockAttrsByKind[kind])
216
+ * - html : 블록 element 내부 HTML (인라인 컨텐츠 전체 직렬화)
217
+ * - style : 블록 element **자신**의 인라인 style. `html` 은 내부만 담으므로
218
+ * 정렬(text-align) 처럼 블록에 직접 걸리는 서식은 이 필드가 없으면
219
+ * 스냅샷 왕복에서 사라진다.
220
+ *
221
+ * 서버 라운드트립을 위한 핵심 직렬화 형태. discriminated union 이라
222
+ * `if (snap.kind === 'heading')` 후 `snap.attrs.level` 처럼 바로 narrow 가능.
223
+ */
224
+ export type BlockSnapshot = {
225
+ [K in BlockKind]: {
226
+ version?: number;
227
+ id: string;
228
+ kind: K;
229
+ attrs: BlockAttrsByKind[K];
230
+ html: string;
231
+ style?: string;
232
+ };
233
+ }[BlockKind];
234
+ /** 특정 BlockKind 에 한정된 BlockSnapshot 의 별칭. 외부에서 narrow 한
235
+ * 타입을 명시할 때 유용 (예: `Snapshot<'image'>`). */
236
+ export type Snapshot<K extends BlockKind> = Extract<BlockSnapshot, {
237
+ kind: K;
238
+ }>;
239
+ /** 단일 Block 을 직렬화 가능한 BlockSnapshot 으로 변환. */
240
+ export declare function serializeBlock(block: Block): BlockSnapshot;
241
+ /** Block 배열을 BlockSnapshot 배열로 직렬화. */
242
+ export declare function serializeBlocks(blocks: Block[]): BlockSnapshot[];
243
+ /**
244
+ * BlockSnapshot 을 새 element 로 렌더한다.
245
+ * BlockType.create(attrs) 로 골격을 만든 뒤 snapshot.html 로 인라인 컨텐츠를 채운다.
246
+ * 결과 element 는 data-block-id 가 snapshot.id 로 세팅되어 있다.
247
+ */
248
+ export declare function renderBlock(snapshot: BlockSnapshot): HTMLElement;
249
+ /**
250
+ * BlockSnapshot 배열을 root 의 자식으로 렌더 (root 의 기존 자식은 모두 제거).
251
+ *
252
+ * 저장소에서 바로 읽은 데이터가 들어올 수 있으므로 {@link upgradeSnapshots} 로
253
+ * 스키마를 정규화한 뒤 렌더한다.
254
+ */
255
+ export declare function renderBlocks(root: HTMLElement, snapshots: readonly BlockSnapshot[]): void;
256
+ /**
257
+ * 본문(`root`) 의 직계 자식 element 들을 순서대로 Block 리스트로 반환한다.
258
+ */
259
+ export declare function listBlocks(root: HTMLElement, idFor: BlockIdResolver): Block[];
260
+ /**
261
+ * 임의의 노드를 받아 본문(`root`) 직계 자식 element 까지 거슬러 올라간 뒤
262
+ * 해당 element 를 Block 으로 분류해 반환한다. 본문 밖이면 null.
263
+ */
264
+ export declare function findBlockFrom(node: Node, root: HTMLElement, idFor: BlockIdResolver): Block | null;
265
+ /**
266
+ * 블록의 인라인 컨텐츠(텍스트와 인라인 element 들)를 추출해 반환한다.
267
+ * 블록 유형 변경 시 기존 컨텐츠를 새 블록으로 옮길 때 사용.
268
+ *
269
+ * - paragraph / heading : 직계 자식 노드 전체
270
+ * - bulletList / orderedList : 첫 li 의 자식 노드들
271
+ * - blockquote : 첫 p 의 자식 노드들 (없으면 자기 자식)
272
+ * - codeBlock : 첫 code 의 자식 노드들 (없으면 자기 자식)
273
+ * - image / table / hr / unknown : []
274
+ */
275
+ export declare function extractInlineContent(block: Block): Node[];
276
+ /**
277
+ * 새로 생성한 블록 element 의 인라인 컨테이너에 노드를 채워 넣는다.
278
+ * 컨텐츠가 비어있으면 기본 placeholder(br)를 그대로 둔다.
279
+ *
280
+ * 새 블록의 `allowedMarks` 에 없는 인라인 마크(bold/italic/underline/strike)
281
+ * 와 — `allowsInlineFormat=false` 인 블록(예: codeBlock)에서는 font/색상까지 —
282
+ * 제거해 "허용된 서식만 유지" 되도록 한다.
283
+ */
284
+ export declare function fillInlineContent(newEl: HTMLElement, kind: BlockKind, content: Node[]): void;
285
+ /**
286
+ * `getHTML()` 호출 시점에 에디터의 현재 테마(Css 변수)를 읽어 인라인 스타일에
287
+ * 그대로 베이크하기 위한 색 팔레트.
288
+ *
289
+ * 누락된 값은 안전한 기본값(에디터 다크 테마와 동일한 cyan 계열) 으로 폴백한다.
290
+ */
291
+ export interface BlockStyleTheme {
292
+ primary?: string;
293
+ fg?: string;
294
+ bg?: string;
295
+ border?: string;
296
+ fgMuted?: string;
297
+ /** 'light' / 'dark'. 명시 시 syntax highlight token 색을 그 모드 팔레트로
298
+ * 베이크. 미지정 시 fg/bg lightness 로 자동 추정. */
299
+ mode?: 'light' | 'dark';
300
+ }
301
+ /**
302
+ * `getComputedStyle(host)` 에서 에디터 테마 변수(--aw-primary 등) 를 읽어
303
+ * BlockStyleTheme 객체로 반환한다. host 가 DOM 에 붙어 있어야 의미 있는 값.
304
+ */
305
+ export declare function readBlockStyleTheme(host: Element): BlockStyleTheme;
306
+ /**
307
+ * `root` 트리에 인라인 스타일을 입힌다. (clone 트리에 사용)
308
+ *
309
+ * - 에디터의 현재 테마 색을 `theme` 으로 받아 baked 인라인으로 출력 → 에디터에서
310
+ * 보이는 그대로 외부 컨텍스트에서도 동일하게 보인다.
311
+ * - theme 미지정 시 cyan 계열 기본값으로 폴백.
312
+ */
313
+ export declare function applyBlockInlineStyles(root: HTMLElement, theme?: BlockStyleTheme): void;
314
+ /** 정렬 값 → 클래스명. `styles: 'class'` 출력에서 text-align 을 대체한다. */
315
+ export declare const ALIGN_CLASS_BY_VALUE: Readonly<Record<string, string>>;
316
+ /**
317
+ * 클래스 기반 출력용 정규화. (`getHTML({ styles: 'class' })` 에서 사용)
318
+ *
319
+ * `style` 속성을 지우는 서버 sanitizer 아래에서도 서식이 살아남게 하는 것이
320
+ * 목적이다. 두 가지를 한다.
321
+ *
322
+ * 1. 본문 직계 블록에 `aw-block` + `aw-block-{kind}` 클래스를 붙인다 — 배포된
323
+ * `aeriz-wysiwyg.min.css` 없이 자체 스타일을 입히려는 소비자의 훅.
324
+ * 2. `text-align` 인라인 선언을 `aw-align-*` 클래스로 옮긴다. 정렬은 값의
325
+ * 가짓수가 네 개로 한정돼 클래스로 완전히 표현되는 유일한 서식이다.
326
+ *
327
+ * 색 · 글자 크기 · 글꼴 · 표 셀 배경은 임의의 값을 갖기 때문에 클래스로 옮길 수
328
+ * 없고 `style` 속성에 남는다. sanitizer 는 `style` 을 통째로 지우는 대신
329
+ * 프로퍼티 단위 허용목록을 쓰면 된다 — 실제로 나오는 프로퍼티 목록은
330
+ * SPEC.md 의 "출력 HTML 허용목록" 절에 확정 명세로 정리돼 있다.
331
+ */
332
+ export declare function applyBlockClassNames(root: HTMLElement): void;
333
+ /**
334
+ * `aw-align-*` 클래스를 인라인 `text-align` 으로 되돌린다.
335
+ *
336
+ * 정렬의 **내부 표현은 언제나 인라인 style** 이고 클래스는 출력 인코딩일
337
+ * 뿐이라는 불변식을 유지한다. 이 되돌리기가 없으면 class 모드로 저장한 문서를
338
+ * 다시 불러왔을 때
339
+ * - 툴바가 현재 정렬을 알아보지 못하고,
340
+ * - 기본 inline 전략으로 내보낼 때 정렬이 통째로 사라진다
341
+ * (applyBlockInlineStyles 는 클래스를 모른다).
342
+ *
343
+ * 이미 인라인 값이 있으면 그쪽을 우선한다 — 더 구체적인 지정이다.
344
+ */
345
+ export declare function restoreAlignFromClasses(root: HTMLElement): void;
346
+ /**
347
+ * `getHTML()` 출력에서 편집 보조 element / 속성을 제거한다.
348
+ *
349
+ * 이미지·유튜브 블록의 리사이즈 핸들과 정렬 컨트롤은 에디터 안에서만 의미가
350
+ * 있는 UI 이고, `contenteditable` 도 발행된 문서에서는 불필요하다. 둘 다
351
+ * `normalizeContent()` 가 다시 만들어 주므로 `setHTML(getHTML())` 라운드트립은
352
+ * 그대로 성립한다.
353
+ */
354
+ export declare function stripEditorOnlyNodes(root: HTMLElement): void;
355
+ /**
356
+ * `getHTML()` 출력에서 에디터 전용 메타데이터 속성을 제거한다.
357
+ * data-block-id 만 보존(외부 반입 시 동일 id 유지에 유용).
358
+ */
359
+ export declare function stripEditorOnlyAttrs(root: HTMLElement): void;
360
+ /**
361
+ * `el` 시작 위치에 캐럿을 둔다. 컨테이너 블록(UL/OL/BLOCKQUOTE/PRE/TABLE)의
362
+ * 경우 안쪽의 텍스트 컨테이너(li/p/code/td)까지 파고 들어가, 다음 키 입력이
363
+ * 컨테이너 자체가 아닌 안쪽에서 일어나도록 한다. hr 은 컨텐츠가 없으므로 그
364
+ * 뒤에 둔다.
365
+ */
366
+ export declare function placeCaretAtStart(el: HTMLElement): void;
367
+ export declare function isElementBlank(el: HTMLElement): boolean;
368
+ // (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
@@ -0,0 +1,60 @@
1
+ /**
2
+ * 글꼴 라이브러리 — 한국어 본문에 친화적인 무료 / 상용 가능 글꼴만 큐레이션.
3
+ * 모두 SIL Open Font License 또는 자체 무제한 상용 라이선스.
4
+ *
5
+ * 로딩 정책:
6
+ * - 모든 글꼴은 글꼴 드롭다운이 처음 열릴 때 1회 일괄 lazy 로드.
7
+ * - Google Fonts CSS2 endpoint 한 번 + 외부 CDN(Pretendard) 별도 1 회.
8
+ * - 실패해도 stack 의 fallback 글꼴이 자동 적용되므로 graceful degradation.
9
+ */
10
+ export interface FontFamily {
11
+ /** 안정 식별자 — 직렬화 / 다음 선택 비교에 사용. */
12
+ id: string;
13
+ /** 드롭다운에 표시되는 한국어 라벨. */
14
+ label: string;
15
+ /** CSS font-family 스택 — execCommand fontName 의 인자로 들어간다. */
16
+ stack: string;
17
+ /** Google Fonts CSS2 family 파라미터 (예: "Noto+Sans+KR:wght@400;700"). */
18
+ googleFonts?: string;
19
+ /** 외부 CDN 의 전체 CSS URL (Google Fonts 가 아닌 글꼴용). */
20
+ cssUrl?: string;
21
+ }
22
+ /** "시스템 기본" 항목의 id. clearFormat / 초기화 분기에 사용. */
23
+ export declare const SYSTEM_FONT_ID = "system";
24
+ export declare const FONT_FAMILIES: ReadonlyArray<FontFamily>;
25
+ /** id → FontFamily lookup. */
26
+ export declare const FONT_FAMILY_BY_ID: Readonly<Record<string, FontFamily>>;
27
+ /**
28
+ * 글자 크기 프리셋 (px). 본문 기본은 16px.
29
+ * 12 ~ 48px 범위에서 자주 쓰이는 단계만 큐레이션.
30
+ */
31
+ export declare const FONT_SIZES: ReadonlyArray<number>;
32
+ /**
33
+ * Computed CSS font-size 문자열(예: "16px", "1.125rem")을 px 정수로 변환.
34
+ * 매칭 실패 시 null. 활성 toolbar 크기 표시에 사용.
35
+ */
36
+ export declare function pxFromCss(css: string | null | undefined): number | null;
37
+ /**
38
+ * 현재 실제로 쓸 수 있는 글꼴만 반환한다. 드롭다운은 이 목록으로 그린다.
39
+ *
40
+ * `FONT_FAMILIES` 전체는 그대로 남겨 둔다 — 이미 그 글꼴로 저장된 본문의
41
+ * 라벨을 표시하려면(`findFontIdFromCss`) 실패한 항목도 알고 있어야 한다.
42
+ */
43
+ export declare function getAvailableFontFamilies(): ReadonlyArray<FontFamily>;
44
+ /** 사용 가능 목록이 바뀌면 호출된다. 반환값을 부르면 구독이 해제된다. */
45
+ export declare function subscribeFontAvailability(listener: () => void): () => void;
46
+ /**
47
+ * 모든 글꼴의 CSS 를 1 회만 lazy 로드한다. 글꼴 드롭다운이 열릴 때 호출.
48
+ * 두 번째 이후 호출은 즉시 반환.
49
+ *
50
+ * 실패는 조용히 넘어가지 않는다 — 받지 못한 글꼴은 목록에서 빠진다.
51
+ */
52
+ export declare function ensureFontFamiliesLoaded(): void;
53
+ /**
54
+ * 임의의 CSS font-family 문자열에 대해 FONT_FAMILIES 중 가장 비슷한 항목을
55
+ * 찾아 id 를 반환. 매칭 실패 시 null. 활성 toolbar 표시에 사용.
56
+ *
57
+ * 비교는 stack 의 첫 family 토큰을 추출해 case-insensitive 비교.
58
+ */
59
+ export declare function findFontIdFromCss(css: string | null | undefined): string | null;
60
+ // (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
@@ -0,0 +1,44 @@
1
+ /**
2
+ * 가벼운 자체 syntax highlighter — 외부 의존성 없음.
3
+ *
4
+ * 단일 generic tokenizer 가 LanguageDef 의 룰(keywords / comments / strings /
5
+ * builtins) 을 받아 동작. 결과는 `<span class="hl-…">` 으로 wrap 된 HTML
6
+ * 문자열로 반환되며, AerizEditor 가 codeBlock 의 innerHTML 로 적용한다.
7
+ *
8
+ * 지원 언어: 15 종 — JavaScript / TypeScript / Python / JSON / HTML / CSS /
9
+ * Bash / SQL / Markdown / C / C++ / C# / Java / Kotlin / Go / Rust.
10
+ *
11
+ * 정확도 목표: 일반적인 코드 80% 케이스. 100% 정확한 파서가 아니므로 corner
12
+ * case (예: regex 리터럴 vs 나누기 연산자, 템플릿 문자열의 ${…} 내부 표현식)
13
+ * 는 단순화되어 있다.
14
+ */
15
+ export interface LanguageDef {
16
+ /** 안정 식별자 — `data-language` 속성에 저장되는 값. */
17
+ id: string;
18
+ /** UI 드롭다운에 표시되는 라벨. */
19
+ label: string;
20
+ /** 키워드 집합. 이 단어로 매칭되면 hl-keyword 로 wrap. */
21
+ keywords: ReadonlySet<string>;
22
+ /** 빌트인 / 라이브러리 함수. hl-builtin. */
23
+ builtins?: ReadonlySet<string>;
24
+ /** 라인 주석 prefix (예: '//'). */
25
+ lineComment?: string;
26
+ /** 블록 주석. */
27
+ blockComment?: {
28
+ start: string;
29
+ end: string;
30
+ };
31
+ /** 문자열 구분자 목록. 일반적으로 ['"', "'"], JS 는 백틱 추가. */
32
+ stringDelims?: ReadonlyArray<string>;
33
+ /** 키워드 매칭 시 case-insensitive (SQL 용). */
34
+ caseInsensitiveKeywords?: boolean;
35
+ /** HTML / CSS 등 특수 처리가 필요한 언어. 자체 토크나이저 사용. */
36
+ custom?: (code: string) => string;
37
+ }
38
+ export declare const LANGUAGES: ReadonlyArray<LanguageDef>;
39
+ /**
40
+ * 코드 문자열을 언어 식별자에 따라 highlight HTML 로 변환.
41
+ * 알 수 없는 언어 또는 'plaintext' 면 escape 만 적용.
42
+ */
43
+ export declare function highlightCode(code: string, langId: string | undefined): string;
44
+ // (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)
@@ -0,0 +1,65 @@
1
+ /**
2
+ * DOM 없이 동작하는 최소 HTML 파서.
3
+ *
4
+ * `blocksToMarkdown` / `blocksToPlainText` 가 `snapshot.html` 의 인라인
5
+ * 컨텐츠를 해석하기 위해 쓴다. `document` 를 쓸 수 없는 런타임(workerd, Node,
6
+ * Deno) 에서 돌아야 하므로 브라우저 파서를 쓸 수 없다.
7
+ *
8
+ * 범위를 의도적으로 좁게 잡았다 — 에디터가 만든 인라인 마크업과, HTML 가져오기
9
+ * 로 들어온 정도의 일반적인 마크업을 다루는 것이 목표이며, 브라우저 HTML5
10
+ * 파싱 알고리즘의 완전한 재현은 목표가 아니다. 아래 두 가지만 보장한다.
11
+ *
12
+ * 1. 어떤 입력에도 예외를 던지지 않는다 (깨진 마크업은 최선 해석 후 통과).
13
+ * 2. `<script>` / `<style>` 의 내용은 결과 트리에 남기지 않는다.
14
+ */
15
+ export interface HtmlText {
16
+ type: 'text';
17
+ value: string;
18
+ }
19
+ export interface HtmlElementNode {
20
+ type: 'element';
21
+ /** 소문자 태그명. */
22
+ tag: string;
23
+ /** 소문자 속성명 → 값. 엔티티가 해제된 상태. */
24
+ attrs: Readonly<Record<string, string>>;
25
+ children: HtmlNode[];
26
+ }
27
+ export type HtmlNode = HtmlText | HtmlElementNode;
28
+ /** HTML 엔티티를 문자로 되돌린다. 해석할 수 없는 참조는 원문 유지. */
29
+ export declare function decodeEntities(input: string): string;
30
+ /** 텍스트를 HTML 본문에 넣을 수 있게 이스케이프한다. */
31
+ export declare function escapeHtml(input: string): string;
32
+ /** 텍스트를 큰따옴표 속성값으로 넣을 수 있게 이스케이프한다. */
33
+ export declare function escapeAttr(input: string): string;
34
+ /**
35
+ * HTML 조각을 노드 트리로 파싱한다.
36
+ *
37
+ * 텍스트 노드의 값은 엔티티가 해제된 상태로 들어온다.
38
+ */
39
+ export declare function parseHtmlFragment(html: string): HtmlNode[];
40
+ /** 노드 트리를 HTML 문자열로 되돌린다. 파싱 → 직렬화는 정규화 역할을 한다. */
41
+ export declare function serializeNodes(nodes: readonly HtmlNode[]): string;
42
+ /**
43
+ * 노드 트리의 텍스트만 이어붙인다. `<br>` 은 개행으로 바꾼다.
44
+ *
45
+ * 블록 경계는 무시한다 — 코드 블록처럼 원문 그대로가 필요한 곳에서 쓴다.
46
+ * 사람이 읽는 텍스트를 뽑을 때는 {@link textWithBlockBreaks} 를 쓸 것.
47
+ */
48
+ export declare function textOf(nodes: readonly HtmlNode[]): string;
49
+ /**
50
+ * 텍스트를 뽑되 블록 경계에 개행을 넣는다.
51
+ *
52
+ * `textOf` 만으로는 `<p>첫 문장</p><p>둘째 문장</p>` 이
53
+ * `"첫 문장둘째 문장"` 이 되어 버린다. 전문 검색 색인에 그대로 들어가면 두
54
+ * 단어가 한 토큰으로 붙어 어느 쪽으로도 검색되지 않고, 미리보기 스니펫도
55
+ * 문장이 뭉개진 채 나온다.
56
+ */
57
+ export declare function textWithBlockBreaks(nodes: readonly HtmlNode[]): string;
58
+ /** 트리에서 주어진 태그의 직계 자식들만 모은다. */
59
+ export declare function childElements(nodes: readonly HtmlNode[], tag: string): HtmlElementNode[];
60
+ /**
61
+ * 트리를 깊이 우선으로 훑어 주어진 태그의 첫 노드를 찾는다.
62
+ * 없으면 `null`.
63
+ */
64
+ export declare function findElement(nodes: readonly HtmlNode[], tag: string): HtmlElementNode | null;
65
+ // (소스맵은 CJS 선언 사본에서 제외됨 — scripts/finalize-types.mjs)