@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.
Files changed (131) hide show
  1. package/README.md +634 -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 +8759 -0
  27. package/dist/aeriz-wysiwyg.css +587 -163
  28. package/dist/aeriz-wysiwyg.esm.js +4249 -1381
  29. package/dist/aeriz-wysiwyg.esm.min.js +4456 -1995
  30. package/dist/aeriz-wysiwyg.js +4249 -1381
  31. package/dist/aeriz-wysiwyg.min.cjs +56 -0
  32. package/dist/aeriz-wysiwyg.min.css +1 -1
  33. package/dist/aeriz-wysiwyg.min.js +54 -21
  34. package/dist/server.cjs +34 -0
  35. package/dist/server.js +798 -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 +530 -0
  58. package/dist-types/cjs/core/AerizViewer.d.cts +61 -0
  59. package/dist-types/cjs/core/block-meta.d.cts +98 -0
  60. package/dist-types/cjs/core/block-policy.d.cts +43 -0
  61. package/dist-types/cjs/core/blocks.d.cts +411 -0
  62. package/dist-types/cjs/core/fonts.d.cts +60 -0
  63. package/dist-types/cjs/core/highlight.d.cts +44 -0
  64. package/dist-types/cjs/core/history.d.cts +86 -0
  65. package/dist-types/cjs/core/html-mini.d.cts +65 -0
  66. package/dist-types/cjs/core/i18n.d.cts +221 -0
  67. package/dist-types/cjs/core/import-html.d.cts +40 -0
  68. package/dist-types/cjs/core/import-markdown.d.cts +33 -0
  69. package/dist-types/cjs/core/input-rules.d.cts +46 -0
  70. package/dist-types/cjs/core/markdown-export.d.cts +30 -0
  71. package/dist-types/cjs/core/plain-text.d.cts +17 -0
  72. package/dist-types/cjs/core/render-string.d.cts +68 -0
  73. package/dist-types/cjs/core/selection.d.cts +46 -0
  74. package/dist-types/cjs/core/snapshot.d.cts +51 -0
  75. package/dist-types/cjs/core/table-ops.d.cts +30 -0
  76. package/dist-types/cjs/index.d.cts +22 -0
  77. package/dist-types/cjs/server/index.d.cts +37 -0
  78. package/dist-types/cjs/types/index.d.cts +61 -0
  79. package/dist-types/cjs/ui/Toolbar.d.cts +21 -0
  80. package/dist-types/cjs/ui/dialogs.d.cts +74 -0
  81. package/dist-types/cjs/ui/icons.d.cts +2 -0
  82. package/dist-types/cjs/ui/popovers.d.cts +70 -0
  83. package/dist-types/core/AerizEditor.d.ts +210 -17
  84. package/dist-types/core/AerizEditor.d.ts.map +1 -1
  85. package/dist-types/core/AerizViewer.d.ts +16 -4
  86. package/dist-types/core/AerizViewer.d.ts.map +1 -1
  87. package/dist-types/core/block-meta.d.ts +98 -0
  88. package/dist-types/core/block-meta.d.ts.map +1 -0
  89. package/dist-types/core/block-policy.d.ts +43 -0
  90. package/dist-types/core/block-policy.d.ts.map +1 -0
  91. package/dist-types/core/blocks.d.ts +109 -11
  92. package/dist-types/core/blocks.d.ts.map +1 -1
  93. package/dist-types/core/fonts.d.ts +11 -0
  94. package/dist-types/core/fonts.d.ts.map +1 -1
  95. package/dist-types/core/history.d.ts +86 -0
  96. package/dist-types/core/history.d.ts.map +1 -0
  97. package/dist-types/core/html-mini.d.ts +65 -0
  98. package/dist-types/core/html-mini.d.ts.map +1 -0
  99. package/dist-types/core/i18n.d.ts +12 -0
  100. package/dist-types/core/i18n.d.ts.map +1 -1
  101. package/dist-types/core/import-html.d.ts +1 -0
  102. package/dist-types/core/import-html.d.ts.map +1 -1
  103. package/dist-types/core/import-markdown.d.ts +0 -4
  104. package/dist-types/core/import-markdown.d.ts.map +1 -1
  105. package/dist-types/core/input-rules.d.ts +46 -0
  106. package/dist-types/core/input-rules.d.ts.map +1 -0
  107. package/dist-types/core/markdown-export.d.ts +30 -0
  108. package/dist-types/core/markdown-export.d.ts.map +1 -0
  109. package/dist-types/core/plain-text.d.ts +17 -0
  110. package/dist-types/core/plain-text.d.ts.map +1 -0
  111. package/dist-types/core/render-string.d.ts +68 -0
  112. package/dist-types/core/render-string.d.ts.map +1 -0
  113. package/dist-types/core/selection.d.ts +46 -0
  114. package/dist-types/core/selection.d.ts.map +1 -0
  115. package/dist-types/core/snapshot.d.ts +51 -0
  116. package/dist-types/core/snapshot.d.ts.map +1 -0
  117. package/dist-types/core/table-ops.d.ts +30 -0
  118. package/dist-types/core/table-ops.d.ts.map +1 -0
  119. package/dist-types/index.d.ts +21 -10
  120. package/dist-types/index.d.ts.map +1 -1
  121. package/dist-types/server/index.d.ts +37 -0
  122. package/dist-types/server/index.d.ts.map +1 -0
  123. package/dist-types/types/index.d.ts +21 -0
  124. package/dist-types/types/index.d.ts.map +1 -1
  125. package/dist-types/ui/Toolbar.d.ts +1 -1
  126. package/dist-types/ui/Toolbar.d.ts.map +1 -1
  127. package/dist-types/ui/dialogs.d.ts.map +1 -1
  128. package/dist-types/ui/icons.d.ts.map +1 -1
  129. package/dist-types/ui/popovers.d.ts +1 -1
  130. package/dist-types/ui/popovers.d.ts.map +1 -1
  131. package/package.json +213 -58
@@ -0,0 +1,112 @@
1
+ # Angular 연동
2
+
3
+ 이 디렉터리는 **TypeScript 소스로 배포**됩니다. 미리 컴파일한 Angular
4
+ 라이브러리는 빌드에 쓰인 Angular 버전과 소비자 버전이 맞아야 하는데, 소스로
5
+ 두면 소비자의 Angular 컴파일러가 직접 컴파일하므로 Angular 14 이상 어느
6
+ 버전에서도 같은 파일이 동작합니다.
7
+
8
+ ## 설정 (택 1)
9
+
10
+ ### 방법 A — tsconfig 에 경로 추가 (권장)
11
+
12
+ `tsconfig.app.json` 의 `include` 에 한 줄 추가하면 Angular CLI 가 이 소스를
13
+ 앱과 함께 컴파일합니다.
14
+
15
+ ```jsonc
16
+ {
17
+ "include": [
18
+ "src/**/*.ts",
19
+ "node_modules/@aeriz/wysiwyg/angular/*.ts" // ← 추가
20
+ ]
21
+ }
22
+ ```
23
+
24
+ ### 방법 B — 파일 복사
25
+
26
+ `aeriz-editor.directive.ts` 를 앱 소스 안으로 복사합니다. 의존성은
27
+ `@angular/core`, `@angular/forms`, `@aeriz/wysiwyg` 뿐입니다.
28
+
29
+ ## 스타일시트
30
+
31
+ `angular.json` 의 `styles` 배열에 추가합니다.
32
+
33
+ ```jsonc
34
+ "styles": [
35
+ "node_modules/@aeriz/wysiwyg/dist/aeriz-wysiwyg.min.css",
36
+ "src/styles.css"
37
+ ]
38
+ ```
39
+
40
+ ## 사용
41
+
42
+ ### standalone 컴포넌트
43
+
44
+ ```ts
45
+ import { Component } from '@angular/core';
46
+ import { FormsModule } from '@angular/forms';
47
+ import { AerizEditorDirective } from '@aeriz/wysiwyg/angular';
48
+
49
+ @Component({
50
+ standalone: true,
51
+ imports: [FormsModule, AerizEditorDirective],
52
+ template: `
53
+ <div aerizEditor [(ngModel)]="html" theme="dark" placeholder="내용을 입력하세요"></div>
54
+ <pre>{{ html }}</pre>
55
+ `,
56
+ })
57
+ export class ComposeComponent {
58
+ html = '<p>안녕하세요</p>';
59
+ }
60
+ ```
61
+
62
+ ### NgModule 앱
63
+
64
+ ```ts
65
+ import { AerizWysiwygModule } from '@aeriz/wysiwyg/angular';
66
+
67
+ @NgModule({
68
+ imports: [BrowserModule, FormsModule, AerizWysiwygModule],
69
+ })
70
+ export class AppModule {}
71
+ ```
72
+
73
+ ## 바인딩 방식
74
+
75
+ | 방식 | 템플릿 |
76
+ | --- | --- |
77
+ | 단방향 | `<div aerizEditor [value]="html" (valueChange)="html = $event"></div>` |
78
+ | 양방향 | `<div aerizEditor [(value)]="html"></div>` |
79
+ | ngModel | `<div aerizEditor [(ngModel)]="html"></div>` |
80
+ | Reactive Forms | `<div aerizEditor formControlName="body"></div>` |
81
+
82
+ ## 입력 / 출력
83
+
84
+ | 이름 | 타입 | 설명 |
85
+ | --- | --- | --- |
86
+ | `value` | `string` | 본문 HTML |
87
+ | `placeholder` | `string` | 빈 본문 안내 문구 |
88
+ | `toolbar` | `ToolbarConfig \| false` | 툴바 구성. `false` 면 숨김 |
89
+ | `theme` | `'light' \| 'dark'` | 테마 |
90
+ | `locale` | `'en' \| 'ko' \| 'ja' \| 'zh'` | UI 언어 |
91
+ | `imageUploadUrl` | `string` | 이미지 업로드 API URL |
92
+ | `fileUploadUrl` | `string` | 파일 업로드 API URL |
93
+ | `imageUpload` | `(file: File) => Promise<string>` | 직접 업로드 핸들러 |
94
+ | `fileUpload` | `(file: File) => Promise<string>` | 직접 업로드 핸들러 |
95
+ | `(valueChange)` | `string` | 본문 변경 |
96
+ | `(stateChange)` | `EditorState` | 블록/선택 상태 변경 |
97
+ | `(ready)` | `AerizEditor` | 인스턴스 생성 완료 |
98
+
99
+ ## 성능 메모
100
+
101
+ 디렉티브는 에디터 인스턴스를 `NgZone` **밖에서** 생성합니다. 에디터는
102
+ `selectionchange` 등 고빈도 이벤트를 구독하므로, zone 안에서 만들면 캐럿을
103
+ 움직일 때마다 변경 감지가 돌게 됩니다. 값이 실제로 바뀔 때만 zone 으로
104
+ 복귀해 한 번 감지를 돌립니다.
105
+
106
+ ## 뷰어
107
+
108
+ ```html
109
+ <div aerizViewer [blocks]="blocks" theme="light"></div>
110
+ <!-- 블록 대신 HTML 문자열도 가능 -->
111
+ <div aerizViewer [html]="savedHtml"></div>
112
+ ```
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Angular 디렉티브 — `[aerizEditor]` / `[aerizViewer]`.
3
+ *
4
+ * 이 파일은 **소스 배포**다. Angular 라이브러리는 소비자의 Angular 버전에 맞춰
5
+ * Ivy 로 컴파일돼야 하고, 미리 빌드한 산출물은 버전 창이 좁아진다. 소스로
6
+ * 두면 소비자의 Angular 컴파일러가 직접 컴파일하므로 Angular 14 ~ 최신까지
7
+ * 같은 파일 하나로 동작한다. 설정 방법은 `angular/README.md` 참고.
8
+ *
9
+ * `@angular/core` / `@angular/forms` 는 소비자 앱의 것을 그대로 쓴다.
10
+ */
11
+ import {
12
+ Directive,
13
+ ElementRef,
14
+ EventEmitter,
15
+ Input,
16
+ NgZone,
17
+ OnChanges,
18
+ OnDestroy,
19
+ OnInit,
20
+ Output,
21
+ forwardRef,
22
+ } from '@angular/core';
23
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
24
+ import type { ControlValueAccessor } from '@angular/forms';
25
+ import { createEditorController, createViewerController } from '@aeriz/wysiwyg/adapter';
26
+ import type {
27
+ AerizEditorController,
28
+ AerizEditorProps,
29
+ AerizViewerController,
30
+ AerizViewerProps,
31
+ } from '@aeriz/wysiwyg/adapter';
32
+ import type {
33
+ AerizEditor,
34
+ AerizViewer,
35
+ BlockSnapshot,
36
+ EditorState,
37
+ ToolbarConfig,
38
+ } from '@aeriz/wysiwyg';
39
+
40
+ type Theme = 'light' | 'dark';
41
+ type Locale = 'en' | 'ko' | 'ja' | 'zh';
42
+ type HtmlStyles = 'inline' | 'class';
43
+ type UploadFn = (file: File) => Promise<string>;
44
+
45
+ /**
46
+ * 에디터 디렉티브.
47
+ *
48
+ * 세 가지 바인딩 방식을 모두 지원한다.
49
+ * - 단방향: `<div aerizEditor [value]="html" (valueChange)="html = $event">`
50
+ * - 양방향: `<div aerizEditor [(value)]="html">`
51
+ * - 폼: `<div aerizEditor [(ngModel)]="html">` / `formControlName="body"`
52
+ *
53
+ * 에디터 내부 리스너(selectionchange 등) 는 매우 자주 발화하므로 인스턴스를
54
+ * Angular zone **밖에서** 만든다. 값이 실제로 바뀔 때만 zone 안으로 돌아와
55
+ * 변경 감지를 한 번 돌린다.
56
+ */
57
+ @Directive({
58
+ selector: '[aerizEditor]',
59
+ standalone: true,
60
+ providers: [
61
+ {
62
+ provide: NG_VALUE_ACCESSOR,
63
+ useExisting: forwardRef(() => AerizEditorDirective),
64
+ multi: true,
65
+ },
66
+ ],
67
+ })
68
+ export class AerizEditorDirective
69
+ implements OnInit, OnChanges, OnDestroy, ControlValueAccessor
70
+ {
71
+ /** 본문 HTML. `[(value)]` 로 양방향 바인딩할 수 있다. */
72
+ @Input() value?: string;
73
+ @Input() placeholder?: string;
74
+ @Input() toolbar?: ToolbarConfig | false;
75
+ @Input() theme?: Theme;
76
+ @Input() locale?: Locale;
77
+ /** `getHTML()` · `(valueChange)` 출력 전략. 기본 `'inline'`. */
78
+ @Input() htmlStyles?: HtmlStyles;
79
+ @Input() imageUploadUrl?: string;
80
+ @Input() fileUploadUrl?: string;
81
+ /** 직접 업로드 핸들러. 설정 시 `imageUploadUrl` 보다 우선한다. */
82
+ @Input() imageUpload?: UploadFn;
83
+ @Input() fileUpload?: UploadFn;
84
+
85
+ @Output() valueChange = new EventEmitter<string>();
86
+ @Output() stateChange = new EventEmitter<EditorState>();
87
+ @Output() ready = new EventEmitter<AerizEditor>();
88
+
89
+ private controller: AerizEditorController | null = null;
90
+ /** 에디터가 들고 있는 값. ngModel / [value] 양쪽의 단일 출처. */
91
+ private current = '';
92
+ private onChangeFn: (value: string) => void = () => undefined;
93
+ private onTouchedFn: () => void = () => undefined;
94
+
95
+ constructor(
96
+ private readonly host: ElementRef<HTMLElement>,
97
+ private readonly zone: NgZone,
98
+ ) {}
99
+
100
+ /** 코어 인스턴스. 명령형 API 접근 경로. */
101
+ get editor(): AerizEditor | null {
102
+ return this.controller?.editor ?? null;
103
+ }
104
+
105
+ ngOnInit(): void {
106
+ if (this.value !== undefined) this.current = this.value;
107
+ this.zone.runOutsideAngular(() => {
108
+ this.controller = createEditorController(
109
+ this.host.nativeElement,
110
+ this.buildProps(),
111
+ );
112
+ });
113
+ }
114
+
115
+ ngOnChanges(): void {
116
+ if (!this.controller) return;
117
+ if (this.value !== undefined) this.current = this.value;
118
+ this.zone.runOutsideAngular(() => {
119
+ this.controller?.update(this.buildProps());
120
+ });
121
+ }
122
+
123
+ ngOnDestroy(): void {
124
+ this.controller?.destroy();
125
+ this.controller = null;
126
+ }
127
+
128
+ // ─── ControlValueAccessor ────────────────────────────────────────────
129
+
130
+ writeValue(value: string | null): void {
131
+ this.current = value ?? '';
132
+ this.zone.runOutsideAngular(() => {
133
+ this.controller?.update(this.buildProps());
134
+ });
135
+ }
136
+
137
+ registerOnChange(fn: (value: string) => void): void {
138
+ this.onChangeFn = fn;
139
+ }
140
+
141
+ registerOnTouched(fn: () => void): void {
142
+ this.onTouchedFn = fn;
143
+ }
144
+
145
+ setDisabledState(isDisabled: boolean): void {
146
+ // 코어에 읽기 전용 모드가 없어 본문 편집 가능 여부만 직접 토글한다.
147
+ const content = this.controller?.editor.content;
148
+ if (content) content.contentEditable = isDisabled ? 'false' : 'true';
149
+ }
150
+
151
+ // ─── 내부 ────────────────────────────────────────────────────────────
152
+
153
+ private buildProps(): AerizEditorProps {
154
+ const props: AerizEditorProps = {
155
+ value: this.current,
156
+ onChange: (html: string) => {
157
+ this.current = html;
158
+ // 편집이 실제로 값을 바꿨을 때만 zone 으로 복귀한다.
159
+ this.zone.run(() => {
160
+ this.onChangeFn(html);
161
+ this.onTouchedFn();
162
+ this.valueChange.emit(html);
163
+ });
164
+ },
165
+ onStateChange: (state: EditorState) => {
166
+ this.zone.run(() => this.stateChange.emit(state));
167
+ },
168
+ onReady: (editor: AerizEditor) => {
169
+ this.zone.run(() => this.ready.emit(editor));
170
+ },
171
+ };
172
+ if (this.placeholder !== undefined) props.placeholder = this.placeholder;
173
+ if (this.toolbar !== undefined) props.toolbar = this.toolbar;
174
+ if (this.theme !== undefined) props.theme = this.theme;
175
+ if (this.locale !== undefined) props.locale = this.locale;
176
+ if (this.htmlStyles !== undefined) props.htmlStyles = this.htmlStyles;
177
+ if (this.imageUploadUrl !== undefined) props.imageUploadUrl = this.imageUploadUrl;
178
+ if (this.fileUploadUrl !== undefined) props.fileUploadUrl = this.fileUploadUrl;
179
+ if (this.imageUpload !== undefined) props.onImageUpload = this.imageUpload;
180
+ if (this.fileUpload !== undefined) props.onFileUpload = this.fileUpload;
181
+ return props;
182
+ }
183
+ }
184
+
185
+ /** 읽기 전용 뷰어 디렉티브. `blocks` 가 있으면 `html` 보다 우선한다. */
186
+ @Directive({
187
+ selector: '[aerizViewer]',
188
+ standalone: true,
189
+ })
190
+ export class AerizViewerDirective implements OnInit, OnChanges, OnDestroy {
191
+ @Input() blocks?: BlockSnapshot[];
192
+ @Input() html?: string;
193
+ @Input() theme?: Theme;
194
+ /** `getHTML()` 출력 전략. 기본 `'inline'`. */
195
+ @Input() htmlStyles?: HtmlStyles;
196
+
197
+ @Output() ready = new EventEmitter<AerizViewer>();
198
+
199
+ private controller: AerizViewerController | null = null;
200
+
201
+ constructor(
202
+ private readonly host: ElementRef<HTMLElement>,
203
+ private readonly zone: NgZone,
204
+ ) {}
205
+
206
+ get viewer(): AerizViewer | null {
207
+ return this.controller?.viewer ?? null;
208
+ }
209
+
210
+ ngOnInit(): void {
211
+ this.zone.runOutsideAngular(() => {
212
+ this.controller = createViewerController(
213
+ this.host.nativeElement,
214
+ this.buildProps(),
215
+ );
216
+ });
217
+ }
218
+
219
+ ngOnChanges(): void {
220
+ if (!this.controller) return;
221
+ this.zone.runOutsideAngular(() => {
222
+ this.controller?.update(this.buildProps());
223
+ });
224
+ }
225
+
226
+ ngOnDestroy(): void {
227
+ this.controller?.destroy();
228
+ this.controller = null;
229
+ }
230
+
231
+ private buildProps(): AerizViewerProps {
232
+ const props: AerizViewerProps = {
233
+ onReady: (viewer: AerizViewer) => {
234
+ this.zone.run(() => this.ready.emit(viewer));
235
+ },
236
+ };
237
+ if (this.blocks !== undefined) props.blocks = this.blocks;
238
+ if (this.html !== undefined) props.html = this.html;
239
+ if (this.theme !== undefined) props.theme = this.theme;
240
+ if (this.htmlStyles !== undefined) props.htmlStyles = this.htmlStyles;
241
+ return props;
242
+ }
243
+ }
@@ -0,0 +1,14 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { AerizEditorDirective, AerizViewerDirective } from './aeriz-editor.directive';
3
+
4
+ /**
5
+ * NgModule 방식 앱을 위한 편의 모듈.
6
+ *
7
+ * standalone 컴포넌트를 쓰는 앱은 이 모듈 없이 디렉티브를 `imports` 에 직접
8
+ * 넣으면 된다.
9
+ */
10
+ @NgModule({
11
+ imports: [AerizEditorDirective, AerizViewerDirective],
12
+ exports: [AerizEditorDirective, AerizViewerDirective],
13
+ })
14
+ export class AerizWysiwygModule {}
@@ -0,0 +1,5 @@
1
+ export {
2
+ AerizEditorDirective,
3
+ AerizViewerDirective,
4
+ } from './aeriz-editor.directive';
5
+ export { AerizWysiwygModule } from './aeriz-wysiwyg.module';
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./shared.cjs"),f=new WeakMap,d=new WeakMap;function c(t,a,s){const n=t[0],e=n?f.get(n):void 0;switch(a){case"getHTML":return(e==null?void 0:e.editor.getHTML())??"";case"getBlocks":return(e==null?void 0:e.editor.serialize())??[];case"setHTML":return t.each((u,i)=>{var r;(r=f.get(i))==null||r.editor.setHTML(String(s[0]??""))}),t;case"update":return t.each((u,i)=>{var r;(r=f.get(i))==null||r.update(s[0]??{})}),t;case"focus":return e==null||e.editor.focus(),t;case"instance":return(e==null?void 0:e.editor)??null;case"destroy":return t.each((u,i)=>{const r=f.get(i);r&&(r.destroy(),f.delete(i))}),t;default:throw new Error(`aerizEditor: 알 수 없는 명령 "${a}"`)}}function y(t,a,s){const n=t[0],e=n?d.get(n):void 0;switch(a){case"getHTML":return(e==null?void 0:e.viewer.getHTML())??"";case"getBlocks":return(e==null?void 0:e.viewer.getBlocks())??[];case"update":return t.each((u,i)=>{var r;(r=d.get(i))==null||r.update(s[0]??{})}),t;case"instance":return(e==null?void 0:e.viewer)??null;case"destroy":return t.each((u,i)=>{const r=d.get(i);r&&(r.destroy(),d.delete(i))}),t;default:throw new Error(`aerizViewer: 알 수 없는 명령 "${a}"`)}}function p(t,...a){if(typeof t=="string")return c(this,t,a);const s=t??{};return this.each((n,e)=>{const u=f.get(e);if(u){u.update(s);return}f.set(e,h.createEditorController(e,s))}),this}function o(t,...a){if(typeof t=="string")return y(this,t,a);const s=t??{};return this.each((n,e)=>{const u=d.get(e);if(u){u.update(s);return}d.set(e,h.createViewerController(e,s))}),this}function w(t){if(!t||typeof t.fn!="object")throw new TypeError("registerAerizJQuery: jQuery 객체가 필요합니다.");t.fn.aerizEditor||(t.fn.aerizEditor=p),t.fn.aerizViewer||(t.fn.aerizViewer=o)}const g=globalThis.jQuery;g&&w(g);exports.registerAerizJQuery=w;
@@ -0,0 +1,91 @@
1
+ import { createEditorController as w, createViewerController as h } from "./shared.js";
2
+ const f = /* @__PURE__ */ new WeakMap(), d = /* @__PURE__ */ new WeakMap();
3
+ function c(t, n, s) {
4
+ const a = t[0], e = a ? f.get(a) : void 0;
5
+ switch (n) {
6
+ case "getHTML":
7
+ return (e == null ? void 0 : e.editor.getHTML()) ?? "";
8
+ case "getBlocks":
9
+ return (e == null ? void 0 : e.editor.serialize()) ?? [];
10
+ case "setHTML":
11
+ return t.each((u, i) => {
12
+ var r;
13
+ (r = f.get(i)) == null || r.editor.setHTML(String(s[0] ?? ""));
14
+ }), t;
15
+ case "update":
16
+ return t.each((u, i) => {
17
+ var r;
18
+ (r = f.get(i)) == null || r.update(s[0] ?? {});
19
+ }), t;
20
+ case "focus":
21
+ return e == null || e.editor.focus(), t;
22
+ case "instance":
23
+ return (e == null ? void 0 : e.editor) ?? null;
24
+ case "destroy":
25
+ return t.each((u, i) => {
26
+ const r = f.get(i);
27
+ r && (r.destroy(), f.delete(i));
28
+ }), t;
29
+ default:
30
+ throw new Error(`aerizEditor: 알 수 없는 명령 "${n}"`);
31
+ }
32
+ }
33
+ function y(t, n, s) {
34
+ const a = t[0], e = a ? d.get(a) : void 0;
35
+ switch (n) {
36
+ case "getHTML":
37
+ return (e == null ? void 0 : e.viewer.getHTML()) ?? "";
38
+ case "getBlocks":
39
+ return (e == null ? void 0 : e.viewer.getBlocks()) ?? [];
40
+ case "update":
41
+ return t.each((u, i) => {
42
+ var r;
43
+ (r = d.get(i)) == null || r.update(s[0] ?? {});
44
+ }), t;
45
+ case "instance":
46
+ return (e == null ? void 0 : e.viewer) ?? null;
47
+ case "destroy":
48
+ return t.each((u, i) => {
49
+ const r = d.get(i);
50
+ r && (r.destroy(), d.delete(i));
51
+ }), t;
52
+ default:
53
+ throw new Error(`aerizViewer: 알 수 없는 명령 "${n}"`);
54
+ }
55
+ }
56
+ function p(t, ...n) {
57
+ if (typeof t == "string")
58
+ return c(this, t, n);
59
+ const s = t ?? {};
60
+ return this.each((a, e) => {
61
+ const u = f.get(e);
62
+ if (u) {
63
+ u.update(s);
64
+ return;
65
+ }
66
+ f.set(e, w(e, s));
67
+ }), this;
68
+ }
69
+ function z(t, ...n) {
70
+ if (typeof t == "string")
71
+ return y(this, t, n);
72
+ const s = t ?? {};
73
+ return this.each((a, e) => {
74
+ const u = d.get(e);
75
+ if (u) {
76
+ u.update(s);
77
+ return;
78
+ }
79
+ d.set(e, h(e, s));
80
+ }), this;
81
+ }
82
+ function o(t) {
83
+ if (!t || typeof t.fn != "object")
84
+ throw new TypeError("registerAerizJQuery: jQuery 객체가 필요합니다.");
85
+ t.fn.aerizEditor || (t.fn.aerizEditor = p), t.fn.aerizViewer || (t.fn.aerizViewer = z);
86
+ }
87
+ const g = globalThis.jQuery;
88
+ g && o(g);
89
+ export {
90
+ o as registerAerizJQuery
91
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react"),l=require("./shared.cjs");function s(r,n){const c=i.useRef(null),t=i.useRef(null),e=i.useRef(n);return e.current=n,i.useEffect(()=>{const o=c.current;if(!o)return;const u=r(o,e.current);return t.current=u,()=>{u.destroy(),t.current=null}},[]),i.useEffect(()=>{var o;(o=t.current)==null||o.update(n)}),{hostRef:c,controllerRef:t}}function f(r){const n={};return r.className!==void 0&&(n.className=r.className),r.style!==void 0&&(n.style=r.style),r.id!==void 0&&(n.id=r.id),n}function m(r,n){const{hostRef:c,controllerRef:t}=s(l.createEditorController,r);return i.useImperativeHandle(n,()=>({get editor(){var e;return((e=t.current)==null?void 0:e.editor)??null},getHTML:()=>{var e;return((e=t.current)==null?void 0:e.editor.getHTML())??""},setHTML:e=>{var o;return(o=t.current)==null?void 0:o.editor.setHTML(e)},focus:()=>{var e;return(e=t.current)==null?void 0:e.editor.focus()}}),[t]),i.createElement("div",{...f(r),ref:c})}function R(r,n){const{hostRef:c,controllerRef:t}=s(l.createViewerController,r);return i.useImperativeHandle(n,()=>({get viewer(){var e;return((e=t.current)==null?void 0:e.viewer)??null}}),[t]),i.createElement("div",{...f(r),ref:c})}const d=i.forwardRef(m);d.displayName="AerizEditor";const a=i.forwardRef(R);a.displayName="AerizViewer";exports.AerizEditor=d;exports.AerizViewer=a;
@@ -0,0 +1,66 @@
1
+ import { forwardRef as s, useImperativeHandle as f, createElement as d, useRef as c, useEffect as u } from "react";
2
+ import { createEditorController as R, createViewerController as v } from "./shared.js";
3
+ function a(r, n) {
4
+ const i = c(null), t = c(null), e = c(n);
5
+ return e.current = n, u(() => {
6
+ const o = i.current;
7
+ if (!o) return;
8
+ const l = r(o, e.current);
9
+ return t.current = l, () => {
10
+ l.destroy(), t.current = null;
11
+ };
12
+ }, []), u(() => {
13
+ var o;
14
+ (o = t.current) == null || o.update(n);
15
+ }), { hostRef: i, controllerRef: t };
16
+ }
17
+ function m(r) {
18
+ const n = {};
19
+ return r.className !== void 0 && (n.className = r.className), r.style !== void 0 && (n.style = r.style), r.id !== void 0 && (n.id = r.id), n;
20
+ }
21
+ function w(r, n) {
22
+ const { hostRef: i, controllerRef: t } = a(R, r);
23
+ return f(
24
+ n,
25
+ () => ({
26
+ get editor() {
27
+ var e;
28
+ return ((e = t.current) == null ? void 0 : e.editor) ?? null;
29
+ },
30
+ getHTML: () => {
31
+ var e;
32
+ return ((e = t.current) == null ? void 0 : e.editor.getHTML()) ?? "";
33
+ },
34
+ setHTML: (e) => {
35
+ var o;
36
+ return (o = t.current) == null ? void 0 : o.editor.setHTML(e);
37
+ },
38
+ focus: () => {
39
+ var e;
40
+ return (e = t.current) == null ? void 0 : e.editor.focus();
41
+ }
42
+ }),
43
+ [t]
44
+ ), d("div", { ...m(r), ref: i });
45
+ }
46
+ function A(r, n) {
47
+ const { hostRef: i, controllerRef: t } = a(v, r);
48
+ return f(
49
+ n,
50
+ () => ({
51
+ get viewer() {
52
+ var e;
53
+ return ((e = t.current) == null ? void 0 : e.viewer) ?? null;
54
+ }
55
+ }),
56
+ [t]
57
+ ), d("div", { ...m(r), ref: i });
58
+ }
59
+ const y = s(w);
60
+ y.displayName = "AerizEditor";
61
+ const z = s(A);
62
+ z.displayName = "AerizViewer";
63
+ export {
64
+ y as AerizEditor,
65
+ z as AerizViewer
66
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("@aeriz/wysiwyg");function v(a){const e=document.createElement("div");e.innerHTML=a,f.normalizeContent(e,{writableTail:!1});const t=new f.BlockIdRegistry;return f.assignMissingIds(e,t),f.serializeBlocks(f.listBlocks(e,o=>t.ensure(o)))}function T(a,e,t){const o={element:a,onChange:t},n=e.value??e.initialHTML;return n!==void 0&&(o.initialHTML=n),e.placeholder!==void 0&&(o.placeholder=e.placeholder),e.toolbar!==void 0&&(o.toolbar=e.toolbar),e.theme!==void 0&&(o.theme=e.theme),e.locale!==void 0&&(o.locale=e.locale),e.htmlStyles!==void 0&&(o.htmlStyles=e.htmlStyles),e.onImageUpload!==void 0&&(o.onImageUpload=e.onImageUpload),e.imageUploadUrl!==void 0&&(o.imageUploadUrl=e.imageUploadUrl),e.onFileUpload!==void 0&&(o.onFileUpload=e.onFileUpload),e.fileUploadUrl!==void 0&&(o.fileUploadUrl=e.fileUploadUrl),o}function w(a,e){return a===e?!0:a===!1||e===!1||a===void 0||e===void 0||a.sticky!==e.sticky||a.items.length!==e.items.length?!1:a.items.every((t,o)=>t===e.items[o])}function M(a,e){let t=e,o="",n=!1,d=!1;const m=l=>{var s;o=l,!n&&((s=t.onChange)==null||s.call(t,l))};let i,c=null,r;const S=l=>{l.onImageUpload===void 0?delete r.onImageUpload:r.onImageUpload=l.onImageUpload,l.imageUploadUrl===void 0?delete r.imageUploadUrl:r.imageUploadUrl=l.imageUploadUrl,l.onFileUpload===void 0?delete r.onFileUpload:r.onFileUpload=l.onFileUpload,l.fileUploadUrl===void 0?delete r.fileUploadUrl:r.fileUploadUrl=l.fileUploadUrl,l.htmlStyles===void 0?delete r.htmlStyles:r.htmlStyles=l.htmlStyles},u=(l,s)=>{var y;const h=s!==void 0?{...l,value:s}:l;r=T(a,h,m),i=new f.AerizEditor(r),o=i.getHTML(),c=i.onStateChange(k=>{var g;return(g=t.onStateChange)==null?void 0:g.call(t,k)}),(y=t.onReady)==null||y.call(t,i)},U=()=>{var l;(l=t.onDestroy)==null||l.call(t,i),c==null||c(),c=null,i.destroy()};return u(t),{get editor(){return i},update(l){if(d)return;const s=t;if(t=l,l.locale!==s.locale||!w(l.toolbar,s.toolbar)){const h=l.value??i.getHTML();U(),u(l,h);return}if(S(l),l.theme!==s.theme&&l.theme!==void 0&&i.setTheme(l.theme),l.placeholder!==s.placeholder&&(l.placeholder===void 0?delete i.content.dataset.placeholder:i.content.dataset.placeholder=l.placeholder),l.value!==void 0&&l.value!==o&&l.value!==i.getHTML()){n=!0;try{i.setHTML(l.value)}finally{n=!1}o=l.value}},destroy(){d||(d=!0,U())}}}function L(a,e){const t={element:a},o=e.blocks??(e.html!==void 0?v(e.html):void 0);return o!==void 0&&(t.initialBlocks=o),e.theme!==void 0&&(t.theme=e.theme),e.htmlStyles!==void 0&&(t.htmlStyles=e.htmlStyles),t}function C(a,e){var m;let t=e,o=!1;const n=L(a,e),d=new f.AerizViewer(n);return(m=t.onReady)==null||m.call(t,d),{viewer:d,update(i){if(o)return;const c=t;t=i,i.theme!==c.theme&&i.theme!==void 0&&d.setTheme(i.theme),i.htmlStyles===void 0?delete n.htmlStyles:n.htmlStyles=i.htmlStyles,i.blocks!==void 0?i.blocks!==c.blocks&&d.setBlocks(i.blocks):i.html!==void 0&&i.html!==c.html&&i.html!==d.getHTML()&&d.setBlocks(v(i.html))},destroy(){var i;o||(o=!0,(i=t.onDestroy)==null||i.call(t,d),d.destroy())}}}exports.createEditorController=M;exports.createViewerController=C;exports.htmlToBlocks=v;
@@ -0,0 +1,87 @@
1
+ import { AerizViewer as k, AerizEditor as T, normalizeContent as L, BlockIdRegistry as M, assignMissingIds as w, serializeBlocks as H, listBlocks as I } from "@aeriz/wysiwyg";
2
+ function y(a) {
3
+ const e = document.createElement("div");
4
+ e.innerHTML = a, L(e, { writableTail: !1 });
5
+ const t = new M();
6
+ return w(e, t), H(I(e, (o) => t.ensure(o)));
7
+ }
8
+ function B(a, e, t) {
9
+ const o = { element: a, onChange: t }, n = e.value ?? e.initialHTML;
10
+ return n !== void 0 && (o.initialHTML = n), e.placeholder !== void 0 && (o.placeholder = e.placeholder), e.toolbar !== void 0 && (o.toolbar = e.toolbar), e.theme !== void 0 && (o.theme = e.theme), e.locale !== void 0 && (o.locale = e.locale), e.htmlStyles !== void 0 && (o.htmlStyles = e.htmlStyles), e.onImageUpload !== void 0 && (o.onImageUpload = e.onImageUpload), e.imageUploadUrl !== void 0 && (o.imageUploadUrl = e.imageUploadUrl), e.onFileUpload !== void 0 && (o.onFileUpload = e.onFileUpload), e.fileUploadUrl !== void 0 && (o.fileUploadUrl = e.fileUploadUrl), o;
11
+ }
12
+ function C(a, e) {
13
+ return a === e ? !0 : a === !1 || e === !1 || a === void 0 || e === void 0 || a.sticky !== e.sticky || a.items.length !== e.items.length ? !1 : a.items.every((t, o) => t === e.items[o]);
14
+ }
15
+ function z(a, e) {
16
+ let t = e, o = "", n = !1, d = !1;
17
+ const c = (l) => {
18
+ var s;
19
+ o = l, !n && ((s = t.onChange) == null || s.call(t, l));
20
+ };
21
+ let i, f = null, r;
22
+ const g = (l) => {
23
+ l.onImageUpload === void 0 ? delete r.onImageUpload : r.onImageUpload = l.onImageUpload, l.imageUploadUrl === void 0 ? delete r.imageUploadUrl : r.imageUploadUrl = l.imageUploadUrl, l.onFileUpload === void 0 ? delete r.onFileUpload : r.onFileUpload = l.onFileUpload, l.fileUploadUrl === void 0 ? delete r.fileUploadUrl : r.fileUploadUrl = l.fileUploadUrl, l.htmlStyles === void 0 ? delete r.htmlStyles : r.htmlStyles = l.htmlStyles;
24
+ }, h = (l, s) => {
25
+ var U;
26
+ const m = s !== void 0 ? { ...l, value: s } : l;
27
+ r = B(a, m, c), i = new T(r), o = i.getHTML(), f = i.onStateChange((S) => {
28
+ var u;
29
+ return (u = t.onStateChange) == null ? void 0 : u.call(t, S);
30
+ }), (U = t.onReady) == null || U.call(t, i);
31
+ }, v = () => {
32
+ var l;
33
+ (l = t.onDestroy) == null || l.call(t, i), f == null || f(), f = null, i.destroy();
34
+ };
35
+ return h(t), {
36
+ get editor() {
37
+ return i;
38
+ },
39
+ update(l) {
40
+ if (d) return;
41
+ const s = t;
42
+ if (t = l, l.locale !== s.locale || !C(l.toolbar, s.toolbar)) {
43
+ const m = l.value ?? i.getHTML();
44
+ v(), h(l, m);
45
+ return;
46
+ }
47
+ if (g(l), l.theme !== s.theme && l.theme !== void 0 && i.setTheme(l.theme), l.placeholder !== s.placeholder && (l.placeholder === void 0 ? delete i.content.dataset.placeholder : i.content.dataset.placeholder = l.placeholder), l.value !== void 0 && l.value !== o && l.value !== i.getHTML()) {
48
+ n = !0;
49
+ try {
50
+ i.setHTML(l.value);
51
+ } finally {
52
+ n = !1;
53
+ }
54
+ o = l.value;
55
+ }
56
+ },
57
+ destroy() {
58
+ d || (d = !0, v());
59
+ }
60
+ };
61
+ }
62
+ function F(a, e) {
63
+ const t = { element: a }, o = e.blocks ?? (e.html !== void 0 ? y(e.html) : void 0);
64
+ return o !== void 0 && (t.initialBlocks = o), e.theme !== void 0 && (t.theme = e.theme), e.htmlStyles !== void 0 && (t.htmlStyles = e.htmlStyles), t;
65
+ }
66
+ function O(a, e) {
67
+ var c;
68
+ let t = e, o = !1;
69
+ const n = F(a, e), d = new k(n);
70
+ return (c = t.onReady) == null || c.call(t, d), {
71
+ viewer: d,
72
+ update(i) {
73
+ if (o) return;
74
+ const f = t;
75
+ t = i, i.theme !== f.theme && i.theme !== void 0 && d.setTheme(i.theme), i.htmlStyles === void 0 ? delete n.htmlStyles : n.htmlStyles = i.htmlStyles, i.blocks !== void 0 ? i.blocks !== f.blocks && d.setBlocks(i.blocks) : i.html !== void 0 && i.html !== f.html && i.html !== d.getHTML() && d.setBlocks(y(i.html));
76
+ },
77
+ destroy() {
78
+ var i;
79
+ o || (o = !0, (i = t.onDestroy) == null || i.call(t, d), d.destroy());
80
+ }
81
+ };
82
+ }
83
+ export {
84
+ z as createEditorController,
85
+ O as createViewerController,
86
+ y as htmlToBlocks
87
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./shared.cjs");function a(t,o={}){const e=r.createEditorController(t,o);return{update(i={}){e.update(i)},destroy(){e.destroy()}}}function l(t,o={}){const e=r.createViewerController(t,o);return{update(i={}){e.update(i)},destroy(){e.destroy()}}}exports.createEditorController=r.createEditorController;exports.createViewerController=r.createViewerController;exports.aerizEditor=a;exports.aerizViewer=l;
@@ -0,0 +1,29 @@
1
+ import { createEditorController as n, createViewerController as d } from "./shared.js";
2
+ function a(e, t = {}) {
3
+ const r = n(e, t);
4
+ return {
5
+ update(o = {}) {
6
+ r.update(o);
7
+ },
8
+ destroy() {
9
+ r.destroy();
10
+ }
11
+ };
12
+ }
13
+ function c(e, t = {}) {
14
+ const r = d(e, t);
15
+ return {
16
+ update(o = {}) {
17
+ r.update(o);
18
+ },
19
+ destroy() {
20
+ r.destroy();
21
+ }
22
+ };
23
+ }
24
+ export {
25
+ a as aerizEditor,
26
+ c as aerizViewer,
27
+ n as createEditorController,
28
+ d as createViewerController
29
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("vue"),f=require("./shared.cjs"),r=l.defineComponent({name:"AerizEditor",props:{modelValue:{type:String,default:void 0},initialHTML:{type:String,default:void 0},placeholder:{type:String,default:void 0},toolbar:{type:[Object,Boolean],default:void 0},theme:{type:String,default:void 0},locale:{type:String,default:void 0},htmlStyles:{type:String,default:void 0},onImageUpload:{type:Function,default:void 0},imageUploadUrl:{type:String,default:void 0},onFileUpload:{type:Function,default:void 0},fileUploadUrl:{type:String,default:void 0}},emits:{"update:modelValue":e=>typeof e=="string",change:e=>typeof e=="string","state-change":e=>!0,ready:e=>!0},setup(e,{emit:o,expose:u}){const a=l.ref(null);let t=null;const n=()=>{const i={onChange:d=>{o("update:modelValue",d),o("change",d)},onStateChange:d=>o("state-change",d),onReady:d=>o("ready",d)};return e.modelValue!==void 0&&(i.value=e.modelValue),e.initialHTML!==void 0&&(i.initialHTML=e.initialHTML),e.placeholder!==void 0&&(i.placeholder=e.placeholder),e.toolbar!==void 0&&(i.toolbar=e.toolbar),e.theme!==void 0&&(i.theme=e.theme),e.locale!==void 0&&(i.locale=e.locale),e.htmlStyles!==void 0&&(i.htmlStyles=e.htmlStyles),e.onImageUpload!==void 0&&(i.onImageUpload=e.onImageUpload),e.imageUploadUrl!==void 0&&(i.imageUploadUrl=e.imageUploadUrl),e.onFileUpload!==void 0&&(i.onFileUpload=e.onFileUpload),e.fileUploadUrl!==void 0&&(i.fileUploadUrl=e.fileUploadUrl),i};return l.onMounted(()=>{a.value&&(t=f.createEditorController(a.value,n()))}),l.watch(()=>({...e}),()=>t==null?void 0:t.update(n()),{flush:"post"}),l.onBeforeUnmount(()=>{t==null||t.destroy(),t=null}),u({get editor(){return(t==null?void 0:t.editor)??null},getHTML:()=>(t==null?void 0:t.editor.getHTML())??"",setHTML:i=>t==null?void 0:t.editor.setHTML(i),focus:()=>t==null?void 0:t.editor.focus()}),()=>l.h("div",{ref:a})}}),v=l.defineComponent({name:"AerizViewer",props:{blocks:{type:Array,default:void 0},html:{type:String,default:void 0},theme:{type:String,default:void 0},htmlStyles:{type:String,default:void 0}},emits:{ready:e=>!0},setup(e,{emit:o,expose:u}){const a=l.ref(null);let t=null;const n=()=>{const i={onReady:d=>o("ready",d)};return e.blocks!==void 0&&(i.blocks=e.blocks),e.html!==void 0&&(i.html=e.html),e.theme!==void 0&&(i.theme=e.theme),e.htmlStyles!==void 0&&(i.htmlStyles=e.htmlStyles),i};return l.onMounted(()=>{a.value&&(t=f.createViewerController(a.value,n()))}),l.watch(()=>({...e}),()=>t==null?void 0:t.update(n()),{flush:"post"}),l.onBeforeUnmount(()=>{t==null||t.destroy(),t=null}),u({get viewer(){return(t==null?void 0:t.viewer)??null}}),()=>l.h("div",{ref:a})}}),m={install(e){e.component("AerizEditor",r),e.component("AerizViewer",v)}};exports.AerizEditor=r;exports.AerizViewer=v;exports.AerizWysiwygPlugin=m;