@aeriz/wysiwyg 1.0.1 → 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 +1194 -153
  29. package/dist/aeriz-wysiwyg.esm.min.js +2067 -1204
  30. package/dist/aeriz-wysiwyg.js +1193 -152
  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,110 @@
1
+ import { defineComponent as u, ref as f, onMounted as m, watch as v, onBeforeUnmount as r, h as y } from "vue";
2
+ import { createEditorController as h, createViewerController as g } from "./shared.js";
3
+ const U = u({
4
+ name: "AerizEditor",
5
+ props: {
6
+ /** `v-model` 바인딩 값 (HTML). */
7
+ modelValue: { type: String, default: void 0 },
8
+ /** `v-model` 없이 초기값만 줄 때 사용. */
9
+ initialHTML: { type: String, default: void 0 },
10
+ placeholder: { type: String, default: void 0 },
11
+ /** `false` 면 툴바를 렌더하지 않는다. */
12
+ toolbar: {
13
+ type: [Object, Boolean],
14
+ default: void 0
15
+ },
16
+ theme: { type: String, default: void 0 },
17
+ locale: { type: String, default: void 0 },
18
+ /** `getHTML()` · `onChange` 출력 전략. 기본 `'inline'`. */
19
+ htmlStyles: { type: String, default: void 0 },
20
+ onImageUpload: { type: Function, default: void 0 },
21
+ imageUploadUrl: { type: String, default: void 0 },
22
+ onFileUpload: { type: Function, default: void 0 },
23
+ fileUploadUrl: { type: String, default: void 0 }
24
+ },
25
+ emits: {
26
+ "update:modelValue": (e) => typeof e == "string",
27
+ change: (e) => typeof e == "string",
28
+ "state-change": (e) => !0,
29
+ ready: (e) => !0
30
+ },
31
+ setup(e, { emit: a, expose: n }) {
32
+ const d = f(null);
33
+ let t = null;
34
+ const o = () => {
35
+ const i = {
36
+ onChange: (l) => {
37
+ a("update:modelValue", l), a("change", l);
38
+ },
39
+ onStateChange: (l) => a("state-change", l),
40
+ onReady: (l) => a("ready", l)
41
+ };
42
+ 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;
43
+ };
44
+ return m(() => {
45
+ d.value && (t = h(d.value, o()));
46
+ }), v(
47
+ () => ({ ...e }),
48
+ () => t == null ? void 0 : t.update(o()),
49
+ { flush: "post" }
50
+ ), r(() => {
51
+ t == null || t.destroy(), t = null;
52
+ }), n({
53
+ get editor() {
54
+ return (t == null ? void 0 : t.editor) ?? null;
55
+ },
56
+ getHTML: () => (t == null ? void 0 : t.editor.getHTML()) ?? "",
57
+ setHTML: (i) => t == null ? void 0 : t.editor.setHTML(i),
58
+ focus: () => t == null ? void 0 : t.editor.focus()
59
+ }), () => y("div", { ref: d });
60
+ }
61
+ }), S = u({
62
+ name: "AerizViewer",
63
+ props: {
64
+ /** 표시할 블록 상태. `html` 보다 우선한다. */
65
+ blocks: {
66
+ type: Array,
67
+ default: void 0
68
+ },
69
+ /** 블록 대신 HTML 문자열을 넣을 때 사용. */
70
+ html: { type: String, default: void 0 },
71
+ theme: { type: String, default: void 0 },
72
+ /** `getHTML()` 출력 전략. 기본 `'inline'`. */
73
+ htmlStyles: { type: String, default: void 0 }
74
+ },
75
+ emits: {
76
+ ready: (e) => !0
77
+ },
78
+ setup(e, { emit: a, expose: n }) {
79
+ const d = f(null);
80
+ let t = null;
81
+ const o = () => {
82
+ const i = {
83
+ onReady: (l) => a("ready", l)
84
+ };
85
+ 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;
86
+ };
87
+ return m(() => {
88
+ d.value && (t = g(d.value, o()));
89
+ }), v(
90
+ () => ({ ...e }),
91
+ () => t == null ? void 0 : t.update(o()),
92
+ { flush: "post" }
93
+ ), r(() => {
94
+ t == null || t.destroy(), t = null;
95
+ }), n({
96
+ get viewer() {
97
+ return (t == null ? void 0 : t.viewer) ?? null;
98
+ }
99
+ }), () => y("div", { ref: d });
100
+ }
101
+ }), b = {
102
+ install(e) {
103
+ e.component("AerizEditor", U), e.component("AerizViewer", S);
104
+ }
105
+ };
106
+ export {
107
+ U as AerizEditor,
108
+ S as AerizViewer,
109
+ b as AerizWysiwygPlugin
110
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./shared.cjs");function r(e,t){e.$watch(()=>({...e.$props}),t,{deep:!1})}const l={name:"AerizEditor",props:{value:{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}},data(){return{aerizController:null}},methods:{aerizProps(){const e=this.$props,t={onChange:i=>{this.$emit("input",i),this.$emit("change",i)},onStateChange:i=>this.$emit("state-change",i),onReady:i=>this.$emit("ready",i)};return e.value!==void 0&&(t.value=e.value),e.initialHTML!==void 0&&(t.initialHTML=e.initialHTML),e.placeholder!==void 0&&(t.placeholder=e.placeholder),e.toolbar!==void 0&&(t.toolbar=e.toolbar),e.theme!==void 0&&(t.theme=e.theme),e.locale!==void 0&&(t.locale=e.locale),e.htmlStyles!==void 0&&(t.htmlStyles=e.htmlStyles),e.onImageUpload!==void 0&&(t.onImageUpload=e.onImageUpload),e.imageUploadUrl!==void 0&&(t.imageUploadUrl=e.imageUploadUrl),e.onFileUpload!==void 0&&(t.onFileUpload=e.onFileUpload),e.fileUploadUrl!==void 0&&(t.fileUploadUrl=e.fileUploadUrl),t},getEditor(){var e;return((e=this.aerizController)==null?void 0:e.editor)??null},getHTML(){var e;return((e=this.aerizController)==null?void 0:e.editor.getHTML())??""},setHTML(e){var t;(t=this.aerizController)==null||t.editor.setHTML(e)},focus(){var e;(e=this.aerizController)==null||e.editor.focus()}},mounted(){this.aerizController=o.createEditorController(this.$el,this.aerizProps()),r(this,()=>{var e;return(e=this.aerizController)==null?void 0:e.update(this.aerizProps())})},beforeDestroy(){var e;(e=this.aerizController)==null||e.destroy(),this.aerizController=null},render(e){return e("div")}},a={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}},data(){return{aerizController:null}},methods:{aerizProps(){const e=this.$props,t={onReady:i=>this.$emit("ready",i)};return e.blocks!==void 0&&(t.blocks=e.blocks),e.html!==void 0&&(t.html=e.html),e.theme!==void 0&&(t.theme=e.theme),e.htmlStyles!==void 0&&(t.htmlStyles=e.htmlStyles),t},getViewer(){var e;return((e=this.aerizController)==null?void 0:e.viewer)??null}},mounted(){this.aerizController=o.createViewerController(this.$el,this.aerizProps()),r(this,()=>{var e;return(e=this.aerizController)==null?void 0:e.update(this.aerizProps())})},beforeDestroy(){var e;(e=this.aerizController)==null||e.destroy(),this.aerizController=null},render(e){return e("div")}},d={install(e){e.component("AerizEditor",l),e.component("AerizViewer",a)}};exports.AerizEditor=l;exports.AerizViewer=a;exports.AerizWysiwygPlugin=d;
@@ -0,0 +1,117 @@
1
+ import { createEditorController as l, createViewerController as r } from "./shared.js";
2
+ function o(e, t) {
3
+ e.$watch(
4
+ () => ({ ...e.$props }),
5
+ t,
6
+ { deep: !1 }
7
+ );
8
+ }
9
+ const a = {
10
+ name: "AerizEditor",
11
+ props: {
12
+ /** `v-model` 바인딩 값 (HTML). */
13
+ value: { type: String, default: void 0 },
14
+ initialHTML: { type: String, default: void 0 },
15
+ placeholder: { type: String, default: void 0 },
16
+ toolbar: { type: [Object, Boolean], default: void 0 },
17
+ theme: { type: String, default: void 0 },
18
+ locale: { type: String, default: void 0 },
19
+ /** `getHTML()` · `onChange` 출력 전략. 기본 `'inline'`. */
20
+ htmlStyles: { type: String, default: void 0 },
21
+ onImageUpload: { type: Function, default: void 0 },
22
+ imageUploadUrl: { type: String, default: void 0 },
23
+ onFileUpload: { type: Function, default: void 0 },
24
+ fileUploadUrl: { type: String, default: void 0 }
25
+ },
26
+ data() {
27
+ return { aerizController: null };
28
+ },
29
+ methods: {
30
+ aerizProps() {
31
+ const e = this.$props, t = {
32
+ onChange: (i) => {
33
+ this.$emit("input", i), this.$emit("change", i);
34
+ },
35
+ onStateChange: (i) => this.$emit("state-change", i),
36
+ onReady: (i) => this.$emit("ready", i)
37
+ };
38
+ return e.value !== void 0 && (t.value = e.value), e.initialHTML !== void 0 && (t.initialHTML = e.initialHTML), e.placeholder !== void 0 && (t.placeholder = e.placeholder), e.toolbar !== void 0 && (t.toolbar = e.toolbar), e.theme !== void 0 && (t.theme = e.theme), e.locale !== void 0 && (t.locale = e.locale), e.htmlStyles !== void 0 && (t.htmlStyles = e.htmlStyles), e.onImageUpload !== void 0 && (t.onImageUpload = e.onImageUpload), e.imageUploadUrl !== void 0 && (t.imageUploadUrl = e.imageUploadUrl), e.onFileUpload !== void 0 && (t.onFileUpload = e.onFileUpload), e.fileUploadUrl !== void 0 && (t.fileUploadUrl = e.fileUploadUrl), t;
39
+ },
40
+ /** 코어 인스턴스. `this.$refs.editor.getEditor()` 로 접근한다. */
41
+ getEditor() {
42
+ var e;
43
+ return ((e = this.aerizController) == null ? void 0 : e.editor) ?? null;
44
+ },
45
+ getHTML() {
46
+ var e;
47
+ return ((e = this.aerizController) == null ? void 0 : e.editor.getHTML()) ?? "";
48
+ },
49
+ setHTML(e) {
50
+ var t;
51
+ (t = this.aerizController) == null || t.editor.setHTML(e);
52
+ },
53
+ focus() {
54
+ var e;
55
+ (e = this.aerizController) == null || e.editor.focus();
56
+ }
57
+ },
58
+ mounted() {
59
+ this.aerizController = l(this.$el, this.aerizProps()), o(this, () => {
60
+ var e;
61
+ return (e = this.aerizController) == null ? void 0 : e.update(this.aerizProps());
62
+ });
63
+ },
64
+ beforeDestroy() {
65
+ var e;
66
+ (e = this.aerizController) == null || e.destroy(), this.aerizController = null;
67
+ },
68
+ render(e) {
69
+ return e("div");
70
+ }
71
+ }, d = {
72
+ name: "AerizViewer",
73
+ props: {
74
+ blocks: { type: Array, default: void 0 },
75
+ html: { type: String, default: void 0 },
76
+ theme: { type: String, default: void 0 },
77
+ /** `getHTML()` 출력 전략. 기본 `'inline'`. */
78
+ htmlStyles: { type: String, default: void 0 }
79
+ },
80
+ data() {
81
+ return { aerizController: null };
82
+ },
83
+ methods: {
84
+ aerizProps() {
85
+ const e = this.$props, t = {
86
+ onReady: (i) => this.$emit("ready", i)
87
+ };
88
+ return e.blocks !== void 0 && (t.blocks = e.blocks), e.html !== void 0 && (t.html = e.html), e.theme !== void 0 && (t.theme = e.theme), e.htmlStyles !== void 0 && (t.htmlStyles = e.htmlStyles), t;
89
+ },
90
+ getViewer() {
91
+ var e;
92
+ return ((e = this.aerizController) == null ? void 0 : e.viewer) ?? null;
93
+ }
94
+ },
95
+ mounted() {
96
+ this.aerizController = r(this.$el, this.aerizProps()), o(this, () => {
97
+ var e;
98
+ return (e = this.aerizController) == null ? void 0 : e.update(this.aerizProps());
99
+ });
100
+ },
101
+ beforeDestroy() {
102
+ var e;
103
+ (e = this.aerizController) == null || e.destroy(), this.aerizController = null;
104
+ },
105
+ render(e) {
106
+ return e("div");
107
+ }
108
+ }, s = {
109
+ install(e) {
110
+ e.component("AerizEditor", a), e.component("AerizViewer", d);
111
+ }
112
+ };
113
+ export {
114
+ a as AerizEditor,
115
+ d as AerizViewer,
116
+ s as AerizWysiwygPlugin
117
+ };
@@ -0,0 +1 @@
1
+ "use strict";var b=Object.defineProperty;var v=(e,l,t)=>l in e?b(e,l,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[l]=t;var r=(e,l,t)=>v(e,typeof l!="symbol"?l+"":l,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("./shared.cjs"),y=["light","dark"],E=["en","ko","ja","zh"];function f(e){return e!==null&&y.includes(e)?e:void 0}function A(e){return e!==null&&E.includes(e)?e:void 0}function V(e){if(e===null)return;const l=e.trim();if(l==="")return;if(l==="false"||l==="none")return!1;if(l.startsWith("{")){try{const i=JSON.parse(l);if(i&&typeof i=="object"&&Array.isArray(i.items))return i}catch{}return}const t=l.split(/[\s,]+/).filter(i=>i.length>0);return t.length>0?{items:t}:void 0}function k(e){const l=e.attachInternals;if(typeof l!="function")return null;try{const t=l.call(e);return typeof t=="object"&&t!==null&&typeof t.setFormValue=="function"?t:null}catch{return null}}class a extends HTMLElement{constructor(){super();r(this,"onImageUpload");r(this,"onFileUpload");r(this,"controller",null);r(this,"internals",null);r(this,"pendingValue");r(this,"currentHTML","");this.internals=k(this)}static get observedAttributes(){return["value","placeholder","theme","locale","toolbar","html-styles","image-upload-url","file-upload-url"]}get value(){return this.controller?this.controller.editor.getHTML():this.pendingValue??this.currentHTML}set value(t){this.pendingValue=t,this.applyProps()}get editor(){var t;return((t=this.controller)==null?void 0:t.editor)??null}getBlocks(){var t;return((t=this.controller)==null?void 0:t.editor.serialize())??[]}focus(){var t;(t=this.controller)==null||t.editor.focus()}connectedCallback(){if(!this.controller){if(this.pendingValue===void 0){const t=this.getAttribute("value");t!==null&&(this.pendingValue=t)}this.controller=p.createEditorController(this,this.buildProps()),this.pendingValue=void 0,this.syncFormValue(this.controller.editor.getHTML()),this.dispatchEvent(new CustomEvent("aeriz-ready",{detail:{editor:this.controller.editor},bubbles:!1}))}}disconnectedCallback(){var t;(t=this.controller)==null||t.destroy(),this.controller=null}attributeChangedCallback(t,i,n){t==="value"&&(this.pendingValue=n??""),this.applyProps()}applyProps(){this.controller&&(this.controller.update(this.buildProps()),this.pendingValue=void 0)}buildProps(){const t={onChange:s=>{this.pendingValue=void 0,this.syncFormValue(s),this.dispatchEvent(new CustomEvent("input",{detail:{html:s},bubbles:!0})),this.dispatchEvent(new CustomEvent("change",{detail:{html:s},bubbles:!0}))}};this.pendingValue!==void 0&&(t.value=this.pendingValue);const i=this.getAttribute("placeholder");i!==null&&(t.placeholder=i);const n=f(this.getAttribute("theme"));n!==void 0&&(t.theme=n);const u=A(this.getAttribute("locale"));u!==void 0&&(t.locale=u);const c=V(this.getAttribute("toolbar"));c!==void 0&&(t.toolbar=c);const o=this.getAttribute("html-styles");(o==="class"||o==="inline")&&(t.htmlStyles=o);const d=this.getAttribute("image-upload-url");d!==null&&(t.imageUploadUrl=d);const h=this.getAttribute("file-upload-url");return h!==null&&(t.fileUploadUrl=h),this.onImageUpload&&(t.onImageUpload=this.onImageUpload),this.onFileUpload&&(t.onFileUpload=this.onFileUpload),t}syncFormValue(t){var i;this.currentHTML=t,(i=this.internals)==null||i.setFormValue(t)}}r(a,"formAssociated",!0);class g extends HTMLElement{constructor(){super(...arguments);r(this,"controller",null);r(this,"pendingBlocks")}static get observedAttributes(){return["html","theme"]}get blocks(){var t;return((t=this.controller)==null?void 0:t.viewer.getBlocks())??this.pendingBlocks??[]}set blocks(t){var i;this.pendingBlocks=t,(i=this.controller)==null||i.update(this.buildProps())}get viewer(){var t;return((t=this.controller)==null?void 0:t.viewer)??null}connectedCallback(){this.controller||(this.controller=p.createViewerController(this,this.buildProps()),this.dispatchEvent(new CustomEvent("aeriz-ready",{detail:{viewer:this.controller.viewer},bubbles:!1})))}disconnectedCallback(){var t;(t=this.controller)==null||t.destroy(),this.controller=null}attributeChangedCallback(){var t;(t=this.controller)==null||t.update(this.buildProps())}buildProps(){const t={};this.pendingBlocks!==void 0&&(t.blocks=this.pendingBlocks);const i=this.getAttribute("html");i!==null&&(t.html=i);const n=f(this.getAttribute("theme"));return n!==void 0&&(t.theme=n),t}}function m(e="aeriz"){if(typeof customElements>"u")return;const l=`${e}-editor`,t=`${e}-viewer`;customElements.get(l)||customElements.define(l,a),customElements.get(t)||customElements.define(t,g)}m();exports.AerizEditorElement=a;exports.AerizViewerElement=g;exports.defineAerizElements=m;
@@ -0,0 +1,207 @@
1
+ var f = Object.defineProperty;
2
+ var g = (e, l, t) => l in e ? f(e, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[l] = t;
3
+ var r = (e, l, t) => g(e, typeof l != "symbol" ? l + "" : l, t);
4
+ import { createEditorController as m, createViewerController as b } from "./shared.js";
5
+ const v = ["light", "dark"], y = ["en", "ko", "ja", "zh"];
6
+ function h(e) {
7
+ return e !== null && v.includes(e) ? e : void 0;
8
+ }
9
+ function E(e) {
10
+ return e !== null && y.includes(e) ? e : void 0;
11
+ }
12
+ function k(e) {
13
+ if (e === null) return;
14
+ const l = e.trim();
15
+ if (l === "") return;
16
+ if (l === "false" || l === "none") return !1;
17
+ if (l.startsWith("{")) {
18
+ try {
19
+ const i = JSON.parse(l);
20
+ if (i && typeof i == "object" && Array.isArray(i.items))
21
+ return i;
22
+ } catch {
23
+ }
24
+ return;
25
+ }
26
+ const t = l.split(/[\s,]+/).filter((i) => i.length > 0);
27
+ return t.length > 0 ? { items: t } : void 0;
28
+ }
29
+ function A(e) {
30
+ const l = e.attachInternals;
31
+ if (typeof l != "function") return null;
32
+ try {
33
+ const t = l.call(e);
34
+ return typeof t == "object" && t !== null && typeof t.setFormValue == "function" ? t : null;
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+ class p extends HTMLElement {
40
+ constructor() {
41
+ super();
42
+ /** 프로퍼티로 설정된 업로드 핸들러. 속성으로는 표현할 수 없다. */
43
+ r(this, "onImageUpload");
44
+ r(this, "onFileUpload");
45
+ r(this, "controller", null);
46
+ r(this, "internals", null);
47
+ /**
48
+ * 아직 에디터에 반영되지 않은 **외부에서 지정한** 값.
49
+ *
50
+ * 반영이 끝나면 즉시 비운다. 이 값이 남아 있으면 관계없는 속성(`theme` 등) 이
51
+ * 바뀔 때마다 낡은 값이 `setHTML()` 로 다시 밀려들어가, 모든 블록 id 가
52
+ * 재발급되고 입력 중이던 캐럿이 문서 맨 앞으로 튄다.
53
+ */
54
+ r(this, "pendingValue");
55
+ /** 에디터가 마지막으로 보고한 본문. 폼 값과 마운트 해제 후 `value` 의 근거. */
56
+ r(this, "currentHTML", "");
57
+ this.internals = A(this);
58
+ }
59
+ static get observedAttributes() {
60
+ return [
61
+ "value",
62
+ "placeholder",
63
+ "theme",
64
+ "locale",
65
+ "toolbar",
66
+ "html-styles",
67
+ "image-upload-url",
68
+ "file-upload-url"
69
+ ];
70
+ }
71
+ /** 현재 본문 HTML. 설정하면 본문을 교체한다. */
72
+ get value() {
73
+ return this.controller ? this.controller.editor.getHTML() : this.pendingValue ?? this.currentHTML;
74
+ }
75
+ set value(t) {
76
+ this.pendingValue = t, this.applyProps();
77
+ }
78
+ /** 코어 인스턴스. 마운트 전에는 `null`. */
79
+ get editor() {
80
+ var t;
81
+ return ((t = this.controller) == null ? void 0 : t.editor) ?? null;
82
+ }
83
+ /** 블록 상태 스냅샷. */
84
+ getBlocks() {
85
+ var t;
86
+ return ((t = this.controller) == null ? void 0 : t.editor.serialize()) ?? [];
87
+ }
88
+ /** 본문에 캐럿을 둔다. `HTMLElement.focus()` 를 본문 쪽으로 위임한다. */
89
+ focus() {
90
+ var t;
91
+ (t = this.controller) == null || t.editor.focus();
92
+ }
93
+ connectedCallback() {
94
+ if (!this.controller) {
95
+ if (this.pendingValue === void 0) {
96
+ const t = this.getAttribute("value");
97
+ t !== null && (this.pendingValue = t);
98
+ }
99
+ this.controller = m(this, this.buildProps()), this.pendingValue = void 0, this.syncFormValue(this.controller.editor.getHTML()), this.dispatchEvent(
100
+ new CustomEvent("aeriz-ready", {
101
+ detail: { editor: this.controller.editor },
102
+ bubbles: !1
103
+ })
104
+ );
105
+ }
106
+ }
107
+ disconnectedCallback() {
108
+ var t;
109
+ (t = this.controller) == null || t.destroy(), this.controller = null;
110
+ }
111
+ attributeChangedCallback(t, i, o) {
112
+ t === "value" && (this.pendingValue = o ?? ""), this.applyProps();
113
+ }
114
+ /**
115
+ * 현재 속성·프로퍼티 상태를 컨트롤러에 반영한다.
116
+ * 반영 직후 pendingValue 를 비워, 다음 갱신에서 같은 값이 되살아나지 않게 한다.
117
+ */
118
+ applyProps() {
119
+ this.controller && (this.controller.update(this.buildProps()), this.pendingValue = void 0);
120
+ }
121
+ buildProps() {
122
+ const t = {
123
+ onChange: (s) => {
124
+ this.pendingValue = void 0, this.syncFormValue(s), this.dispatchEvent(new CustomEvent("input", { detail: { html: s }, bubbles: !0 })), this.dispatchEvent(new CustomEvent("change", { detail: { html: s }, bubbles: !0 }));
125
+ }
126
+ };
127
+ this.pendingValue !== void 0 && (t.value = this.pendingValue);
128
+ const i = this.getAttribute("placeholder");
129
+ i !== null && (t.placeholder = i);
130
+ const o = h(this.getAttribute("theme"));
131
+ o !== void 0 && (t.theme = o);
132
+ const u = E(this.getAttribute("locale"));
133
+ u !== void 0 && (t.locale = u);
134
+ const a = k(this.getAttribute("toolbar"));
135
+ a !== void 0 && (t.toolbar = a);
136
+ const n = this.getAttribute("html-styles");
137
+ (n === "class" || n === "inline") && (t.htmlStyles = n);
138
+ const c = this.getAttribute("image-upload-url");
139
+ c !== null && (t.imageUploadUrl = c);
140
+ const d = this.getAttribute("file-upload-url");
141
+ return d !== null && (t.fileUploadUrl = d), this.onImageUpload && (t.onImageUpload = this.onImageUpload), this.onFileUpload && (t.onFileUpload = this.onFileUpload), t;
142
+ }
143
+ syncFormValue(t) {
144
+ var i;
145
+ this.currentHTML = t, (i = this.internals) == null || i.setFormValue(t);
146
+ }
147
+ }
148
+ /** 폼 연동 대상임을 선언. 미지원 브라우저는 이 필드를 무시한다. */
149
+ r(p, "formAssociated", !0);
150
+ class V extends HTMLElement {
151
+ constructor() {
152
+ super(...arguments);
153
+ r(this, "controller", null);
154
+ r(this, "pendingBlocks");
155
+ }
156
+ static get observedAttributes() {
157
+ return ["html", "theme"];
158
+ }
159
+ /** 블록 상태를 직접 넣는다. `html` 속성보다 우선한다. */
160
+ get blocks() {
161
+ var t;
162
+ return ((t = this.controller) == null ? void 0 : t.viewer.getBlocks()) ?? this.pendingBlocks ?? [];
163
+ }
164
+ set blocks(t) {
165
+ var i;
166
+ this.pendingBlocks = t, (i = this.controller) == null || i.update(this.buildProps());
167
+ }
168
+ get viewer() {
169
+ var t;
170
+ return ((t = this.controller) == null ? void 0 : t.viewer) ?? null;
171
+ }
172
+ connectedCallback() {
173
+ this.controller || (this.controller = b(this, this.buildProps()), this.dispatchEvent(
174
+ new CustomEvent("aeriz-ready", {
175
+ detail: { viewer: this.controller.viewer },
176
+ bubbles: !1
177
+ })
178
+ ));
179
+ }
180
+ disconnectedCallback() {
181
+ var t;
182
+ (t = this.controller) == null || t.destroy(), this.controller = null;
183
+ }
184
+ attributeChangedCallback() {
185
+ var t;
186
+ (t = this.controller) == null || t.update(this.buildProps());
187
+ }
188
+ buildProps() {
189
+ const t = {};
190
+ this.pendingBlocks !== void 0 && (t.blocks = this.pendingBlocks);
191
+ const i = this.getAttribute("html");
192
+ i !== null && (t.html = i);
193
+ const o = h(this.getAttribute("theme"));
194
+ return o !== void 0 && (t.theme = o), t;
195
+ }
196
+ }
197
+ function C(e = "aeriz") {
198
+ if (typeof customElements > "u") return;
199
+ const l = `${e}-editor`, t = `${e}-viewer`;
200
+ customElements.get(l) || customElements.define(l, p), customElements.get(t) || customElements.define(t, V);
201
+ }
202
+ C();
203
+ export {
204
+ p as AerizEditorElement,
205
+ V as AerizViewerElement,
206
+ C as defineAerizElements
207
+ };
@@ -0,0 +1,169 @@
1
+ var AerizWysiwygAdapter = function(exports, wysiwyg) {
2
+ "use strict";
3
+ function htmlToBlocks(html) {
4
+ const scratch = document.createElement("div");
5
+ scratch.innerHTML = html;
6
+ wysiwyg.normalizeContent(scratch);
7
+ const ids = new wysiwyg.BlockIdRegistry();
8
+ wysiwyg.assignMissingIds(scratch, ids);
9
+ return wysiwyg.serializeBlocks(wysiwyg.listBlocks(scratch, (el) => ids.ensure(el)));
10
+ }
11
+ function toEditorOptions(element, props, onChange) {
12
+ const options = { element, onChange };
13
+ const initial = props.value ?? props.initialHTML;
14
+ if (initial !== void 0) options.initialHTML = initial;
15
+ if (props.placeholder !== void 0) options.placeholder = props.placeholder;
16
+ if (props.toolbar !== void 0) options.toolbar = props.toolbar;
17
+ if (props.theme !== void 0) options.theme = props.theme;
18
+ if (props.locale !== void 0) options.locale = props.locale;
19
+ if (props.htmlStyles !== void 0) options.htmlStyles = props.htmlStyles;
20
+ if (props.onImageUpload !== void 0) options.onImageUpload = props.onImageUpload;
21
+ if (props.imageUploadUrl !== void 0) options.imageUploadUrl = props.imageUploadUrl;
22
+ if (props.onFileUpload !== void 0) options.onFileUpload = props.onFileUpload;
23
+ if (props.fileUploadUrl !== void 0) options.fileUploadUrl = props.fileUploadUrl;
24
+ return options;
25
+ }
26
+ function sameToolbar(a, b) {
27
+ if (a === b) return true;
28
+ if (a === false || b === false || a === void 0 || b === void 0) {
29
+ return false;
30
+ }
31
+ if (a.sticky !== b.sticky) return false;
32
+ if (a.items.length !== b.items.length) return false;
33
+ return a.items.every((item, i) => item === b.items[i]);
34
+ }
35
+ function createEditorController(host, initialProps) {
36
+ let props = initialProps;
37
+ let lastHTML = "";
38
+ let silent = false;
39
+ let disposed = false;
40
+ const emitChange = (html) => {
41
+ var _a;
42
+ lastHTML = html;
43
+ if (silent) return;
44
+ (_a = props.onChange) == null ? void 0 : _a.call(props, html);
45
+ };
46
+ let editor;
47
+ let unsubscribe = null;
48
+ let liveOptions;
49
+ const syncLazyOptions = (next) => {
50
+ if (next.onImageUpload === void 0) delete liveOptions.onImageUpload;
51
+ else liveOptions.onImageUpload = next.onImageUpload;
52
+ if (next.imageUploadUrl === void 0) delete liveOptions.imageUploadUrl;
53
+ else liveOptions.imageUploadUrl = next.imageUploadUrl;
54
+ if (next.onFileUpload === void 0) delete liveOptions.onFileUpload;
55
+ else liveOptions.onFileUpload = next.onFileUpload;
56
+ if (next.fileUploadUrl === void 0) delete liveOptions.fileUploadUrl;
57
+ else liveOptions.fileUploadUrl = next.fileUploadUrl;
58
+ if (next.htmlStyles === void 0) delete liveOptions.htmlStyles;
59
+ else liveOptions.htmlStyles = next.htmlStyles;
60
+ };
61
+ const create = (from, html) => {
62
+ var _a;
63
+ const seed = html !== void 0 ? { ...from, value: html } : from;
64
+ liveOptions = toEditorOptions(host, seed, emitChange);
65
+ editor = new wysiwyg.AerizEditor(liveOptions);
66
+ lastHTML = editor.getHTML();
67
+ unsubscribe = editor.onStateChange((state) => {
68
+ var _a2;
69
+ return (_a2 = props.onStateChange) == null ? void 0 : _a2.call(props, state);
70
+ });
71
+ (_a = props.onReady) == null ? void 0 : _a.call(props, editor);
72
+ };
73
+ const teardown = () => {
74
+ var _a;
75
+ (_a = props.onDestroy) == null ? void 0 : _a.call(props, editor);
76
+ unsubscribe == null ? void 0 : unsubscribe();
77
+ unsubscribe = null;
78
+ editor.destroy();
79
+ };
80
+ create(props);
81
+ return {
82
+ get editor() {
83
+ return editor;
84
+ },
85
+ update(next) {
86
+ if (disposed) return;
87
+ const prev = props;
88
+ props = next;
89
+ if (next.locale !== prev.locale || !sameToolbar(next.toolbar, prev.toolbar)) {
90
+ const carried = next.value ?? editor.getHTML();
91
+ teardown();
92
+ create(next, carried);
93
+ return;
94
+ }
95
+ syncLazyOptions(next);
96
+ if (next.theme !== prev.theme && next.theme !== void 0) {
97
+ editor.setTheme(next.theme);
98
+ }
99
+ if (next.placeholder !== prev.placeholder) {
100
+ if (next.placeholder === void 0) {
101
+ delete editor.content.dataset.placeholder;
102
+ } else {
103
+ editor.content.dataset.placeholder = next.placeholder;
104
+ }
105
+ }
106
+ if (next.value !== void 0 && next.value !== lastHTML && next.value !== editor.getHTML()) {
107
+ silent = true;
108
+ try {
109
+ editor.setHTML(next.value);
110
+ } finally {
111
+ silent = false;
112
+ }
113
+ lastHTML = next.value;
114
+ }
115
+ },
116
+ destroy() {
117
+ if (disposed) return;
118
+ disposed = true;
119
+ teardown();
120
+ }
121
+ };
122
+ }
123
+ function toViewerOptions(element, props) {
124
+ const options = { element };
125
+ const blocks = props.blocks ?? (props.html !== void 0 ? htmlToBlocks(props.html) : void 0);
126
+ if (blocks !== void 0) options.initialBlocks = blocks;
127
+ if (props.theme !== void 0) options.theme = props.theme;
128
+ if (props.htmlStyles !== void 0) options.htmlStyles = props.htmlStyles;
129
+ return options;
130
+ }
131
+ function createViewerController(host, initialProps) {
132
+ var _a;
133
+ let props = initialProps;
134
+ let disposed = false;
135
+ const liveOptions = toViewerOptions(host, initialProps);
136
+ const viewer = new wysiwyg.AerizViewer(liveOptions);
137
+ (_a = props.onReady) == null ? void 0 : _a.call(props, viewer);
138
+ return {
139
+ viewer,
140
+ update(next) {
141
+ if (disposed) return;
142
+ const prev = props;
143
+ props = next;
144
+ if (next.theme !== prev.theme && next.theme !== void 0) {
145
+ viewer.setTheme(next.theme);
146
+ }
147
+ if (next.htmlStyles === void 0) delete liveOptions.htmlStyles;
148
+ else liveOptions.htmlStyles = next.htmlStyles;
149
+ if (next.blocks !== void 0) {
150
+ if (next.blocks !== prev.blocks) viewer.setBlocks(next.blocks);
151
+ } else if (next.html !== void 0 && next.html !== prev.html) {
152
+ if (next.html !== viewer.getHTML()) viewer.setBlocks(htmlToBlocks(next.html));
153
+ }
154
+ },
155
+ destroy() {
156
+ var _a2;
157
+ if (disposed) return;
158
+ disposed = true;
159
+ (_a2 = props.onDestroy) == null ? void 0 : _a2.call(props, viewer);
160
+ viewer.destroy();
161
+ }
162
+ };
163
+ }
164
+ exports.createEditorController = createEditorController;
165
+ exports.createViewerController = createViewerController;
166
+ exports.htmlToBlocks = htmlToBlocks;
167
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
168
+ return exports;
169
+ }({}, AerizWysiwyg);
@@ -0,0 +1 @@
1
+ var AerizWysiwygAdapter=function(m,s){"use strict";function v(a){const e=document.createElement("div");e.innerHTML=a,s.normalizeContent(e);const t=new s.BlockIdRegistry;return s.assignMissingIds(e,t),s.serializeBlocks(s.listBlocks(e,o=>t.ensure(o)))}function k(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 T(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 h=l=>{var c;o=l,!n&&((c=t.onChange)==null||c.call(t,l))};let i,f=null,r;const H=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,c)=>{var y;const u=c!==void 0?{...l,value:c}:l;r=k(a,u,h),i=new s.AerizEditor(r),o=i.getHTML(),f=i.onStateChange(I=>{var S;return(S=t.onStateChange)==null?void 0:S.call(t,I)}),(y=t.onReady)==null||y.call(t,i)},g=()=>{var l;(l=t.onDestroy)==null||l.call(t,i),f==null||f(),f=null,i.destroy()};return U(t),{get editor(){return i},update(l){if(d)return;const c=t;if(t=l,l.locale!==c.locale||!T(l.toolbar,c.toolbar)){const u=l.value??i.getHTML();g(),U(l,u);return}if(H(l),l.theme!==c.theme&&l.theme!==void 0&&i.setTheme(l.theme),l.placeholder!==c.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,g())}}}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 h;let t=e,o=!1;const n=L(a,e),d=new s.AerizViewer(n);return(h=t.onReady)==null||h.call(t,d),{viewer:d,update(i){if(o)return;const f=t;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(v(i.html))},destroy(){var i;o||(o=!0,(i=t.onDestroy)==null||i.call(t,d),d.destroy())}}}return m.createEditorController=M,m.createViewerController=C,m.htmlToBlocks=v,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"}),m}({},AerizWysiwyg);