@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
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @liwe3/webcomponents\n * A collection of reusable web components\n */\n\n// Export SmartSelect\nexport {\n
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * @liwe3/webcomponents\n * A collection of reusable web components\n */\n\n// Export SmartSelect\nexport {\n\tSmartSelectElement,\n\tdefineSmartSelect,\n\ttype SelectOption,\n} from './SmartSelect';\n\n// Export AITextEditor\nexport {\n\tAITextEditorElement,\n\tdefineAITextEditor,\n\ttype AITextEditorConfig,\n} from './AITextEditor';\n\n// Export Toast\nexport {\n\tToastElement,\n\tdefineToast,\n\ttoastAdd,\n\ttype ToastType,\n\ttype ToastButton,\n\ttype ToastConfig,\n} from './Toast';\n\n// Export Dialog\nexport {\n\tDialogElement,\n\tdefineDialog,\n\tdialogAdd,\n\ttype DialogButton,\n\ttype DialogConfig,\n} from './Dialog';\n\n// Export PopoverMenu\nexport {\n\tPopoverMenuElement,\n\tdefinePopoverMenu,\n\ttype PopoverMenuItem,\n\ttype PopoverMenuConfig,\n} from './PopoverMenu';\n\n// Export DateSelector\nexport {\n\tDateSelectorElement,\n\tdefineDateSelector,\n\ttype DateRange,\n} from './DateSelector';\n\n// Export TreeView\nexport {\n\tTreeViewElement,\n\tdefineTreeView,\n\ttype TreeNode,\n} from './TreeView';\n\n// Export ContainerBox\nexport {\n\tContainerBoxElement,\n\tdefineContainerBox,\n\ttype MenuPosition,\n\ttype ContainerBoxConfig,\n} from './ContainerBox';\n\n// Export Drawer\nexport {\n\tDrawerElement,\n\tdefineDrawer,\n\ttype DrawerDirection,\n\ttype DrawerState,\n\ttype DrawerConfig,\n} from './Drawer';\n\n// Export ImageView\nexport * from './ImageView';\n\n// Export ChunkUploader\nexport {\n\tChunkUploaderElement,\n\tdefineChunkUploader,\n\ttype UploadedFile,\n\ttype ChunkUploaderConfig,\n} from './ChunkUploader';\n\n// Export CheckList\nexport {\n\tCheckListElement,\n\tdefineCheckList,\n\ttype CheckListItem,\n} from './CheckList';\n\n// Export ButtonToolbar\nexport {\n\tButtonToolbarElement,\n\tdefineButtonToolbar,\n\ttype ButtonToolbarItem,\n\ttype ButtonToolbarGroup,\n} from './ButtonToolbar';\n\n// Export AIMarkdownEditor\nexport {\n\tAIMarkdownEditorElement,\n\tdefineAIMarkdownEditor,\n} from './AIMarkdownEditor';\n\n// Export MarkdownPreview\nexport {\n\tMarkdownPreviewElement,\n\tdefineMarkdownPreview,\n} from './MarkdownPreview';\n\n// Export ResizableCropper\nexport {\n\tResizableCropperElement,\n\tdefineResizableCropper,\n\ttype ResizableCropperState,\n\ttype ResizableCropEventDetail,\n\ttype ResizableCropperValues,\n\ttype ResizableCropperComponentState,\n} from './ResizableCropper';\n\n// Export ComicBalloon\nexport {\n\tComicBalloonElement,\n\tdefineComicBalloon,\n\tBalloonType,\n\ttype HandlerPosition,\n\ttype ContentChangeEvent,\n\ttype HandlerMoveEvent,\n} from './ComicBalloon';\n\n// Convenience function to register all components at once\nexport const defineAllComponents = () : void => {\n\tif ( typeof window !== 'undefined' ) {\n\t\timport( './SmartSelect' ).then( ( { defineSmartSelect } ) => defineSmartSelect() );\n\t\timport( './AITextEditor' ).then( ( { defineAITextEditor } ) => defineAITextEditor() );\n\t\timport( './AIMarkdownEditor' ).then( ( { defineAIMarkdownEditor } ) => defineAIMarkdownEditor() );\n\t\timport( './MarkdownPreview' ).then( ( { defineMarkdownPreview } ) => defineMarkdownPreview() );\n\t\timport( './Toast' ).then( ( { defineToast } ) => defineToast() );\n\t\timport( './Dialog' ).then( ( { defineDialog } ) => defineDialog() );\n\t\timport( './PopoverMenu' ).then( ( { definePopoverMenu } ) => definePopoverMenu() );\n\t\timport( './DateSelector' ).then( ( { defineDateSelector } ) => defineDateSelector() );\n\t\timport( './TreeView' ).then( ( { defineTreeView } ) => defineTreeView() );\n\t\timport( './ContainerBox' ).then( ( { defineContainerBox } ) => defineContainerBox() );\n\t\timport( './Drawer' ).then( ( { defineDrawer } ) => defineDrawer() );\n\t\timport( './ChunkUploader' ).then( ( { defineChunkUploader } ) => defineChunkUploader() );\n\t\timport( './CheckList' ).then( ( { defineCheckList } ) => defineCheckList() );\n\t\timport( './ButtonToolbar' ).then( ( { defineButtonToolbar } ) => defineButtonToolbar() );\n\t\timport( './ResizableCropper' ).then( ( { defineResizableCropper } ) => defineResizableCropper() );\n\t\timport( './ComicBalloon' ).then( ( { defineComicBalloon } ) => defineComicBalloon() );\n\t}\n};\n"],"names":["defineAllComponents","defineSmartSelect","defineAITextEditor","defineAIMarkdownEditor","defineMarkdownPreview","defineToast","defineDialog","definePopoverMenu","defineDateSelector","defineTreeView","defineContainerBox","defineDrawer","defineChunkUploader","defineCheckList","defineButtonToolbar","defineResizableCropper","defineComicBalloon"],"mappings":";;;;;;;;;;;;;;;;;AAwIO,MAAMA,IAAsB,MAAa;AAC/C,EAAK,OAAO,SAAW,QACtB,OAAQ,kBAAgB,EAAE,KAAM,CAAE,EAAE,mBAAAC,EAAAA,MAAyBA,GAAoB,GACjF,OAAQ,mBAAiB,EAAE,KAAM,CAAE,EAAE,oBAAAC,EAAAA,MAA0BA,GAAqB,GACpF,OAAQ,uBAAqB,EAAE,KAAM,CAAE,EAAE,wBAAAC,EAAAA,MAA8BA,GAAyB,GAChG,OAAQ,sBAAoB,EAAE,KAAM,CAAE,EAAE,uBAAAC,EAAAA,MAA6BA,GAAwB,GAC7F,OAAQ,YAAU,EAAE,KAAM,CAAE,EAAE,aAAAC,EAAAA,MAAmBA,GAAc,GAC/D,OAAQ,aAAW,EAAE,KAAM,CAAE,EAAE,cAAAC,EAAAA,MAAoBA,GAAe,GAClE,OAAQ,kBAAgB,EAAE,KAAM,CAAE,EAAE,mBAAAC,EAAAA,MAAyBA,GAAoB,GACjF,OAAQ,mBAAiB,EAAE,KAAM,CAAE,EAAE,oBAAAC,EAAAA,MAA0BA,GAAqB,GACpF,OAAQ,eAAa,EAAE,KAAM,CAAE,EAAE,gBAAAC,EAAAA,MAAsBA,GAAiB,GACxE,OAAQ,mBAAiB,EAAE,KAAM,CAAE,EAAE,oBAAAC,EAAAA,MAA0BA,GAAqB,GACpF,OAAQ,aAAW,EAAE,KAAM,CAAE,EAAE,cAAAC,EAAAA,MAAoBA,GAAe,GAClE,OAAQ,oBAAkB,EAAE,KAAM,CAAE,EAAE,qBAAAC,EAAAA,MAA2BA,GAAsB,GACvF,OAAQ,gBAAc,EAAE,KAAM,CAAE,EAAE,iBAAAC,EAAAA,MAAuBA,GAAkB,GAC3E,OAAQ,oBAAkB,EAAE,KAAM,CAAE,EAAE,qBAAAC,EAAAA,MAA2BA,GAAsB,GACvF,OAAQ,uBAAqB,EAAE,KAAM,CAAE,EAAE,wBAAAC,EAAAA,MAA8BA,GAAyB,GAChG,OAAQ,mBAAiB,EAAE,KAAM,CAAE,EAAE,oBAAAC,EAAAA,MAA0BA,GAAqB;AAEtF;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liwe3/webcomponents",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "A collection of reusable web components including SmartSelect and AITextEditor",
|
|
3
|
+
"version": "1.1.10",
|
|
4
|
+
"description": "A collection of reusable web components including SmartSelect and AITextEditor, ChunkUploader and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"import": "./dist/Toast.js",
|
|
28
28
|
"default": "./dist/Toast.js"
|
|
29
29
|
},
|
|
30
|
+
"./dialog": {
|
|
31
|
+
"types": "./dist/Dialog.d.ts",
|
|
32
|
+
"import": "./dist/Dialog.js",
|
|
33
|
+
"default": "./dist/Dialog.js"
|
|
34
|
+
},
|
|
30
35
|
"./popover-menu": {
|
|
31
36
|
"types": "./dist/PopoverMenu.d.ts",
|
|
32
37
|
"import": "./dist/PopoverMenu.js",
|
|
@@ -36,6 +41,56 @@
|
|
|
36
41
|
"types": "./dist/DateSelector.d.ts",
|
|
37
42
|
"import": "./dist/DateSelector.js",
|
|
38
43
|
"default": "./dist/DateSelector.js"
|
|
44
|
+
},
|
|
45
|
+
"./tree-view": {
|
|
46
|
+
"types": "./dist/TreeView.d.ts",
|
|
47
|
+
"import": "./dist/TreeView.js",
|
|
48
|
+
"default": "./dist/TreeView.js"
|
|
49
|
+
},
|
|
50
|
+
"./container-box": {
|
|
51
|
+
"types": "./dist/ContainerBox.d.ts",
|
|
52
|
+
"import": "./dist/ContainerBox.js",
|
|
53
|
+
"default": "./dist/ContainerBox.js"
|
|
54
|
+
},
|
|
55
|
+
"./drawer": {
|
|
56
|
+
"types": "./dist/Drawer.d.ts",
|
|
57
|
+
"import": "./dist/Drawer.js",
|
|
58
|
+
"default": "./dist/Drawer.js"
|
|
59
|
+
},
|
|
60
|
+
"./image-view": {
|
|
61
|
+
"types": "./dist/ImageView.d.ts",
|
|
62
|
+
"import": "./dist/ImageView.js",
|
|
63
|
+
"default": "./dist/ImageView.js"
|
|
64
|
+
},
|
|
65
|
+
"./chunk-uploader": {
|
|
66
|
+
"types": "./dist/ChunkUploader.d.ts",
|
|
67
|
+
"import": "./dist/ChunkUploader.js",
|
|
68
|
+
"default": "./dist/ChunkUploader.js"
|
|
69
|
+
},
|
|
70
|
+
"./button-toolbar": {
|
|
71
|
+
"types": "./dist/ButtonToolbar.d.ts",
|
|
72
|
+
"import": "./dist/ButtonToolbar.js",
|
|
73
|
+
"default": "./dist/ButtonToolbar.js"
|
|
74
|
+
},
|
|
75
|
+
"./ai-markdown-editor": {
|
|
76
|
+
"types": "./dist/AIMarkdownEditor.d.ts",
|
|
77
|
+
"import": "./dist/AIMarkdownEditor.js",
|
|
78
|
+
"default": "./dist/AIMarkdownEditor.js"
|
|
79
|
+
},
|
|
80
|
+
"./markdown-preview": {
|
|
81
|
+
"types": "./dist/MarkdownPreview.d.ts",
|
|
82
|
+
"import": "./dist/MarkdownPreview.js",
|
|
83
|
+
"default": "./dist/MarkdownPreview.js"
|
|
84
|
+
},
|
|
85
|
+
"./checklist": {
|
|
86
|
+
"types": "./dist/CheckList.d.ts",
|
|
87
|
+
"import": "./dist/CheckList.js",
|
|
88
|
+
"default": "./dist/CheckList.js"
|
|
89
|
+
},
|
|
90
|
+
"./resizable-cropper": {
|
|
91
|
+
"types": "./dist/ResizableCropper.d.ts",
|
|
92
|
+
"import": "./dist/ResizableCropper.js",
|
|
93
|
+
"default": "./dist/ResizableCropper.js"
|
|
39
94
|
}
|
|
40
95
|
},
|
|
41
96
|
"files": [
|
|
@@ -58,11 +113,11 @@
|
|
|
58
113
|
"text-editor",
|
|
59
114
|
"liwe3"
|
|
60
115
|
],
|
|
61
|
-
"author": "
|
|
116
|
+
"author": "Fabio Rotondo",
|
|
62
117
|
"license": "MIT",
|
|
63
118
|
"repository": {
|
|
64
119
|
"type": "git",
|
|
65
|
-
"url": "https://github.com/liwe3
|
|
120
|
+
"url": "https://github.com/fsoft72/liwe3-webcomponents.git"
|
|
66
121
|
},
|
|
67
122
|
"devDependencies": {
|
|
68
123
|
"typescript": "^5.9.2",
|
|
@@ -72,4 +127,4 @@
|
|
|
72
127
|
"access": "public"
|
|
73
128
|
},
|
|
74
129
|
"packageManager": "pnpm@10.16.0"
|
|
75
|
-
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import { AITextEditorElement, defineAITextEditor } from './AITextEditor';
|
|
2
|
+
import { ButtonToolbarElement, ButtonToolbarGroup, defineButtonToolbar } from './ButtonToolbar';
|
|
3
|
+
import { MarkdownPreviewElement, defineMarkdownPreview } from './MarkdownPreview';
|
|
4
|
+
|
|
5
|
+
export class AIMarkdownEditorElement extends HTMLElement {
|
|
6
|
+
declare shadowRoot: ShadowRoot;
|
|
7
|
+
private aiEditor!: AITextEditorElement;
|
|
8
|
+
private toolbar!: ButtonToolbarElement;
|
|
9
|
+
private preview!: MarkdownPreviewElement;
|
|
10
|
+
private editorStatus!: HTMLElement;
|
|
11
|
+
private loading!: HTMLElement;
|
|
12
|
+
private isPreviewMode: boolean = false;
|
|
13
|
+
private markdownLibUrl: string = 'https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js';
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
super();
|
|
17
|
+
this.attachShadow({ mode: 'open' });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
connectedCallback(): void {
|
|
21
|
+
this.render();
|
|
22
|
+
this.init();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private render(): void {
|
|
26
|
+
this.shadowRoot.innerHTML = `
|
|
27
|
+
<style>
|
|
28
|
+
:host {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: 100%;
|
|
33
|
+
gap: 0.5rem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.editor-container {
|
|
37
|
+
flex: 1;
|
|
38
|
+
position: relative;
|
|
39
|
+
min-height: 0; /* Important for flexbox scrolling */
|
|
40
|
+
border: 2px solid #e1e5e9;
|
|
41
|
+
border-radius: 12px;
|
|
42
|
+
background: #fafbfc;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.editor-container:focus-within {
|
|
46
|
+
border-color: #4facfe;
|
|
47
|
+
background: white;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.editor-status {
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: 5px;
|
|
53
|
+
left: 5px;
|
|
54
|
+
width: 10px;
|
|
55
|
+
height: 10px;
|
|
56
|
+
border-radius: 100%;
|
|
57
|
+
background: #777;
|
|
58
|
+
z-index: 10;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.loading {
|
|
62
|
+
position: absolute;
|
|
63
|
+
top: 5px;
|
|
64
|
+
right: 10px;
|
|
65
|
+
z-index: 10;
|
|
66
|
+
display: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.loading.show {
|
|
70
|
+
display: block;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.spinner {
|
|
74
|
+
width: 10px;
|
|
75
|
+
height: 10px;
|
|
76
|
+
border: 2px solid #e1e5e9;
|
|
77
|
+
border-top: 2px solid #4facfe;
|
|
78
|
+
border-radius: 50%;
|
|
79
|
+
animation: spin 1s linear infinite;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@keyframes spin {
|
|
83
|
+
0% { transform: rotate(0deg); }
|
|
84
|
+
100% { transform: rotate(360deg); }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
liwe3-ai-text-editor {
|
|
88
|
+
width: 100%;
|
|
89
|
+
height: 100%;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.settings-modal {
|
|
93
|
+
position: absolute;
|
|
94
|
+
top: 50%;
|
|
95
|
+
left: 50%;
|
|
96
|
+
transform: translate(-50%, -50%);
|
|
97
|
+
background: white;
|
|
98
|
+
padding: 20px;
|
|
99
|
+
border-radius: 8px;
|
|
100
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
101
|
+
z-index: 100;
|
|
102
|
+
width: 400px;
|
|
103
|
+
max-width: 90%;
|
|
104
|
+
display: none;
|
|
105
|
+
border: 1px solid #e5e7eb;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.settings-modal.open {
|
|
109
|
+
display: block;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.settings-modal h3 {
|
|
113
|
+
margin-top: 0;
|
|
114
|
+
margin-bottom: 15px;
|
|
115
|
+
font-size: 18px;
|
|
116
|
+
color: #1f2937;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.form-group {
|
|
120
|
+
margin-bottom: 15px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.form-group label {
|
|
124
|
+
display: block;
|
|
125
|
+
margin-bottom: 5px;
|
|
126
|
+
font-size: 14px;
|
|
127
|
+
color: #4b5563;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.form-group input, .form-group textarea {
|
|
131
|
+
width: 100%;
|
|
132
|
+
padding: 8px;
|
|
133
|
+
border: 1px solid #d1d5db;
|
|
134
|
+
border-radius: 4px;
|
|
135
|
+
font-size: 14px;
|
|
136
|
+
box-sizing: border-box;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.form-group textarea {
|
|
140
|
+
resize: vertical;
|
|
141
|
+
min-height: 60px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.modal-actions {
|
|
145
|
+
display: flex;
|
|
146
|
+
justify-content: flex-end;
|
|
147
|
+
gap: 10px;
|
|
148
|
+
margin-top: 20px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.btn {
|
|
152
|
+
padding: 8px 16px;
|
|
153
|
+
border-radius: 4px;
|
|
154
|
+
border: none;
|
|
155
|
+
cursor: pointer;
|
|
156
|
+
font-size: 14px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.btn-primary {
|
|
160
|
+
background: #3b82f6;
|
|
161
|
+
color: white;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.btn-secondary {
|
|
165
|
+
background: #e5e7eb;
|
|
166
|
+
color: #374151;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.overlay {
|
|
170
|
+
position: fixed;
|
|
171
|
+
top: 0;
|
|
172
|
+
left: 0;
|
|
173
|
+
right: 0;
|
|
174
|
+
bottom: 0;
|
|
175
|
+
background: rgba(0,0,0,0.5);
|
|
176
|
+
z-index: 99;
|
|
177
|
+
display: none;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.overlay.open {
|
|
181
|
+
display: block;
|
|
182
|
+
}
|
|
183
|
+
</style>
|
|
184
|
+
<liwe3-button-toolbar id="toolbar"></liwe3-button-toolbar>
|
|
185
|
+
<div class="editor-container">
|
|
186
|
+
<div class="editor-status"></div>
|
|
187
|
+
<div class="loading" id="loading">
|
|
188
|
+
<div class="spinner"></div>
|
|
189
|
+
</div>
|
|
190
|
+
<liwe3-ai-text-editor id="editor"></liwe3-ai-text-editor>
|
|
191
|
+
<liwe3-markdown-preview id="preview" style="display: none; width: 100%; height: 100%; overflow: auto;"></liwe3-markdown-preview>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="overlay" id="overlay"></div>
|
|
195
|
+
<div class="settings-modal" id="settingsModal">
|
|
196
|
+
<h3>AI Settings</h3>
|
|
197
|
+
<div class="form-group">
|
|
198
|
+
<label for="apiKey">API Key</label>
|
|
199
|
+
<input type="password" id="apiKey" placeholder="sk-...">
|
|
200
|
+
</div>
|
|
201
|
+
<div class="form-group">
|
|
202
|
+
<label for="systemPrompt">System Prompt</label>
|
|
203
|
+
<textarea id="systemPrompt"></textarea>
|
|
204
|
+
</div>
|
|
205
|
+
<div class="form-group">
|
|
206
|
+
<label for="modelName">Model Name</label>
|
|
207
|
+
<input type="text" id="modelName" placeholder="gpt-3.5-turbo">
|
|
208
|
+
</div>
|
|
209
|
+
<div class="form-group">
|
|
210
|
+
<label for="apiEndpoint">API Endpoint</label>
|
|
211
|
+
<input type="text" id="apiEndpoint" placeholder="https://api.openai.com/v1/chat/completions">
|
|
212
|
+
</div>
|
|
213
|
+
<div class="form-group">
|
|
214
|
+
<label for="markdownLibUrl">Markdown Library URL</label>
|
|
215
|
+
<input type="text" id="markdownLibUrl" placeholder="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js">
|
|
216
|
+
</div>
|
|
217
|
+
<div class="form-group">
|
|
218
|
+
<label for="suggestionDelay">Suggestion Delay (seconds)</label>
|
|
219
|
+
<input type="number" id="suggestionDelay" step="0.1" min="0.5">
|
|
220
|
+
</div>
|
|
221
|
+
<div class="modal-actions">
|
|
222
|
+
<button class="btn btn-secondary" id="cancelBtn">Cancel</button>
|
|
223
|
+
<button class="btn btn-primary" id="saveBtn">Save</button>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private init(): void {
|
|
230
|
+
this.aiEditor = this.shadowRoot.getElementById('editor') as AITextEditorElement;
|
|
231
|
+
this.preview = this.shadowRoot.getElementById('preview') as MarkdownPreviewElement;
|
|
232
|
+
this.toolbar = this.shadowRoot.getElementById('toolbar') as ButtonToolbarElement;
|
|
233
|
+
this.editorStatus = this.shadowRoot.querySelector('.editor-status') as HTMLElement;
|
|
234
|
+
this.loading = this.shadowRoot.getElementById('loading') as HTMLElement;
|
|
235
|
+
|
|
236
|
+
// Configure the AITextEditor in embedded mode with callbacks
|
|
237
|
+
this.aiEditor.configure({
|
|
238
|
+
embedded: true,
|
|
239
|
+
onStatusChange: (hasApiKey: boolean) => {
|
|
240
|
+
this.editorStatus.style.backgroundColor = hasApiKey ? '#4caf50' : '#777';
|
|
241
|
+
},
|
|
242
|
+
onLoadingChange: (isLoading: boolean) => {
|
|
243
|
+
if (isLoading) {
|
|
244
|
+
this.loading.classList.add('show');
|
|
245
|
+
} else {
|
|
246
|
+
this.loading.classList.remove('show');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
this.setupModal();
|
|
252
|
+
this.setupToolbar();
|
|
253
|
+
|
|
254
|
+
// Forward events from aiEditor
|
|
255
|
+
this.aiEditor.addEventListener('change', (e: Event) => {
|
|
256
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
257
|
+
detail: (e as CustomEvent).detail,
|
|
258
|
+
bubbles: true,
|
|
259
|
+
composed: true
|
|
260
|
+
}));
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
this.aiEditor.addEventListener('beforeSuggestion', (e: Event) => {
|
|
264
|
+
this.dispatchEvent(new CustomEvent('beforeSuggestion', {
|
|
265
|
+
detail: (e as CustomEvent).detail,
|
|
266
|
+
bubbles: true,
|
|
267
|
+
composed: true,
|
|
268
|
+
cancelable: true
|
|
269
|
+
}));
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
private setupModal(): void {
|
|
274
|
+
const modal = this.shadowRoot.getElementById('settingsModal') as HTMLElement;
|
|
275
|
+
const overlay = this.shadowRoot.getElementById('overlay') as HTMLElement;
|
|
276
|
+
const cancelBtn = this.shadowRoot.getElementById('cancelBtn') as HTMLButtonElement;
|
|
277
|
+
const saveBtn = this.shadowRoot.getElementById('saveBtn') as HTMLButtonElement;
|
|
278
|
+
|
|
279
|
+
const close = () => {
|
|
280
|
+
modal.classList.remove('open');
|
|
281
|
+
overlay.classList.remove('open');
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
cancelBtn.addEventListener('click', close);
|
|
285
|
+
overlay.addEventListener('click', close);
|
|
286
|
+
|
|
287
|
+
saveBtn.addEventListener('click', () => {
|
|
288
|
+
const apiKey = (this.shadowRoot.getElementById('apiKey') as HTMLInputElement).value;
|
|
289
|
+
const systemPrompt = (this.shadowRoot.getElementById('systemPrompt') as HTMLTextAreaElement).value;
|
|
290
|
+
const modelName = (this.shadowRoot.getElementById('modelName') as HTMLInputElement).value;
|
|
291
|
+
const apiEndpoint = (this.shadowRoot.getElementById('apiEndpoint') as HTMLInputElement).value;
|
|
292
|
+
const markdownLibUrl = (this.shadowRoot.getElementById('markdownLibUrl') as HTMLInputElement).value;
|
|
293
|
+
const suggestionDelay = parseFloat((this.shadowRoot.getElementById('suggestionDelay') as HTMLInputElement).value);
|
|
294
|
+
|
|
295
|
+
this.aiEditor.setApiKey(apiKey);
|
|
296
|
+
this.aiEditor.setSystemPrompt(systemPrompt);
|
|
297
|
+
this.aiEditor.setModelName(modelName);
|
|
298
|
+
this.aiEditor.setApiEndpoint(apiEndpoint);
|
|
299
|
+
this.markdownLibUrl = markdownLibUrl;
|
|
300
|
+
if (!isNaN(suggestionDelay)) {
|
|
301
|
+
this.aiEditor.setSuggestionDelay(suggestionDelay);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
close();
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private openSettings(): void {
|
|
309
|
+
const modal = this.shadowRoot.getElementById('settingsModal') as HTMLElement;
|
|
310
|
+
const overlay = this.shadowRoot.getElementById('overlay') as HTMLElement;
|
|
311
|
+
|
|
312
|
+
// Load current values
|
|
313
|
+
(this.shadowRoot.getElementById('apiKey') as HTMLInputElement).value = this.aiEditor.getApiKey();
|
|
314
|
+
(this.shadowRoot.getElementById('systemPrompt') as HTMLTextAreaElement).value = this.aiEditor.getSystemPrompt();
|
|
315
|
+
(this.shadowRoot.getElementById('modelName') as HTMLInputElement).value = this.aiEditor.getModelName();
|
|
316
|
+
(this.shadowRoot.getElementById('apiEndpoint') as HTMLInputElement).value = this.aiEditor.getApiEndpoint();
|
|
317
|
+
(this.shadowRoot.getElementById('markdownLibUrl') as HTMLInputElement).value = this.markdownLibUrl;
|
|
318
|
+
(this.shadowRoot.getElementById('suggestionDelay') as HTMLInputElement).value = this.aiEditor.getSuggestionDelay().toString();
|
|
319
|
+
|
|
320
|
+
modal.classList.add('open');
|
|
321
|
+
overlay.classList.add('open');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private setupToolbar(): void {
|
|
325
|
+
const groups: ButtonToolbarGroup[] = [
|
|
326
|
+
{
|
|
327
|
+
id: 'format',
|
|
328
|
+
items: [
|
|
329
|
+
{
|
|
330
|
+
id: 'bold',
|
|
331
|
+
label: 'B',
|
|
332
|
+
tooltip: 'Bold',
|
|
333
|
+
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>'
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
id: 'italic',
|
|
337
|
+
label: 'I',
|
|
338
|
+
tooltip: 'Italic',
|
|
339
|
+
icon: '<svg viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>'
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: 'underline',
|
|
343
|
+
label: 'U',
|
|
344
|
+
tooltip: 'Underline',
|
|
345
|
+
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>'
|
|
346
|
+
}
|
|
347
|
+
]
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: 'lists',
|
|
351
|
+
items: [
|
|
352
|
+
{
|
|
353
|
+
id: 'ul',
|
|
354
|
+
label: 'UL',
|
|
355
|
+
tooltip: 'Unordered List',
|
|
356
|
+
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>'
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
id: 'ol',
|
|
360
|
+
label: 'OL',
|
|
361
|
+
tooltip: 'Numbered List',
|
|
362
|
+
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>'
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
id: 'settings',
|
|
368
|
+
items: [
|
|
369
|
+
{
|
|
370
|
+
id: 'preview',
|
|
371
|
+
tooltip: 'Toggle Preview',
|
|
372
|
+
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>'
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
id: 'settings',
|
|
376
|
+
tooltip: 'AI Settings',
|
|
377
|
+
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>'
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
}
|
|
381
|
+
];
|
|
382
|
+
|
|
383
|
+
this.toolbar.groups = groups;
|
|
384
|
+
this.toolbar.addEventListener('button-click', (e: Event) => {
|
|
385
|
+
const detail = (e as CustomEvent).detail;
|
|
386
|
+
this.handleToolbarAction(detail.id);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private togglePreview(): void {
|
|
391
|
+
this.isPreviewMode = !this.isPreviewMode;
|
|
392
|
+
if (this.isPreviewMode) {
|
|
393
|
+
this.preview.value = this.aiEditor.getText();
|
|
394
|
+
this.preview.libUrl = this.markdownLibUrl;
|
|
395
|
+
this.aiEditor.style.display = 'none';
|
|
396
|
+
this.preview.style.display = 'block';
|
|
397
|
+
} else {
|
|
398
|
+
this.aiEditor.style.display = 'block';
|
|
399
|
+
this.preview.style.display = 'none';
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
private handleToolbarAction(actionId: string): void {
|
|
404
|
+
if (actionId === 'preview') {
|
|
405
|
+
this.togglePreview();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const textarea = this.aiEditor.shadowRoot?.getElementById('editor') as HTMLTextAreaElement;
|
|
410
|
+
if (!textarea) return;
|
|
411
|
+
|
|
412
|
+
const start = textarea.selectionStart;
|
|
413
|
+
const end = textarea.selectionEnd;
|
|
414
|
+
const text = textarea.value;
|
|
415
|
+
const selectedText = text.substring(start, end);
|
|
416
|
+
|
|
417
|
+
let newText = '';
|
|
418
|
+
let newCursorPos = end;
|
|
419
|
+
|
|
420
|
+
switch (actionId) {
|
|
421
|
+
case 'settings':
|
|
422
|
+
this.openSettings();
|
|
423
|
+
return; // Exit early as we don't need text manipulation
|
|
424
|
+
case 'bold':
|
|
425
|
+
newText = text.substring(0, start) + `**${selectedText}**` + text.substring(end);
|
|
426
|
+
newCursorPos = end + 4; // ** + **
|
|
427
|
+
if (start === end) newCursorPos = start + 2; // Position inside **
|
|
428
|
+
break;
|
|
429
|
+
case 'italic':
|
|
430
|
+
newText = text.substring(0, start) + `*${selectedText}*` + text.substring(end);
|
|
431
|
+
newCursorPos = end + 2; // * + *
|
|
432
|
+
if (start === end) newCursorPos = start + 1; // Position inside *
|
|
433
|
+
break;
|
|
434
|
+
case 'underline':
|
|
435
|
+
newText = text.substring(0, start) + `<u>${selectedText}</u>` + text.substring(end);
|
|
436
|
+
newCursorPos = end + 7; // <u> + </u>
|
|
437
|
+
if (start === end) newCursorPos = start + 3; // Position inside <u>
|
|
438
|
+
break;
|
|
439
|
+
case 'ul':
|
|
440
|
+
// For lists, we want to handle multiline selection
|
|
441
|
+
if (start !== end) {
|
|
442
|
+
const lines = selectedText.split('\n');
|
|
443
|
+
const listText = lines.map(line => `- ${line}`).join('\n');
|
|
444
|
+
newText = text.substring(0, start) + listText + text.substring(end);
|
|
445
|
+
newCursorPos = start + listText.length;
|
|
446
|
+
} else {
|
|
447
|
+
// Insert at beginning of line? Or just insert marker?
|
|
448
|
+
// Simple version: insert marker
|
|
449
|
+
newText = text.substring(0, start) + `- ` + text.substring(end);
|
|
450
|
+
newCursorPos = start + 2;
|
|
451
|
+
}
|
|
452
|
+
break;
|
|
453
|
+
case 'ol':
|
|
454
|
+
if (start !== end) {
|
|
455
|
+
const lines = selectedText.split('\n');
|
|
456
|
+
const listText = lines.map((line, i) => `${i + 1}. ${line}`).join('\n');
|
|
457
|
+
newText = text.substring(0, start) + listText + text.substring(end);
|
|
458
|
+
newCursorPos = start + listText.length;
|
|
459
|
+
} else {
|
|
460
|
+
newText = text.substring(0, start) + `1. ` + text.substring(end);
|
|
461
|
+
newCursorPos = start + 3;
|
|
462
|
+
}
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (newText) {
|
|
467
|
+
textarea.value = newText;
|
|
468
|
+
textarea.focus();
|
|
469
|
+
|
|
470
|
+
// If we just inserted markers around empty selection, put cursor inside
|
|
471
|
+
if (start === end) {
|
|
472
|
+
if (actionId === 'bold') textarea.setSelectionRange(start + 2, start + 2);
|
|
473
|
+
else if (actionId === 'italic') textarea.setSelectionRange(start + 1, start + 1);
|
|
474
|
+
else if (actionId === 'underline') textarea.setSelectionRange(start + 3, start + 3);
|
|
475
|
+
else textarea.setSelectionRange(newCursorPos, newCursorPos);
|
|
476
|
+
} else {
|
|
477
|
+
// Select the modified text
|
|
478
|
+
// This is a bit complex to calculate exactly for all cases, so just putting cursor at end for now
|
|
479
|
+
textarea.setSelectionRange(newCursorPos, newCursorPos);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Trigger input event so AITextEditor updates
|
|
483
|
+
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Proxy methods to AITextEditor
|
|
488
|
+
setText(text: string): void {
|
|
489
|
+
if (this.aiEditor) {
|
|
490
|
+
this.aiEditor.setText(text);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
getText(): string {
|
|
495
|
+
return this.aiEditor ? this.aiEditor.getText() : '';
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
setApiKey(key: string): void {
|
|
499
|
+
if (this.aiEditor) {
|
|
500
|
+
this.aiEditor.setApiKey(key);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
getApiKey(): string {
|
|
505
|
+
return this.aiEditor ? this.aiEditor.getApiKey() : '';
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
setSuggestionDelay(seconds: number): void {
|
|
509
|
+
if (this.aiEditor) {
|
|
510
|
+
this.aiEditor.setSuggestionDelay(seconds);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
getSuggestionDelay(): number {
|
|
515
|
+
return this.aiEditor ? this.aiEditor.getSuggestionDelay() : 1;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
setSystemPrompt(prompt: string): void {
|
|
519
|
+
if (this.aiEditor) {
|
|
520
|
+
this.aiEditor.setSystemPrompt(prompt);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
getSystemPrompt(): string {
|
|
525
|
+
return this.aiEditor ? this.aiEditor.getSystemPrompt() : '';
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
setApiEndpoint(endpoint: string): void {
|
|
529
|
+
if (this.aiEditor) {
|
|
530
|
+
this.aiEditor.setApiEndpoint(endpoint);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
getApiEndpoint(): string {
|
|
535
|
+
return this.aiEditor ? this.aiEditor.getApiEndpoint() : '';
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
setModelName(modelName: string): void {
|
|
539
|
+
if (this.aiEditor) {
|
|
540
|
+
this.aiEditor.setModelName(modelName);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
getModelName(): string {
|
|
545
|
+
return this.aiEditor ? this.aiEditor.getModelName() : '';
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
setContext(context: string): void {
|
|
549
|
+
if (this.aiEditor) {
|
|
550
|
+
this.aiEditor.setContext(context);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
getContext(): string {
|
|
555
|
+
return this.aiEditor ? this.aiEditor.getContext() : '';
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export const defineAIMarkdownEditor = (tagName: string = 'liwe3-ai-markdown-editor'): void => {
|
|
560
|
+
if (typeof window !== 'undefined') {
|
|
561
|
+
defineAITextEditor();
|
|
562
|
+
defineButtonToolbar();
|
|
563
|
+
defineMarkdownPreview();
|
|
564
|
+
if (!customElements.get(tagName)) {
|
|
565
|
+
customElements.define(tagName, AIMarkdownEditorElement);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
};
|