@liwe3/webcomponents 1.0.14 → 1.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AIMarkdownEditor.d.ts +35 -0
- package/dist/AIMarkdownEditor.d.ts.map +1 -0
- package/dist/AIMarkdownEditor.js +412 -0
- package/dist/AIMarkdownEditor.js.map +1 -0
- package/dist/AITextEditor.d.ts +183 -0
- package/dist/AITextEditor.d.ts.map +1 -0
- package/dist/AITextEditor.js +63 -27
- package/dist/AITextEditor.js.map +1 -1
- package/dist/ButtonToolbar.d.ts +35 -0
- package/dist/ButtonToolbar.d.ts.map +1 -0
- package/dist/ButtonToolbar.js +220 -0
- package/dist/ButtonToolbar.js.map +1 -0
- package/dist/CheckList.d.ts +31 -0
- package/dist/CheckList.d.ts.map +1 -0
- package/dist/CheckList.js +336 -0
- package/dist/CheckList.js.map +1 -0
- package/dist/ChunkUploader.d.ts +125 -0
- package/dist/ChunkUploader.d.ts.map +1 -0
- package/dist/ChunkUploader.js +756 -0
- package/dist/ChunkUploader.js.map +1 -0
- package/dist/ComicBalloon.d.ts +82 -0
- package/dist/ComicBalloon.d.ts.map +1 -0
- package/dist/ComicBalloon.js +346 -0
- package/dist/ComicBalloon.js.map +1 -0
- package/dist/ContainerBox.d.ts +112 -0
- package/dist/ContainerBox.d.ts.map +1 -0
- package/dist/ContainerBox.js +359 -0
- package/dist/ContainerBox.js.map +1 -0
- package/dist/DateSelector.d.ts +103 -0
- package/dist/DateSelector.d.ts.map +1 -0
- package/dist/Dialog.d.ts +102 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +299 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/Drawer.d.ts +63 -0
- package/dist/Drawer.d.ts.map +1 -0
- package/dist/Drawer.js +340 -0
- package/dist/Drawer.js.map +1 -0
- package/dist/ImageView.d.ts +42 -0
- package/dist/ImageView.d.ts.map +1 -0
- package/dist/ImageView.js +209 -0
- package/dist/ImageView.js.map +1 -0
- package/dist/MarkdownPreview.d.ts +25 -0
- package/dist/MarkdownPreview.d.ts.map +1 -0
- package/dist/MarkdownPreview.js +147 -0
- package/dist/MarkdownPreview.js.map +1 -0
- package/dist/PopoverMenu.d.ts +103 -0
- package/dist/PopoverMenu.d.ts.map +1 -0
- package/dist/ResizableCropper.d.ts +158 -0
- package/dist/ResizableCropper.d.ts.map +1 -0
- package/dist/ResizableCropper.js +562 -0
- package/dist/ResizableCropper.js.map +1 -0
- package/dist/SmartSelect.d.ts +100 -0
- package/dist/SmartSelect.d.ts.map +1 -0
- package/dist/SmartSelect.js +45 -2
- package/dist/SmartSelect.js.map +1 -1
- package/dist/Toast.d.ts +127 -0
- package/dist/Toast.d.ts.map +1 -0
- package/dist/Toast.js +79 -49
- package/dist/Toast.js.map +1 -1
- package/dist/TreeView.d.ts +84 -0
- package/dist/TreeView.d.ts.map +1 -0
- package/dist/TreeView.js +478 -0
- package/dist/TreeView.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -14
- package/dist/index.js.map +1 -1
- package/package.json +60 -5
- package/src/AIMarkdownEditor.ts +568 -0
- package/src/AITextEditor.ts +97 -2
- package/src/ButtonToolbar.ts +302 -0
- package/src/CheckList.ts +438 -0
- package/src/ChunkUploader.ts +1135 -0
- package/src/ComicBalloon.ts +709 -0
- package/src/ContainerBox.ts +570 -0
- package/src/Dialog.ts +510 -0
- package/src/Drawer.ts +435 -0
- package/src/ImageView.ts +265 -0
- package/src/MarkdownPreview.ts +213 -0
- package/src/ResizableCropper.ts +1099 -0
- package/src/SmartSelect.ts +48 -2
- package/src/Toast.ts +96 -32
- package/src/TreeView.ts +673 -0
- package/src/index.ts +129 -27
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare class AIMarkdownEditorElement extends HTMLElement {
|
|
2
|
+
shadowRoot: ShadowRoot;
|
|
3
|
+
private aiEditor;
|
|
4
|
+
private toolbar;
|
|
5
|
+
private preview;
|
|
6
|
+
private editorStatus;
|
|
7
|
+
private loading;
|
|
8
|
+
private isPreviewMode;
|
|
9
|
+
private markdownLibUrl;
|
|
10
|
+
constructor();
|
|
11
|
+
connectedCallback(): void;
|
|
12
|
+
private render;
|
|
13
|
+
private init;
|
|
14
|
+
private setupModal;
|
|
15
|
+
private openSettings;
|
|
16
|
+
private setupToolbar;
|
|
17
|
+
private togglePreview;
|
|
18
|
+
private handleToolbarAction;
|
|
19
|
+
setText(text: string): void;
|
|
20
|
+
getText(): string;
|
|
21
|
+
setApiKey(key: string): void;
|
|
22
|
+
getApiKey(): string;
|
|
23
|
+
setSuggestionDelay(seconds: number): void;
|
|
24
|
+
getSuggestionDelay(): number;
|
|
25
|
+
setSystemPrompt(prompt: string): void;
|
|
26
|
+
getSystemPrompt(): string;
|
|
27
|
+
setApiEndpoint(endpoint: string): void;
|
|
28
|
+
getApiEndpoint(): string;
|
|
29
|
+
setModelName(modelName: string): void;
|
|
30
|
+
getModelName(): string;
|
|
31
|
+
setContext(context: string): void;
|
|
32
|
+
getContext(): string;
|
|
33
|
+
}
|
|
34
|
+
export declare const defineAIMarkdownEditor: (tagName?: string) => void;
|
|
35
|
+
//# sourceMappingURL=AIMarkdownEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIMarkdownEditor.d.ts","sourceRoot":"","sources":["../src/AIMarkdownEditor.ts"],"names":[],"mappings":"AAIA,qBAAa,uBAAwB,SAAQ,WAAW;IAC9C,UAAU,EAAE,UAAU,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,cAAc,CAAqE;;IAO3F,iBAAiB,IAAI,IAAI;IAKzB,OAAO,CAAC,MAAM;IA4Md,OAAO,CAAC,IAAI;IA4CZ,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,YAAY;IAkEpB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,mBAAmB;IAqF3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,OAAO,IAAI,MAAM;IAIjB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM5B,SAAS,IAAI,MAAM;IAInB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMzC,kBAAkB,IAAI,MAAM;IAI5B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMrC,eAAe,IAAI,MAAM;IAIzB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMtC,cAAc,IAAI,MAAM;IAIxB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMrC,YAAY,IAAI,MAAM;IAItB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMjC,UAAU,IAAI,MAAM;CAGrB;AAED,eAAO,MAAM,sBAAsB,GAAI,UAAS,MAAmC,KAAG,IASrF,CAAC"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { defineAITextEditor as c } from "./AITextEditor.js";
|
|
2
|
+
import { defineButtonToolbar as m } from "./ButtonToolbar.js";
|
|
3
|
+
import { defineMarkdownPreview as u } from "./MarkdownPreview.js";
|
|
4
|
+
class v extends HTMLElement {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(), this.isPreviewMode = !1, this.markdownLibUrl = "https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js", this.attachShadow({ mode: "open" });
|
|
7
|
+
}
|
|
8
|
+
connectedCallback() {
|
|
9
|
+
this.render(), this.init();
|
|
10
|
+
}
|
|
11
|
+
render() {
|
|
12
|
+
this.shadowRoot.innerHTML = `
|
|
13
|
+
<style>
|
|
14
|
+
:host {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
width: 100%;
|
|
18
|
+
height: 100%;
|
|
19
|
+
gap: 0.5rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.editor-container {
|
|
23
|
+
flex: 1;
|
|
24
|
+
position: relative;
|
|
25
|
+
min-height: 0; /* Important for flexbox scrolling */
|
|
26
|
+
border: 2px solid #e1e5e9;
|
|
27
|
+
border-radius: 12px;
|
|
28
|
+
background: #fafbfc;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.editor-container:focus-within {
|
|
32
|
+
border-color: #4facfe;
|
|
33
|
+
background: white;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.editor-status {
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 5px;
|
|
39
|
+
left: 5px;
|
|
40
|
+
width: 10px;
|
|
41
|
+
height: 10px;
|
|
42
|
+
border-radius: 100%;
|
|
43
|
+
background: #777;
|
|
44
|
+
z-index: 10;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.loading {
|
|
48
|
+
position: absolute;
|
|
49
|
+
top: 5px;
|
|
50
|
+
right: 10px;
|
|
51
|
+
z-index: 10;
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.loading.show {
|
|
56
|
+
display: block;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.spinner {
|
|
60
|
+
width: 10px;
|
|
61
|
+
height: 10px;
|
|
62
|
+
border: 2px solid #e1e5e9;
|
|
63
|
+
border-top: 2px solid #4facfe;
|
|
64
|
+
border-radius: 50%;
|
|
65
|
+
animation: spin 1s linear infinite;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@keyframes spin {
|
|
69
|
+
0% { transform: rotate(0deg); }
|
|
70
|
+
100% { transform: rotate(360deg); }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
liwe3-ai-text-editor {
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.settings-modal {
|
|
79
|
+
position: absolute;
|
|
80
|
+
top: 50%;
|
|
81
|
+
left: 50%;
|
|
82
|
+
transform: translate(-50%, -50%);
|
|
83
|
+
background: white;
|
|
84
|
+
padding: 20px;
|
|
85
|
+
border-radius: 8px;
|
|
86
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
87
|
+
z-index: 100;
|
|
88
|
+
width: 400px;
|
|
89
|
+
max-width: 90%;
|
|
90
|
+
display: none;
|
|
91
|
+
border: 1px solid #e5e7eb;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.settings-modal.open {
|
|
95
|
+
display: block;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.settings-modal h3 {
|
|
99
|
+
margin-top: 0;
|
|
100
|
+
margin-bottom: 15px;
|
|
101
|
+
font-size: 18px;
|
|
102
|
+
color: #1f2937;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.form-group {
|
|
106
|
+
margin-bottom: 15px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.form-group label {
|
|
110
|
+
display: block;
|
|
111
|
+
margin-bottom: 5px;
|
|
112
|
+
font-size: 14px;
|
|
113
|
+
color: #4b5563;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.form-group input, .form-group textarea {
|
|
117
|
+
width: 100%;
|
|
118
|
+
padding: 8px;
|
|
119
|
+
border: 1px solid #d1d5db;
|
|
120
|
+
border-radius: 4px;
|
|
121
|
+
font-size: 14px;
|
|
122
|
+
box-sizing: border-box;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.form-group textarea {
|
|
126
|
+
resize: vertical;
|
|
127
|
+
min-height: 60px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.modal-actions {
|
|
131
|
+
display: flex;
|
|
132
|
+
justify-content: flex-end;
|
|
133
|
+
gap: 10px;
|
|
134
|
+
margin-top: 20px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.btn {
|
|
138
|
+
padding: 8px 16px;
|
|
139
|
+
border-radius: 4px;
|
|
140
|
+
border: none;
|
|
141
|
+
cursor: pointer;
|
|
142
|
+
font-size: 14px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.btn-primary {
|
|
146
|
+
background: #3b82f6;
|
|
147
|
+
color: white;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.btn-secondary {
|
|
151
|
+
background: #e5e7eb;
|
|
152
|
+
color: #374151;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.overlay {
|
|
156
|
+
position: fixed;
|
|
157
|
+
top: 0;
|
|
158
|
+
left: 0;
|
|
159
|
+
right: 0;
|
|
160
|
+
bottom: 0;
|
|
161
|
+
background: rgba(0,0,0,0.5);
|
|
162
|
+
z-index: 99;
|
|
163
|
+
display: none;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.overlay.open {
|
|
167
|
+
display: block;
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
170
|
+
<liwe3-button-toolbar id="toolbar"></liwe3-button-toolbar>
|
|
171
|
+
<div class="editor-container">
|
|
172
|
+
<div class="editor-status"></div>
|
|
173
|
+
<div class="loading" id="loading">
|
|
174
|
+
<div class="spinner"></div>
|
|
175
|
+
</div>
|
|
176
|
+
<liwe3-ai-text-editor id="editor"></liwe3-ai-text-editor>
|
|
177
|
+
<liwe3-markdown-preview id="preview" style="display: none; width: 100%; height: 100%; overflow: auto;"></liwe3-markdown-preview>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div class="overlay" id="overlay"></div>
|
|
181
|
+
<div class="settings-modal" id="settingsModal">
|
|
182
|
+
<h3>AI Settings</h3>
|
|
183
|
+
<div class="form-group">
|
|
184
|
+
<label for="apiKey">API Key</label>
|
|
185
|
+
<input type="password" id="apiKey" placeholder="sk-...">
|
|
186
|
+
</div>
|
|
187
|
+
<div class="form-group">
|
|
188
|
+
<label for="systemPrompt">System Prompt</label>
|
|
189
|
+
<textarea id="systemPrompt"></textarea>
|
|
190
|
+
</div>
|
|
191
|
+
<div class="form-group">
|
|
192
|
+
<label for="modelName">Model Name</label>
|
|
193
|
+
<input type="text" id="modelName" placeholder="gpt-3.5-turbo">
|
|
194
|
+
</div>
|
|
195
|
+
<div class="form-group">
|
|
196
|
+
<label for="apiEndpoint">API Endpoint</label>
|
|
197
|
+
<input type="text" id="apiEndpoint" placeholder="https://api.openai.com/v1/chat/completions">
|
|
198
|
+
</div>
|
|
199
|
+
<div class="form-group">
|
|
200
|
+
<label for="markdownLibUrl">Markdown Library URL</label>
|
|
201
|
+
<input type="text" id="markdownLibUrl" placeholder="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js">
|
|
202
|
+
</div>
|
|
203
|
+
<div class="form-group">
|
|
204
|
+
<label for="suggestionDelay">Suggestion Delay (seconds)</label>
|
|
205
|
+
<input type="number" id="suggestionDelay" step="0.1" min="0.5">
|
|
206
|
+
</div>
|
|
207
|
+
<div class="modal-actions">
|
|
208
|
+
<button class="btn btn-secondary" id="cancelBtn">Cancel</button>
|
|
209
|
+
<button class="btn btn-primary" id="saveBtn">Save</button>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
`;
|
|
213
|
+
}
|
|
214
|
+
init() {
|
|
215
|
+
this.aiEditor = this.shadowRoot.getElementById("editor"), this.preview = this.shadowRoot.getElementById("preview"), this.toolbar = this.shadowRoot.getElementById("toolbar"), this.editorStatus = this.shadowRoot.querySelector(".editor-status"), this.loading = this.shadowRoot.getElementById("loading"), this.aiEditor.configure({
|
|
216
|
+
embedded: !0,
|
|
217
|
+
onStatusChange: (t) => {
|
|
218
|
+
this.editorStatus.style.backgroundColor = t ? "#4caf50" : "#777";
|
|
219
|
+
},
|
|
220
|
+
onLoadingChange: (t) => {
|
|
221
|
+
t ? this.loading.classList.add("show") : this.loading.classList.remove("show");
|
|
222
|
+
}
|
|
223
|
+
}), this.setupModal(), this.setupToolbar(), this.aiEditor.addEventListener("change", (t) => {
|
|
224
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
225
|
+
detail: t.detail,
|
|
226
|
+
bubbles: !0,
|
|
227
|
+
composed: !0
|
|
228
|
+
}));
|
|
229
|
+
}), this.aiEditor.addEventListener("beforeSuggestion", (t) => {
|
|
230
|
+
this.dispatchEvent(new CustomEvent("beforeSuggestion", {
|
|
231
|
+
detail: t.detail,
|
|
232
|
+
bubbles: !0,
|
|
233
|
+
composed: !0,
|
|
234
|
+
cancelable: !0
|
|
235
|
+
}));
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
setupModal() {
|
|
239
|
+
const t = this.shadowRoot.getElementById("settingsModal"), o = this.shadowRoot.getElementById("overlay"), e = this.shadowRoot.getElementById("cancelBtn"), i = this.shadowRoot.getElementById("saveBtn"), s = () => {
|
|
240
|
+
t.classList.remove("open"), o.classList.remove("open");
|
|
241
|
+
};
|
|
242
|
+
e.addEventListener("click", s), o.addEventListener("click", s), i.addEventListener("click", () => {
|
|
243
|
+
const n = this.shadowRoot.getElementById("apiKey").value, d = this.shadowRoot.getElementById("systemPrompt").value, a = this.shadowRoot.getElementById("modelName").value, p = this.shadowRoot.getElementById("apiEndpoint").value, r = this.shadowRoot.getElementById("markdownLibUrl").value, l = parseFloat(this.shadowRoot.getElementById("suggestionDelay").value);
|
|
244
|
+
this.aiEditor.setApiKey(n), this.aiEditor.setSystemPrompt(d), this.aiEditor.setModelName(a), this.aiEditor.setApiEndpoint(p), this.markdownLibUrl = r, isNaN(l) || this.aiEditor.setSuggestionDelay(l), s();
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
openSettings() {
|
|
248
|
+
const t = this.shadowRoot.getElementById("settingsModal"), o = this.shadowRoot.getElementById("overlay");
|
|
249
|
+
this.shadowRoot.getElementById("apiKey").value = this.aiEditor.getApiKey(), this.shadowRoot.getElementById("systemPrompt").value = this.aiEditor.getSystemPrompt(), this.shadowRoot.getElementById("modelName").value = this.aiEditor.getModelName(), this.shadowRoot.getElementById("apiEndpoint").value = this.aiEditor.getApiEndpoint(), this.shadowRoot.getElementById("markdownLibUrl").value = this.markdownLibUrl, this.shadowRoot.getElementById("suggestionDelay").value = this.aiEditor.getSuggestionDelay().toString(), t.classList.add("open"), o.classList.add("open");
|
|
250
|
+
}
|
|
251
|
+
setupToolbar() {
|
|
252
|
+
const t = [
|
|
253
|
+
{
|
|
254
|
+
id: "format",
|
|
255
|
+
items: [
|
|
256
|
+
{
|
|
257
|
+
id: "bold",
|
|
258
|
+
label: "B",
|
|
259
|
+
tooltip: "Bold",
|
|
260
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M8 11h4.5a2.5 2.5 0 0 0 0-5H8v5zm10 4.5a4.5 4.5 0 0 1-4.5 4.5H6V4h6.5a4.5 4.5 0 0 1 3.26 7.586A4.5 4.5 0 0 1 18 15.5zM8 13v5h5.5a2.5 2.5 0 0 0 0-5H8z"/></svg>'
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
id: "italic",
|
|
264
|
+
label: "I",
|
|
265
|
+
tooltip: "Italic",
|
|
266
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>'
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: "underline",
|
|
270
|
+
label: "U",
|
|
271
|
+
tooltip: "Underline",
|
|
272
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>'
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: "lists",
|
|
278
|
+
items: [
|
|
279
|
+
{
|
|
280
|
+
id: "ul",
|
|
281
|
+
label: "UL",
|
|
282
|
+
tooltip: "Unordered List",
|
|
283
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/></svg>'
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: "ol",
|
|
287
|
+
label: "OL",
|
|
288
|
+
tooltip: "Numbered List",
|
|
289
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></svg>'
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: "settings",
|
|
295
|
+
items: [
|
|
296
|
+
{
|
|
297
|
+
id: "preview",
|
|
298
|
+
tooltip: "Toggle Preview",
|
|
299
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>'
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: "settings",
|
|
303
|
+
tooltip: "AI Settings",
|
|
304
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L4.16 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.04.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.57 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.08-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>'
|
|
305
|
+
}
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
];
|
|
309
|
+
this.toolbar.groups = t, this.toolbar.addEventListener("button-click", (o) => {
|
|
310
|
+
const e = o.detail;
|
|
311
|
+
this.handleToolbarAction(e.id);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
togglePreview() {
|
|
315
|
+
this.isPreviewMode = !this.isPreviewMode, this.isPreviewMode ? (this.preview.value = this.aiEditor.getText(), this.preview.libUrl = this.markdownLibUrl, this.aiEditor.style.display = "none", this.preview.style.display = "block") : (this.aiEditor.style.display = "block", this.preview.style.display = "none");
|
|
316
|
+
}
|
|
317
|
+
handleToolbarAction(t) {
|
|
318
|
+
if (t === "preview") {
|
|
319
|
+
this.togglePreview();
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const o = this.aiEditor.shadowRoot?.getElementById("editor");
|
|
323
|
+
if (!o) return;
|
|
324
|
+
const e = o.selectionStart, i = o.selectionEnd, s = o.value, n = s.substring(e, i);
|
|
325
|
+
let d = "", a = i;
|
|
326
|
+
switch (t) {
|
|
327
|
+
case "settings":
|
|
328
|
+
this.openSettings();
|
|
329
|
+
return;
|
|
330
|
+
// Exit early as we don't need text manipulation
|
|
331
|
+
case "bold":
|
|
332
|
+
d = s.substring(0, e) + `**${n}**` + s.substring(i), a = i + 4, e === i && (a = e + 2);
|
|
333
|
+
break;
|
|
334
|
+
case "italic":
|
|
335
|
+
d = s.substring(0, e) + `*${n}*` + s.substring(i), a = i + 2, e === i && (a = e + 1);
|
|
336
|
+
break;
|
|
337
|
+
case "underline":
|
|
338
|
+
d = s.substring(0, e) + `<u>${n}</u>` + s.substring(i), a = i + 7, e === i && (a = e + 3);
|
|
339
|
+
break;
|
|
340
|
+
case "ul":
|
|
341
|
+
if (e !== i) {
|
|
342
|
+
const r = n.split(`
|
|
343
|
+
`).map((l) => `- ${l}`).join(`
|
|
344
|
+
`);
|
|
345
|
+
d = s.substring(0, e) + r + s.substring(i), a = e + r.length;
|
|
346
|
+
} else
|
|
347
|
+
d = s.substring(0, e) + "- " + s.substring(i), a = e + 2;
|
|
348
|
+
break;
|
|
349
|
+
case "ol":
|
|
350
|
+
if (e !== i) {
|
|
351
|
+
const r = n.split(`
|
|
352
|
+
`).map((l, g) => `${g + 1}. ${l}`).join(`
|
|
353
|
+
`);
|
|
354
|
+
d = s.substring(0, e) + r + s.substring(i), a = e + r.length;
|
|
355
|
+
} else
|
|
356
|
+
d = s.substring(0, e) + "1. " + s.substring(i), a = e + 3;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
d && (o.value = d, o.focus(), e === i ? t === "bold" ? o.setSelectionRange(e + 2, e + 2) : t === "italic" ? o.setSelectionRange(e + 1, e + 1) : t === "underline" ? o.setSelectionRange(e + 3, e + 3) : o.setSelectionRange(a, a) : o.setSelectionRange(a, a), o.dispatchEvent(new Event("input", { bubbles: !0 })));
|
|
360
|
+
}
|
|
361
|
+
// Proxy methods to AITextEditor
|
|
362
|
+
setText(t) {
|
|
363
|
+
this.aiEditor && this.aiEditor.setText(t);
|
|
364
|
+
}
|
|
365
|
+
getText() {
|
|
366
|
+
return this.aiEditor ? this.aiEditor.getText() : "";
|
|
367
|
+
}
|
|
368
|
+
setApiKey(t) {
|
|
369
|
+
this.aiEditor && this.aiEditor.setApiKey(t);
|
|
370
|
+
}
|
|
371
|
+
getApiKey() {
|
|
372
|
+
return this.aiEditor ? this.aiEditor.getApiKey() : "";
|
|
373
|
+
}
|
|
374
|
+
setSuggestionDelay(t) {
|
|
375
|
+
this.aiEditor && this.aiEditor.setSuggestionDelay(t);
|
|
376
|
+
}
|
|
377
|
+
getSuggestionDelay() {
|
|
378
|
+
return this.aiEditor ? this.aiEditor.getSuggestionDelay() : 1;
|
|
379
|
+
}
|
|
380
|
+
setSystemPrompt(t) {
|
|
381
|
+
this.aiEditor && this.aiEditor.setSystemPrompt(t);
|
|
382
|
+
}
|
|
383
|
+
getSystemPrompt() {
|
|
384
|
+
return this.aiEditor ? this.aiEditor.getSystemPrompt() : "";
|
|
385
|
+
}
|
|
386
|
+
setApiEndpoint(t) {
|
|
387
|
+
this.aiEditor && this.aiEditor.setApiEndpoint(t);
|
|
388
|
+
}
|
|
389
|
+
getApiEndpoint() {
|
|
390
|
+
return this.aiEditor ? this.aiEditor.getApiEndpoint() : "";
|
|
391
|
+
}
|
|
392
|
+
setModelName(t) {
|
|
393
|
+
this.aiEditor && this.aiEditor.setModelName(t);
|
|
394
|
+
}
|
|
395
|
+
getModelName() {
|
|
396
|
+
return this.aiEditor ? this.aiEditor.getModelName() : "";
|
|
397
|
+
}
|
|
398
|
+
setContext(t) {
|
|
399
|
+
this.aiEditor && this.aiEditor.setContext(t);
|
|
400
|
+
}
|
|
401
|
+
getContext() {
|
|
402
|
+
return this.aiEditor ? this.aiEditor.getContext() : "";
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const E = (h = "liwe3-ai-markdown-editor") => {
|
|
406
|
+
typeof window < "u" && (c(), m(), u(), customElements.get(h) || customElements.define(h, v));
|
|
407
|
+
};
|
|
408
|
+
export {
|
|
409
|
+
v as AIMarkdownEditorElement,
|
|
410
|
+
E as defineAIMarkdownEditor
|
|
411
|
+
};
|
|
412
|
+
//# sourceMappingURL=AIMarkdownEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIMarkdownEditor.js","sources":["../src/AIMarkdownEditor.ts"],"sourcesContent":["import { AITextEditorElement, defineAITextEditor } from './AITextEditor';\nimport { ButtonToolbarElement, ButtonToolbarGroup, defineButtonToolbar } from './ButtonToolbar';\nimport { MarkdownPreviewElement, defineMarkdownPreview } from './MarkdownPreview';\n\nexport class AIMarkdownEditorElement extends HTMLElement {\n declare shadowRoot: ShadowRoot;\n private aiEditor!: AITextEditorElement;\n private toolbar!: ButtonToolbarElement;\n private preview!: MarkdownPreviewElement;\n private editorStatus!: HTMLElement;\n private loading!: HTMLElement;\n private isPreviewMode: boolean = false;\n private markdownLibUrl: string = 'https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js';\n\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void {\n this.render();\n this.init();\n }\n\n private render(): void {\n this.shadowRoot.innerHTML = `\n <style>\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n gap: 0.5rem;\n }\n \n .editor-container {\n flex: 1;\n position: relative;\n min-height: 0; /* Important for flexbox scrolling */\n border: 2px solid #e1e5e9;\n border-radius: 12px;\n background: #fafbfc;\n }\n \n .editor-container:focus-within {\n border-color: #4facfe;\n background: white;\n }\n\n .editor-status {\n position: absolute;\n top: 5px;\n left: 5px;\n width: 10px;\n height: 10px;\n border-radius: 100%;\n background: #777;\n z-index: 10;\n }\n \n .loading {\n position: absolute;\n top: 5px;\n right: 10px;\n z-index: 10;\n display: none;\n }\n\n .loading.show {\n display: block;\n }\n\n .spinner {\n width: 10px;\n height: 10px;\n border: 2px solid #e1e5e9;\n border-top: 2px solid #4facfe;\n border-radius: 50%;\n animation: spin 1s linear infinite;\n }\n\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n liwe3-ai-text-editor {\n width: 100%;\n height: 100%;\n }\n\n .settings-modal {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: white;\n padding: 20px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.15);\n z-index: 100;\n width: 400px;\n max-width: 90%;\n display: none;\n border: 1px solid #e5e7eb;\n }\n\n .settings-modal.open {\n display: block;\n }\n\n .settings-modal h3 {\n margin-top: 0;\n margin-bottom: 15px;\n font-size: 18px;\n color: #1f2937;\n }\n\n .form-group {\n margin-bottom: 15px;\n }\n\n .form-group label {\n display: block;\n margin-bottom: 5px;\n font-size: 14px;\n color: #4b5563;\n }\n\n .form-group input, .form-group textarea {\n width: 100%;\n padding: 8px;\n border: 1px solid #d1d5db;\n border-radius: 4px;\n font-size: 14px;\n box-sizing: border-box;\n }\n\n .form-group textarea {\n resize: vertical;\n min-height: 60px;\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n margin-top: 20px;\n }\n\n .btn {\n padding: 8px 16px;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n font-size: 14px;\n }\n\n .btn-primary {\n background: #3b82f6;\n color: white;\n }\n\n .btn-secondary {\n background: #e5e7eb;\n color: #374151;\n }\n\n .overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0,0,0,0.5);\n z-index: 99;\n display: none;\n }\n\n .overlay.open {\n display: block;\n }\n </style>\n <liwe3-button-toolbar id=\"toolbar\"></liwe3-button-toolbar>\n <div class=\"editor-container\">\n <div class=\"editor-status\"></div>\n <div class=\"loading\" id=\"loading\">\n <div class=\"spinner\"></div>\n </div>\n <liwe3-ai-text-editor id=\"editor\"></liwe3-ai-text-editor>\n <liwe3-markdown-preview id=\"preview\" style=\"display: none; width: 100%; height: 100%; overflow: auto;\"></liwe3-markdown-preview>\n </div>\n \n <div class=\"overlay\" id=\"overlay\"></div>\n <div class=\"settings-modal\" id=\"settingsModal\">\n <h3>AI Settings</h3>\n <div class=\"form-group\">\n <label for=\"apiKey\">API Key</label>\n <input type=\"password\" id=\"apiKey\" placeholder=\"sk-...\">\n </div>\n <div class=\"form-group\">\n <label for=\"systemPrompt\">System Prompt</label>\n <textarea id=\"systemPrompt\"></textarea>\n </div>\n <div class=\"form-group\">\n <label for=\"modelName\">Model Name</label>\n <input type=\"text\" id=\"modelName\" placeholder=\"gpt-3.5-turbo\">\n </div>\n <div class=\"form-group\">\n <label for=\"apiEndpoint\">API Endpoint</label>\n <input type=\"text\" id=\"apiEndpoint\" placeholder=\"https://api.openai.com/v1/chat/completions\">\n </div>\n <div class=\"form-group\">\n <label for=\"markdownLibUrl\">Markdown Library URL</label>\n <input type=\"text\" id=\"markdownLibUrl\" placeholder=\"https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js\">\n </div>\n <div class=\"form-group\">\n <label for=\"suggestionDelay\">Suggestion Delay (seconds)</label>\n <input type=\"number\" id=\"suggestionDelay\" step=\"0.1\" min=\"0.5\">\n </div>\n <div class=\"modal-actions\">\n <button class=\"btn btn-secondary\" id=\"cancelBtn\">Cancel</button>\n <button class=\"btn btn-primary\" id=\"saveBtn\">Save</button>\n </div>\n </div>\n `;\n }\n\n private init(): void {\n this.aiEditor = this.shadowRoot.getElementById('editor') as AITextEditorElement;\n this.preview = this.shadowRoot.getElementById('preview') as MarkdownPreviewElement;\n this.toolbar = this.shadowRoot.getElementById('toolbar') as ButtonToolbarElement;\n this.editorStatus = this.shadowRoot.querySelector('.editor-status') as HTMLElement;\n this.loading = this.shadowRoot.getElementById('loading') as HTMLElement;\n \n // Configure the AITextEditor in embedded mode with callbacks\n this.aiEditor.configure({\n embedded: true,\n onStatusChange: (hasApiKey: boolean) => {\n this.editorStatus.style.backgroundColor = hasApiKey ? '#4caf50' : '#777';\n },\n onLoadingChange: (isLoading: boolean) => {\n if (isLoading) {\n this.loading.classList.add('show');\n } else {\n this.loading.classList.remove('show');\n }\n }\n });\n \n this.setupModal();\n this.setupToolbar();\n \n // Forward events from aiEditor\n this.aiEditor.addEventListener('change', (e: Event) => {\n this.dispatchEvent(new CustomEvent('change', { \n detail: (e as CustomEvent).detail,\n bubbles: true,\n composed: true \n }));\n });\n\n this.aiEditor.addEventListener('beforeSuggestion', (e: Event) => {\n this.dispatchEvent(new CustomEvent('beforeSuggestion', { \n detail: (e as CustomEvent).detail,\n bubbles: true,\n composed: true,\n cancelable: true\n }));\n });\n }\n\n private setupModal(): void {\n const modal = this.shadowRoot.getElementById('settingsModal') as HTMLElement;\n const overlay = this.shadowRoot.getElementById('overlay') as HTMLElement;\n const cancelBtn = this.shadowRoot.getElementById('cancelBtn') as HTMLButtonElement;\n const saveBtn = this.shadowRoot.getElementById('saveBtn') as HTMLButtonElement;\n\n const close = () => {\n modal.classList.remove('open');\n overlay.classList.remove('open');\n };\n\n cancelBtn.addEventListener('click', close);\n overlay.addEventListener('click', close);\n\n saveBtn.addEventListener('click', () => {\n const apiKey = (this.shadowRoot.getElementById('apiKey') as HTMLInputElement).value;\n const systemPrompt = (this.shadowRoot.getElementById('systemPrompt') as HTMLTextAreaElement).value;\n const modelName = (this.shadowRoot.getElementById('modelName') as HTMLInputElement).value;\n const apiEndpoint = (this.shadowRoot.getElementById('apiEndpoint') as HTMLInputElement).value;\n const markdownLibUrl = (this.shadowRoot.getElementById('markdownLibUrl') as HTMLInputElement).value;\n const suggestionDelay = parseFloat((this.shadowRoot.getElementById('suggestionDelay') as HTMLInputElement).value);\n\n this.aiEditor.setApiKey(apiKey);\n this.aiEditor.setSystemPrompt(systemPrompt);\n this.aiEditor.setModelName(modelName);\n this.aiEditor.setApiEndpoint(apiEndpoint);\n this.markdownLibUrl = markdownLibUrl;\n if (!isNaN(suggestionDelay)) {\n this.aiEditor.setSuggestionDelay(suggestionDelay);\n }\n\n close();\n });\n }\n\n private openSettings(): void {\n const modal = this.shadowRoot.getElementById('settingsModal') as HTMLElement;\n const overlay = this.shadowRoot.getElementById('overlay') as HTMLElement;\n \n // Load current values\n (this.shadowRoot.getElementById('apiKey') as HTMLInputElement).value = this.aiEditor.getApiKey();\n (this.shadowRoot.getElementById('systemPrompt') as HTMLTextAreaElement).value = this.aiEditor.getSystemPrompt();\n (this.shadowRoot.getElementById('modelName') as HTMLInputElement).value = this.aiEditor.getModelName();\n (this.shadowRoot.getElementById('apiEndpoint') as HTMLInputElement).value = this.aiEditor.getApiEndpoint();\n (this.shadowRoot.getElementById('markdownLibUrl') as HTMLInputElement).value = this.markdownLibUrl;\n (this.shadowRoot.getElementById('suggestionDelay') as HTMLInputElement).value = this.aiEditor.getSuggestionDelay().toString();\n\n modal.classList.add('open');\n overlay.classList.add('open');\n }\n\n private setupToolbar(): void {\n const groups: ButtonToolbarGroup[] = [\n {\n id: 'format',\n items: [\n {\n id: 'bold',\n label: 'B',\n tooltip: 'Bold',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M8 11h4.5a2.5 2.5 0 0 0 0-5H8v5zm10 4.5a4.5 4.5 0 0 1-4.5 4.5H6V4h6.5a4.5 4.5 0 0 1 3.26 7.586A4.5 4.5 0 0 1 18 15.5zM8 13v5h5.5a2.5 2.5 0 0 0 0-5H8z\"/></svg>'\n },\n {\n id: 'italic',\n label: 'I',\n tooltip: 'Italic',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>'\n },\n {\n id: 'underline',\n label: 'U',\n tooltip: 'Underline',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>'\n }\n ]\n },\n {\n id: 'lists',\n items: [\n {\n id: 'ul',\n label: 'UL',\n tooltip: 'Unordered List',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z\"/></svg>'\n },\n {\n id: 'ol',\n label: 'OL',\n tooltip: 'Numbered List',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z\"/></svg>'\n }\n ]\n },\n {\n id: 'settings',\n items: [\n {\n id: 'preview',\n tooltip: 'Toggle Preview',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z\"/></svg>'\n },\n {\n id: 'settings',\n tooltip: 'AI Settings',\n icon: '<svg viewBox=\"0 0 24 24\"><path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L4.16 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.04.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.57 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.08-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/></svg>'\n }\n ]\n }\n ];\n\n this.toolbar.groups = groups;\n this.toolbar.addEventListener('button-click', (e: Event) => {\n const detail = (e as CustomEvent).detail;\n this.handleToolbarAction(detail.id);\n });\n }\n\n private togglePreview(): void {\n this.isPreviewMode = !this.isPreviewMode;\n if (this.isPreviewMode) {\n this.preview.value = this.aiEditor.getText();\n this.preview.libUrl = this.markdownLibUrl;\n this.aiEditor.style.display = 'none';\n this.preview.style.display = 'block';\n } else {\n this.aiEditor.style.display = 'block';\n this.preview.style.display = 'none';\n }\n }\n\n private handleToolbarAction(actionId: string): void {\n if (actionId === 'preview') {\n this.togglePreview();\n return;\n }\n\n const textarea = this.aiEditor.shadowRoot?.getElementById('editor') as HTMLTextAreaElement;\n if (!textarea) return;\n\n const start = textarea.selectionStart;\n const end = textarea.selectionEnd;\n const text = textarea.value;\n const selectedText = text.substring(start, end);\n \n let newText = '';\n let newCursorPos = end;\n\n switch (actionId) {\n case 'settings':\n this.openSettings();\n return; // Exit early as we don't need text manipulation\n case 'bold':\n newText = text.substring(0, start) + `**${selectedText}**` + text.substring(end);\n newCursorPos = end + 4; // ** + **\n if (start === end) newCursorPos = start + 2; // Position inside **\n break;\n case 'italic':\n newText = text.substring(0, start) + `*${selectedText}*` + text.substring(end);\n newCursorPos = end + 2; // * + *\n if (start === end) newCursorPos = start + 1; // Position inside *\n break;\n case 'underline':\n newText = text.substring(0, start) + `<u>${selectedText}</u>` + text.substring(end);\n newCursorPos = end + 7; // <u> + </u>\n if (start === end) newCursorPos = start + 3; // Position inside <u>\n break;\n case 'ul':\n // For lists, we want to handle multiline selection\n if (start !== end) {\n const lines = selectedText.split('\\n');\n const listText = lines.map(line => `- ${line}`).join('\\n');\n newText = text.substring(0, start) + listText + text.substring(end);\n newCursorPos = start + listText.length;\n } else {\n // Insert at beginning of line? Or just insert marker?\n // Simple version: insert marker\n newText = text.substring(0, start) + `- ` + text.substring(end);\n newCursorPos = start + 2;\n }\n break;\n case 'ol':\n if (start !== end) {\n const lines = selectedText.split('\\n');\n const listText = lines.map((line, i) => `${i + 1}. ${line}`).join('\\n');\n newText = text.substring(0, start) + listText + text.substring(end);\n newCursorPos = start + listText.length;\n } else {\n newText = text.substring(0, start) + `1. ` + text.substring(end);\n newCursorPos = start + 3;\n }\n break;\n }\n\n if (newText) {\n textarea.value = newText;\n textarea.focus();\n \n // If we just inserted markers around empty selection, put cursor inside\n if (start === end) {\n if (actionId === 'bold') textarea.setSelectionRange(start + 2, start + 2);\n else if (actionId === 'italic') textarea.setSelectionRange(start + 1, start + 1);\n else if (actionId === 'underline') textarea.setSelectionRange(start + 3, start + 3);\n else textarea.setSelectionRange(newCursorPos, newCursorPos);\n } else {\n // Select the modified text\n // This is a bit complex to calculate exactly for all cases, so just putting cursor at end for now\n textarea.setSelectionRange(newCursorPos, newCursorPos);\n }\n\n // Trigger input event so AITextEditor updates\n textarea.dispatchEvent(new Event('input', { bubbles: true }));\n }\n }\n\n // Proxy methods to AITextEditor\n setText(text: string): void {\n if (this.aiEditor) {\n this.aiEditor.setText(text);\n }\n }\n\n getText(): string {\n return this.aiEditor ? this.aiEditor.getText() : '';\n }\n\n setApiKey(key: string): void {\n if (this.aiEditor) {\n this.aiEditor.setApiKey(key);\n }\n }\n\n getApiKey(): string {\n return this.aiEditor ? this.aiEditor.getApiKey() : '';\n }\n\n setSuggestionDelay(seconds: number): void {\n if (this.aiEditor) {\n this.aiEditor.setSuggestionDelay(seconds);\n }\n }\n\n getSuggestionDelay(): number {\n return this.aiEditor ? this.aiEditor.getSuggestionDelay() : 1;\n }\n\n setSystemPrompt(prompt: string): void {\n if (this.aiEditor) {\n this.aiEditor.setSystemPrompt(prompt);\n }\n }\n\n getSystemPrompt(): string {\n return this.aiEditor ? this.aiEditor.getSystemPrompt() : '';\n }\n\n setApiEndpoint(endpoint: string): void {\n if (this.aiEditor) {\n this.aiEditor.setApiEndpoint(endpoint);\n }\n }\n\n getApiEndpoint(): string {\n return this.aiEditor ? this.aiEditor.getApiEndpoint() : '';\n }\n\n setModelName(modelName: string): void {\n if (this.aiEditor) {\n this.aiEditor.setModelName(modelName);\n }\n }\n\n getModelName(): string {\n return this.aiEditor ? this.aiEditor.getModelName() : '';\n }\n\n setContext(context: string): void {\n if (this.aiEditor) {\n this.aiEditor.setContext(context);\n }\n }\n\n getContext(): string {\n return this.aiEditor ? this.aiEditor.getContext() : '';\n }\n}\n\nexport const defineAIMarkdownEditor = (tagName: string = 'liwe3-ai-markdown-editor'): void => {\n if (typeof window !== 'undefined') {\n defineAITextEditor();\n defineButtonToolbar();\n defineMarkdownPreview();\n if (!customElements.get(tagName)) {\n customElements.define(tagName, AIMarkdownEditorElement);\n }\n }\n};\n"],"names":["AIMarkdownEditorElement","hasApiKey","isLoading","e","modal","overlay","cancelBtn","saveBtn","close","apiKey","systemPrompt","modelName","apiEndpoint","markdownLibUrl","suggestionDelay","groups","detail","actionId","textarea","start","end","text","selectedText","newText","newCursorPos","listText","line","i","key","seconds","prompt","endpoint","context","defineAIMarkdownEditor","tagName","defineAITextEditor","defineButtonToolbar","defineMarkdownPreview"],"mappings":"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"}
|