@textbus/xnote 0.3.9 → 1.0.1

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.
@@ -1,17 +1,18 @@
1
1
  import { jsxs, jsx, Fragment } from '@viewfly/core/jsx-runtime';
2
2
  import { withScopedCSS } from '@viewfly/scoped-css';
3
3
  import { Injectable, InjectFlags, Injector, inject, createSignal, onUnmounted, getCurrentInstance, createRef, InjectionToken, withAnnotation, onUpdated, onMounted, watch, reactive, ReflectiveInjector, createDynamicRef, jsx as jsx$1, viewfly, Fragment as Fragment$1, createContext } from '@viewfly/core';
4
- import { Subject, fromEvent, Selection, Subscription, Attribute, Keyboard, Commander, Controller, useContext, onBreak, onContentInsert, ContentType, createVNode, merge, Slot, Component, Registry, Query, QueryStateType, Formatter, BehaviorSubject, onSlotApplyFormat, onSlotSetAttribute, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, onFocusIn, onFocusOut, onDetach, onGetRanges, onParentSlotUpdated, Textbus, History, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, debounceTime, delay, tap, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
4
+ import { Subject, fromEvent, Selection, Subscription, Controller, ContentType, Component, Attribute, Keyboard, Commander, useContext, onBreak, onContentInsert, createVNode, merge, Slot, Registry, Query, QueryStateType, Formatter, BehaviorSubject, onSlotApplyFormat, onSlotSetAttribute, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, onFocusIn, onFocusOut, onDetach, onGetRanges, onParentSlotUpdated, Textbus, History, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, debounceTime, delay, tap, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
5
5
  import { normalizeHex, hex2Hsl, hex2Rgb, hex2Hsv, hsl2Hex, hsl2Hsv, hsl2Rgb, rgb2Hsl, rgb2Hex, rgb2Hsv, hsv2Hex, hsv2Hsl, hsv2Rgb, any2Hsl, parseCss } from '@tanbo/color';
6
- import { VIEW_CONTAINER, isMac, DomAdapter, Input, BrowserModule, SelectionBridge, VIEW_DOCUMENT, CollaborateSelectionAwarenessDelegate, isMobileBrowser, CollaborateCursor, Parser } from '@textbus/platform-browser';
6
+ import { VIEW_CONTAINER, isMac, DomAdapter, Input, SelectionBridge, Parser, BrowserModule, VIEW_DOCUMENT, CollaborateSelectionAwarenessDelegate, isMobileBrowser, CollaborateCursor } from '@textbus/platform-browser';
7
7
  import { createPortal, createApp, DomRenderer, HTMLRenderer, OutputTranslator } from '@viewfly/platform-browser';
8
+ import MarkdownIt from 'markdown-it';
8
9
  import highlightjs from 'highlight.js';
9
10
  import { v4 } from 'uuid';
10
11
  import Katex from 'katex';
11
12
  import { ViewflyAdapter, ViewflyVDomAdapter } from '@textbus/adapter-viewfly';
12
13
  import { MessageBus, CollaborateModule } from '@textbus/collaborate';
13
14
 
14
- var scopedId$q = "vf-7d288d";
15
+ var scopedId$r = "vf-7d288d";
15
16
 
16
17
  /******************************************************************************
17
18
  Copyright (c) Microsoft Corporation.
@@ -201,7 +202,7 @@ function Button(props) {
201
202
  subscription.unsubscribe();
202
203
  });
203
204
  }
204
- return withScopedCSS(scopedId$q, () => {
205
+ return withScopedCSS(scopedId$r, () => {
205
206
  return (jsxs("button", Object.assign({ type: "button" }, props, { class: [
206
207
  'btn',
207
208
  {
@@ -213,7 +214,7 @@ function Button(props) {
213
214
  });
214
215
  }
215
216
 
216
- var scopedId$p = "vf-d552b9";
217
+ var scopedId$q = "vf-d552b9";
217
218
 
218
219
  class Picker {
219
220
  set hex(color) {
@@ -542,7 +543,7 @@ function ColorPicker(props) {
542
543
  props.onSelected(picker);
543
544
  addRecentColor();
544
545
  }
545
- return withScopedCSS(scopedId$p, () => {
546
+ return withScopedCSS(scopedId$q, () => {
546
547
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
547
548
  return (jsxs("div", { onMousedown: ev => {
548
549
  ev.stopPropagation();
@@ -593,10 +594,10 @@ function ColorPicker(props) {
593
594
  });
594
595
  }
595
596
 
596
- var scopedId$o = "vf-ac7e8d";
597
+ var scopedId$p = "vf-ac7e8d";
597
598
 
598
599
  function ComponentToolbar(props) {
599
- return withScopedCSS(scopedId$o, () => {
600
+ return withScopedCSS(scopedId$p, () => {
600
601
  return (jsx("div", { class: "component-toolbar", style: props.style, children: jsx("div", { class: [
601
602
  'toolbar',
602
603
  {
@@ -606,15 +607,15 @@ function ComponentToolbar(props) {
606
607
  });
607
608
  }
608
609
 
609
- var scopedId$n = "vf-ede279";
610
+ var scopedId$o = "vf-ede279";
610
611
 
611
612
  function Divider() {
612
- return withScopedCSS(scopedId$n, () => {
613
+ return withScopedCSS(scopedId$o, () => {
613
614
  return jsx("div", { class: "divider" });
614
615
  });
615
616
  }
616
617
 
617
- var scopedId$m = "vf-d91ad6";
618
+ var scopedId$n = "vf-d91ad6";
618
619
 
619
620
  function DragResize(props) {
620
621
  const isShow = createSignal(false);
@@ -723,16 +724,16 @@ function DragResize(props) {
723
724
  });
724
725
  }
725
726
  const sizeText = createSignal(`${component.state.width}*${component.state.height}`);
726
- return withScopedCSS(scopedId$m, () => {
727
+ return withScopedCSS(scopedId$n, () => {
727
728
  return (jsxs("div", { class: "drag-resize", onClick: selectComponent, children: [jsx("div", { class: "container", ref: ref, children: props.children }), jsxs("div", { class: ['resize-tool', {
728
729
  active: isShow()
729
730
  }], children: [jsx("div", { class: "mask", ref: mask, children: sizeText() }), jsxs("div", { class: "btn-group", ref: btnGroup, onMousedown: drag, children: [jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" }), jsx("button", { type: "button" })] })] })] }));
730
731
  });
731
732
  }
732
733
 
733
- var scopedId$l = "vf-0fd06a";
734
+ var scopedId$m = "vf-0fd06a";
734
735
 
735
- var scopedId$k = "vf-8a05e9";
736
+ var scopedId$l = "vf-8a05e9";
736
737
 
737
738
  const DropdownMenuContainer = new InjectionToken('DropdownMenuContainer');
738
739
  const DropdownMenuPortal = withAnnotation({
@@ -837,7 +838,7 @@ const DropdownMenuPortal = withAnnotation({
837
838
  function stopPropagation(ev) {
838
839
  ev.stopPropagation();
839
840
  }
840
- return createPortal(withScopedCSS(scopedId$k, () => {
841
+ return createPortal(withScopedCSS(scopedId$l, () => {
841
842
  return (jsx("div", { onMouseenter: onEnter, onMousedown: stopPropagation, onMouseleave: onLeave, ref: menuRef, style: {
842
843
  width: props.width
843
844
  }, class: "dropdown-menu", children: jsx("div", { class: "dropdown-menu-content", style: {
@@ -916,7 +917,7 @@ const Dropdown = withAnnotation({
916
917
  dropdownContextService.hide(false);
917
918
  }
918
919
  },
919
- $render: withScopedCSS(scopedId$l, () => {
920
+ $render: withScopedCSS(scopedId$m, () => {
920
921
  return (jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsx("div", { class: ['dropdown-btn-inner', {
921
922
  'has-arrow': props.arrow
922
923
  }], children: props.children }), props.arrow && jsx("div", { ref: arrowRef, class: "dropdown-btn-arrow", children: jsx(Button, { disabled: props.disabled, arrow: true }) })] }), isShow() &&
@@ -935,7 +936,7 @@ const Dropdown = withAnnotation({
935
936
  };
936
937
  });
937
938
 
938
- var scopedId$j = "vf-c32a7b";
939
+ var scopedId$k = "vf-c32a7b";
939
940
 
940
941
  function Keymap(props) {
941
942
  const arr = [];
@@ -969,20 +970,20 @@ function Keymap(props) {
969
970
  arr.push(jsx("span", { children: keymap.key }));
970
971
  }
971
972
  }
972
- return withScopedCSS(scopedId$j, () => {
973
+ return withScopedCSS(scopedId$k, () => {
973
974
  return (jsx("span", { class: "keymap", children: arr }));
974
975
  });
975
976
  }
976
977
 
977
- var scopedId$i = "vf-acaa5f";
978
+ var scopedId$j = "vf-acaa5f";
978
979
 
979
980
  function MenuHeading(props) {
980
- return withScopedCSS(scopedId$i, () => {
981
+ return withScopedCSS(scopedId$j, () => {
981
982
  return (jsx("div", { class: "menu-heading", children: props.children }));
982
983
  });
983
984
  }
984
985
 
985
- var scopedId$h = "vf-c3b9dc";
986
+ var scopedId$i = "vf-c3b9dc";
986
987
 
987
988
  function MenuItem(props) {
988
989
  const dropdownContextService = inject(DropdownContextService, null);
@@ -1002,7 +1003,7 @@ function MenuItem(props) {
1002
1003
  }
1003
1004
  (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, props.value);
1004
1005
  }
1005
- return withScopedCSS(scopedId$h, () => {
1006
+ return withScopedCSS(scopedId$i, () => {
1006
1007
  return (jsxs("div", { class: ['menu-item', { disabled: props.disabled, active: props.arrow && isActive() }], onClick: click, children: [jsxs("div", { class: "menu-item-content", children: [jsxs("div", { children: [props.icon && jsx("span", { class: "menu-icon", children: props.icon }), props.children] }), jsx("div", { children: props.desc })] }), props.arrow ?
1007
1008
  jsx("div", { class: "arrow", children: jsx("span", { class: "xnote-icon-arrow-right" }) }) :
1008
1009
  jsx("div", { class: [
@@ -1012,11 +1013,11 @@ function MenuItem(props) {
1012
1013
  });
1013
1014
  }
1014
1015
 
1015
- var scopedId$g = "vf-a23c47";
1016
+ var scopedId$h = "vf-a23c47";
1016
1017
 
1017
1018
  function Popup(props) {
1018
1019
  const host = inject(VIEW_CONTAINER);
1019
- return createPortal(withScopedCSS(scopedId$g, () => {
1020
+ return createPortal(withScopedCSS(scopedId$h, () => {
1020
1021
  return (jsx("div", { class: "popup", style: {
1021
1022
  left: props.left + 'px',
1022
1023
  top: props.top + 'px'
@@ -1024,65 +1025,47 @@ function Popup(props) {
1024
1025
  }), host);
1025
1026
  }
1026
1027
 
1027
- var scopedId$f = "vf-b7a2c8";
1028
+ var scopedId$g = "vf-b7a2c8";
1028
1029
 
1029
1030
  function ToolbarItem(props) {
1030
- return withScopedCSS(scopedId$f, () => {
1031
+ return withScopedCSS(scopedId$g, () => {
1031
1032
  return (jsx("div", { class: "toolbar-item", children: props.children }));
1032
1033
  });
1033
1034
  }
1034
1035
 
1035
- var scopedId$e = "vf-2a8a65";
1036
+ var scopedId$f = "vf-93d3ba";
1036
1037
 
1037
- let RefreshService = class RefreshService {
1038
+ let EditorService = class EditorService {
1038
1039
  constructor() {
1039
- Object.defineProperty(this, "onRefresh", {
1040
+ Object.defineProperty(this, "hideInlineToolbar", {
1041
+ enumerable: true,
1042
+ configurable: true,
1043
+ writable: true,
1044
+ value: false
1045
+ });
1046
+ Object.defineProperty(this, "canShowLeftToolbar", {
1047
+ enumerable: true,
1048
+ configurable: true,
1049
+ writable: true,
1050
+ value: true
1051
+ });
1052
+ Object.defineProperty(this, "onLeftToolbarCanVisibleChange", {
1040
1053
  enumerable: true,
1041
1054
  configurable: true,
1042
1055
  writable: true,
1043
1056
  value: new Subject()
1044
1057
  });
1045
1058
  }
1046
- };
1047
- RefreshService = __decorate([
1048
- Injectable()
1049
- ], RefreshService);
1050
-
1051
- const textAlignAttr = new Attribute('textAlign', {
1052
- render(node, formatValue) {
1053
- node.styles.set('text-align', formatValue);
1054
- }
1055
- });
1056
- const textAlignAttrLoader = {
1057
- match(element) {
1058
- return !!element.style.textAlign;
1059
- },
1060
- read(element) {
1061
- return {
1062
- attribute: textAlignAttr,
1063
- value: element.style.textAlign
1064
- };
1059
+ changeLeftToolbarVisible(b) {
1060
+ this.canShowLeftToolbar = b;
1061
+ this.onLeftToolbarCanVisibleChange.next();
1065
1062
  }
1066
1063
  };
1067
- function registerTextAlignShortcut(textbus) {
1068
- const keyboard = textbus.get(Keyboard);
1069
- const commander = textbus.get(Commander);
1070
- keyboard.addShortcut({
1071
- keymap: {
1072
- key: 'lrej'.split(''),
1073
- modKey: true
1074
- },
1075
- action(key) {
1076
- const valueMap = {
1077
- l: 'left',
1078
- r: 'right',
1079
- e: 'center',
1080
- j: 'justify'
1081
- };
1082
- commander.applyAttribute(textAlignAttr, valueMap[key]);
1083
- }
1084
- });
1085
- }
1064
+ EditorService = __decorate([
1065
+ Injectable({
1066
+ provideIn: 'root'
1067
+ })
1068
+ ], EditorService);
1086
1069
 
1087
1070
  function useReadonly() {
1088
1071
  const controller = inject(Controller);
@@ -1099,6 +1082,110 @@ function useOutput() {
1099
1082
  return createSignal(inject(OutputInjectionToken));
1100
1083
  }
1101
1084
 
1085
+ class ImageComponent extends Component {
1086
+ static fromJSON(textbus, json) {
1087
+ return new ImageComponent(Object.assign({}, json));
1088
+ }
1089
+ getSlots() {
1090
+ return [];
1091
+ }
1092
+ }
1093
+ Object.defineProperty(ImageComponent, "type", {
1094
+ enumerable: true,
1095
+ configurable: true,
1096
+ writable: true,
1097
+ value: ContentType.InlineComponent
1098
+ });
1099
+ Object.defineProperty(ImageComponent, "componentName", {
1100
+ enumerable: true,
1101
+ configurable: true,
1102
+ writable: true,
1103
+ value: 'ImageComponent'
1104
+ });
1105
+ function ImageView(props) {
1106
+ const { name, state } = props.component;
1107
+ const imageRef = createRef();
1108
+ const readonly = useReadonly();
1109
+ const output = useOutput();
1110
+ return () => {
1111
+ if (readonly() || output()) {
1112
+ return (jsx("div", { class: "xnote-image", ref: props.rootRef, "data-component": name, children: jsx("img", { alt: "", src: state.src, style: {
1113
+ width: state.width,
1114
+ height: state.height
1115
+ } }) }));
1116
+ }
1117
+ return (jsx("div", { class: "xnote-image", ref: props.rootRef, "data-component": name, children: jsx(DragResize, { source: imageRef, component: props.component, children: jsx("img", { alt: "", ref: imageRef, src: state.src, style: {
1118
+ width: state.width,
1119
+ height: state.height
1120
+ } }) }) }));
1121
+ };
1122
+ }
1123
+ const imageComponentLoader = {
1124
+ match(element) {
1125
+ return element.tagName === 'IMG' || element.dataset.component === ImageComponent.componentName;
1126
+ },
1127
+ read(element) {
1128
+ const img = element instanceof HTMLImageElement ? element : (element.querySelector('img') || document.createElement('img'));
1129
+ return new ImageComponent({
1130
+ src: img.src,
1131
+ width: img.style.width || 'auto',
1132
+ height: img.style.height || 'auto'
1133
+ });
1134
+ }
1135
+ };
1136
+
1137
+ class VideoComponent extends Component {
1138
+ static fromJSON(_, json) {
1139
+ return new VideoComponent(Object.assign({}, json));
1140
+ }
1141
+ getSlots() {
1142
+ return [];
1143
+ }
1144
+ }
1145
+ Object.defineProperty(VideoComponent, "type", {
1146
+ enumerable: true,
1147
+ configurable: true,
1148
+ writable: true,
1149
+ value: ContentType.InlineComponent
1150
+ });
1151
+ Object.defineProperty(VideoComponent, "componentName", {
1152
+ enumerable: true,
1153
+ configurable: true,
1154
+ writable: true,
1155
+ value: 'VideoComponent'
1156
+ });
1157
+ function VideoView(props) {
1158
+ const { name, state } = props.component;
1159
+ const videoRef = createRef();
1160
+ const readonly = useReadonly();
1161
+ const output = useOutput();
1162
+ return () => {
1163
+ if (readonly() || output()) {
1164
+ return (jsx("div", { class: "xnote-video", ref: props.rootRef, "data-component": name, children: jsx("video", { ref: videoRef, src: state.src, style: {
1165
+ width: state.width,
1166
+ height: state.height
1167
+ } }) }));
1168
+ }
1169
+ return (jsx("div", { ref: props.rootRef, class: "xnote-video", "data-component": name, children: jsx(DragResize, { source: videoRef, component: props.component, children: jsx("video", { ref: videoRef, src: state.src, style: {
1170
+ width: state.width,
1171
+ height: state.height
1172
+ } }) }) }));
1173
+ };
1174
+ }
1175
+ const videoComponentLoader = {
1176
+ match(element) {
1177
+ return element.tagName === 'VIDEO' || element.dataset.component === VideoComponent.componentName;
1178
+ },
1179
+ read(element) {
1180
+ const video = element instanceof HTMLVideoElement ? element : (element.querySelector('video') || document.createElement('video'));
1181
+ return new VideoComponent({
1182
+ src: video.src,
1183
+ width: video.style.width || 'auto',
1184
+ height: video.style.height || 'auto'
1185
+ });
1186
+ }
1187
+ };
1188
+
1102
1189
  const headingAttr = new Attribute('Heading', {
1103
1190
  render(node, formatValue) {
1104
1191
  node.classes.add('xnote-' + formatValue);
@@ -1182,6 +1269,89 @@ function useBlockContent(slot) {
1182
1269
  });
1183
1270
  }
1184
1271
 
1272
+ const textIndentAttr = new Attribute('textIndent', {
1273
+ render(node, formatValue) {
1274
+ return node.styles.set('text-indent', formatValue * 24 + 'px');
1275
+ }
1276
+ });
1277
+ const textIndentAttrLoader = {
1278
+ match(element) {
1279
+ return !!element.style.textIndent;
1280
+ },
1281
+ read(element) {
1282
+ return {
1283
+ attribute: textIndentAttr,
1284
+ value: (parseInt(element.style.textIndent) || 0) / 24
1285
+ };
1286
+ }
1287
+ };
1288
+ function registerTextIndentShortcut(textbus) {
1289
+ const keyboard = textbus.get(Keyboard);
1290
+ const selection = textbus.get(Selection);
1291
+ const commander = textbus.get(Commander);
1292
+ keyboard.addShortcut({
1293
+ keymap: {
1294
+ key: 'Tab',
1295
+ },
1296
+ action() {
1297
+ const blocks = selection.getBlocks();
1298
+ blocks.forEach(block => {
1299
+ if (block.slot.parent instanceof SourceCodeComponent) {
1300
+ return;
1301
+ }
1302
+ const currentIndent = block.slot.getAttribute(textIndentAttr);
1303
+ if (typeof currentIndent === 'number') {
1304
+ block.slot.setAttribute(textIndentAttr, currentIndent + 1);
1305
+ }
1306
+ else {
1307
+ block.slot.setAttribute(textIndentAttr, 1);
1308
+ }
1309
+ });
1310
+ }
1311
+ });
1312
+ keyboard.addShortcut({
1313
+ keymap: {
1314
+ key: 'Tab',
1315
+ shiftKey: true,
1316
+ },
1317
+ action() {
1318
+ const blocks = selection.getBlocks();
1319
+ blocks.forEach(block => {
1320
+ const currentIndent = block.slot.getAttribute(textIndentAttr);
1321
+ if (typeof currentIndent === 'number' && currentIndent > 1) {
1322
+ block.slot.setAttribute(textIndentAttr, currentIndent - 1);
1323
+ }
1324
+ else {
1325
+ block.slot.removeAttribute(textIndentAttr);
1326
+ }
1327
+ });
1328
+ }
1329
+ });
1330
+ keyboard.addShortcut({
1331
+ keymap: {
1332
+ key: 'Backspace'
1333
+ },
1334
+ action() {
1335
+ if (!selection.isCollapsed) {
1336
+ return false;
1337
+ }
1338
+ const slot = selection.commonAncestorSlot;
1339
+ const currentIndent = slot.getAttribute(textIndentAttr);
1340
+ if (typeof currentIndent === 'number' && selection.startOffset === 0) {
1341
+ if (currentIndent > 1) {
1342
+ slot.setAttribute(textIndentAttr, currentIndent - 1);
1343
+ }
1344
+ else {
1345
+ slot.removeAttribute(textIndentAttr);
1346
+ }
1347
+ }
1348
+ else {
1349
+ commander.delete(true);
1350
+ }
1351
+ }
1352
+ });
1353
+ }
1354
+
1185
1355
  function SlotRender(props) {
1186
1356
  const adapter = inject(DomAdapter);
1187
1357
  const instance = getCurrentInstance();
@@ -2278,270 +2448,83 @@ function SourceCodeView(props) {
2278
2448
  children = nodesToVNodes(item.slot, nodes, 0);
2279
2449
  if (!children.length) {
2280
2450
  const br = createVNode('br');
2281
- br.location = {
2282
- slot: item.slot,
2283
- startIndex: 0,
2284
- endIndex: 1
2285
- };
2286
- children.push(br);
2287
- }
2288
- }
2289
- return createVNode('div', {
2290
- class: 'xnote-source-code-line' + (item.emphasize ? ' xnote-source-code-line-emphasize' : ''),
2291
- key: item.slot.id
2292
- }, [
2293
- createVNode('span', { class: 'xnote-source-code-line-content' }, children)
2294
- ]);
2295
- }, readonly());
2296
- }) }), jsx("span", { class: "xnote-source-code-lang", children: lang })] })] }));
2297
- };
2298
- }
2299
- function nodesToVNodes(slot, nodes, index) {
2300
- return nodes.map(i => {
2301
- const location = {
2302
- slot,
2303
- startIndex: index,
2304
- endIndex: index + i.textContent.length
2305
- };
2306
- if (i.nodeType === Node.ELEMENT_NODE) {
2307
- const childNodes = Array.from(i.childNodes);
2308
- const vEle = createVNode('span', {
2309
- class: i.className
2310
- }, nodesToVNodes(slot, childNodes, index));
2311
- index = location.endIndex;
2312
- vEle.location = Object.assign({}, location);
2313
- return vEle;
2314
- }
2315
- index = location.endIndex;
2316
- const textNode = new VTextNode(i.textContent);
2317
- textNode.location = location;
2318
- return textNode;
2319
- });
2320
- }
2321
- const sourceCodeComponentLoader = {
2322
- match(element, returnableContentTypes) {
2323
- return returnableContentTypes.includes(ContentType.BlockComponent) &&
2324
- ((element.tagName === 'DIV' && element.dataset.component === SourceCodeComponent.componentName) ||
2325
- element.tagName === 'PRE');
2326
- },
2327
- read(el) {
2328
- let slots = [];
2329
- if (el.tagName === 'DIV') {
2330
- const lines = el.querySelectorAll('.xnote-source-code-line');
2331
- slots = Array.from(lines).map(i => {
2332
- const code = i.innerText.replace(/[\s\n]+$/, '');
2333
- const item = createCodeSlot();
2334
- const slot = item.slot;
2335
- item.emphasize = i.classList.contains('xnote-source-code-line-emphasize');
2336
- slot.insert(code);
2337
- return item;
2338
- });
2339
- }
2340
- else {
2341
- el.querySelectorAll('br').forEach(br => {
2342
- br.parentNode.replaceChild(document.createTextNode('\n'), br);
2343
- });
2344
- slots = el.innerText.split('\n').map(code => {
2345
- const item = createCodeSlot();
2346
- item.slot.insert(code);
2347
- return item;
2348
- });
2349
- }
2350
- return new SourceCodeComponent({
2351
- lang: el.dataset.lang || '',
2352
- theme: el.dataset.theme || '',
2353
- lineNumber: el.dataset.lineNumber === 'true',
2354
- autoBreak: el.dataset.autoBreak === 'true',
2355
- slots
2356
- });
2357
- },
2358
- };
2359
-
2360
- const textIndentAttr = new Attribute('textIndent', {
2361
- render(node, formatValue) {
2362
- return node.styles.set('text-indent', formatValue * 24 + 'px');
2363
- }
2364
- });
2365
- const textIndentAttrLoader = {
2366
- match(element) {
2367
- return !!element.style.textIndent;
2368
- },
2369
- read(element) {
2370
- return {
2371
- attribute: textIndentAttr,
2372
- value: (parseInt(element.style.textIndent) || 0) / 24
2373
- };
2374
- }
2375
- };
2376
- function registerTextIndentShortcut(textbus) {
2377
- const keyboard = textbus.get(Keyboard);
2378
- const selection = textbus.get(Selection);
2379
- const commander = textbus.get(Commander);
2380
- keyboard.addShortcut({
2381
- keymap: {
2382
- key: 'Tab',
2383
- },
2384
- action() {
2385
- const blocks = selection.getBlocks();
2386
- blocks.forEach(block => {
2387
- if (block.slot.parent instanceof SourceCodeComponent) {
2388
- return;
2389
- }
2390
- const currentIndent = block.slot.getAttribute(textIndentAttr);
2391
- if (typeof currentIndent === 'number') {
2392
- block.slot.setAttribute(textIndentAttr, currentIndent + 1);
2393
- }
2394
- else {
2395
- block.slot.setAttribute(textIndentAttr, 1);
2396
- }
2397
- });
2398
- }
2399
- });
2400
- keyboard.addShortcut({
2401
- keymap: {
2402
- key: 'Tab',
2403
- shiftKey: true,
2404
- },
2405
- action() {
2406
- const blocks = selection.getBlocks();
2407
- blocks.forEach(block => {
2408
- const currentIndent = block.slot.getAttribute(textIndentAttr);
2409
- if (typeof currentIndent === 'number' && currentIndent > 1) {
2410
- block.slot.setAttribute(textIndentAttr, currentIndent - 1);
2411
- }
2412
- else {
2413
- block.slot.removeAttribute(textIndentAttr);
2414
- }
2415
- });
2416
- }
2417
- });
2418
- keyboard.addShortcut({
2419
- keymap: {
2420
- key: 'Backspace'
2421
- },
2422
- action() {
2423
- if (!selection.isCollapsed) {
2424
- return false;
2425
- }
2426
- const slot = selection.commonAncestorSlot;
2427
- const currentIndent = slot.getAttribute(textIndentAttr);
2428
- if (typeof currentIndent === 'number' && selection.startOffset === 0) {
2429
- if (currentIndent > 1) {
2430
- slot.setAttribute(textIndentAttr, currentIndent - 1);
2431
- }
2432
- else {
2433
- slot.removeAttribute(textIndentAttr);
2434
- }
2435
- }
2436
- else {
2437
- commander.delete(true);
2438
- }
2439
- }
2440
- });
2441
- }
2442
-
2443
- class ImageComponent extends Component {
2444
- static fromJSON(textbus, json) {
2445
- return new ImageComponent(Object.assign({}, json));
2446
- }
2447
- getSlots() {
2448
- return [];
2449
- }
2450
- }
2451
- Object.defineProperty(ImageComponent, "type", {
2452
- enumerable: true,
2453
- configurable: true,
2454
- writable: true,
2455
- value: ContentType.InlineComponent
2456
- });
2457
- Object.defineProperty(ImageComponent, "componentName", {
2458
- enumerable: true,
2459
- configurable: true,
2460
- writable: true,
2461
- value: 'ImageComponent'
2462
- });
2463
- function ImageView(props) {
2464
- const { name, state } = props.component;
2465
- const imageRef = createRef();
2466
- const readonly = useReadonly();
2467
- const output = useOutput();
2468
- return () => {
2469
- if (readonly() || output()) {
2470
- return (jsx("div", { class: "xnote-image", ref: props.rootRef, "data-component": name, children: jsx("img", { alt: "", src: state.src, style: {
2471
- width: state.width,
2472
- height: state.height
2473
- } }) }));
2474
- }
2475
- return (jsx("div", { class: "xnote-image", ref: props.rootRef, "data-component": name, children: jsx(DragResize, { source: imageRef, component: props.component, children: jsx("img", { alt: "", ref: imageRef, src: state.src, style: {
2476
- width: state.width,
2477
- height: state.height
2478
- } }) }) }));
2479
- };
2480
- }
2481
- const imageComponentLoader = {
2482
- match(element) {
2483
- return element.tagName === 'IMG' || element.dataset.component === ImageComponent.componentName;
2484
- },
2485
- read(element) {
2486
- const img = element instanceof HTMLImageElement ? element : (element.querySelector('img') || document.createElement('img'));
2487
- return new ImageComponent({
2488
- src: img.src,
2489
- width: img.style.width || 'auto',
2490
- height: img.style.height || 'auto'
2491
- });
2492
- }
2493
- };
2494
-
2495
- class VideoComponent extends Component {
2496
- static fromJSON(_, json) {
2497
- return new VideoComponent(Object.assign({}, json));
2498
- }
2499
- getSlots() {
2500
- return [];
2501
- }
2502
- }
2503
- Object.defineProperty(VideoComponent, "type", {
2504
- enumerable: true,
2505
- configurable: true,
2506
- writable: true,
2507
- value: ContentType.InlineComponent
2508
- });
2509
- Object.defineProperty(VideoComponent, "componentName", {
2510
- enumerable: true,
2511
- configurable: true,
2512
- writable: true,
2513
- value: 'VideoComponent'
2514
- });
2515
- function VideoView(props) {
2516
- const { name, state } = props.component;
2517
- const videoRef = createRef();
2518
- const readonly = useReadonly();
2519
- const output = useOutput();
2520
- return () => {
2521
- if (readonly() || output()) {
2522
- return (jsx("div", { class: "xnote-video", ref: props.rootRef, "data-component": name, children: jsx("video", { ref: videoRef, src: state.src, style: {
2523
- width: state.width,
2524
- height: state.height
2525
- } }) }));
2526
- }
2527
- return (jsx("div", { ref: props.rootRef, class: "xnote-video", "data-component": name, children: jsx(DragResize, { source: videoRef, component: props.component, children: jsx("video", { ref: videoRef, src: state.src, style: {
2528
- width: state.width,
2529
- height: state.height
2530
- } }) }) }));
2451
+ br.location = {
2452
+ slot: item.slot,
2453
+ startIndex: 0,
2454
+ endIndex: 1
2455
+ };
2456
+ children.push(br);
2457
+ }
2458
+ }
2459
+ return createVNode('div', {
2460
+ class: 'xnote-source-code-line' + (item.emphasize ? ' xnote-source-code-line-emphasize' : ''),
2461
+ key: item.slot.id
2462
+ }, [
2463
+ createVNode('span', { class: 'xnote-source-code-line-content' }, children)
2464
+ ]);
2465
+ }, readonly());
2466
+ }) }), jsx("span", { class: "xnote-source-code-lang", children: lang })] })] }));
2531
2467
  };
2532
2468
  }
2533
- const videoComponentLoader = {
2534
- match(element) {
2535
- return element.tagName === 'VIDEO' || element.dataset.component === VideoComponent.componentName;
2469
+ function nodesToVNodes(slot, nodes, index) {
2470
+ return nodes.map(i => {
2471
+ const location = {
2472
+ slot,
2473
+ startIndex: index,
2474
+ endIndex: index + i.textContent.length
2475
+ };
2476
+ if (i.nodeType === Node.ELEMENT_NODE) {
2477
+ const childNodes = Array.from(i.childNodes);
2478
+ const vEle = createVNode('span', {
2479
+ class: i.className
2480
+ }, nodesToVNodes(slot, childNodes, index));
2481
+ index = location.endIndex;
2482
+ vEle.location = Object.assign({}, location);
2483
+ return vEle;
2484
+ }
2485
+ index = location.endIndex;
2486
+ const textNode = new VTextNode(i.textContent);
2487
+ textNode.location = location;
2488
+ return textNode;
2489
+ });
2490
+ }
2491
+ const sourceCodeComponentLoader = {
2492
+ match(element, returnableContentTypes) {
2493
+ return returnableContentTypes.includes(ContentType.BlockComponent) &&
2494
+ ((element.tagName === 'DIV' && element.dataset.component === SourceCodeComponent.componentName) ||
2495
+ element.tagName === 'PRE');
2536
2496
  },
2537
- read(element) {
2538
- const video = element instanceof HTMLVideoElement ? element : (element.querySelector('video') || document.createElement('video'));
2539
- return new VideoComponent({
2540
- src: video.src,
2541
- width: video.style.width || 'auto',
2542
- height: video.style.height || 'auto'
2497
+ read(el) {
2498
+ let slots = [];
2499
+ if (el.tagName === 'DIV') {
2500
+ const lines = el.querySelectorAll('.xnote-source-code-line');
2501
+ slots = Array.from(lines).map(i => {
2502
+ const code = i.innerText.replace(/[\s\n]+$/, '');
2503
+ const item = createCodeSlot();
2504
+ const slot = item.slot;
2505
+ item.emphasize = i.classList.contains('xnote-source-code-line-emphasize');
2506
+ slot.insert(code);
2507
+ return item;
2508
+ });
2509
+ }
2510
+ else {
2511
+ el.querySelectorAll('br').forEach(br => {
2512
+ br.parentNode.replaceChild(document.createTextNode('\n'), br);
2513
+ });
2514
+ slots = el.innerText.split('\n').map(code => {
2515
+ const item = createCodeSlot();
2516
+ item.slot.insert(code);
2517
+ return item;
2518
+ });
2519
+ }
2520
+ return new SourceCodeComponent({
2521
+ lang: el.dataset.lang || '',
2522
+ theme: el.dataset.theme || '',
2523
+ lineNumber: el.dataset.lineNumber === 'true',
2524
+ autoBreak: el.dataset.autoBreak === 'true',
2525
+ slots
2543
2526
  });
2544
- }
2527
+ },
2545
2528
  };
2546
2529
 
2547
2530
  let ToolService = class ToolService {
@@ -2572,11 +2555,17 @@ let ToolService = class ToolService {
2572
2555
  is = true;
2573
2556
  }
2574
2557
  }
2575
- this.state.set({
2558
+ const rawState = this.state();
2559
+ const newState = {
2576
2560
  selectEmbed: is,
2577
2561
  readonly: controller.readonly,
2578
2562
  inSourceCode: selection.commonAncestorComponent instanceof SourceCodeComponent
2579
- });
2563
+ };
2564
+ if (newState.selectEmbed !== rawState.selectEmbed ||
2565
+ newState.readonly !== rawState.readonly ||
2566
+ newState.inSourceCode !== rawState.inSourceCode) {
2567
+ this.state.set(newState);
2568
+ }
2580
2569
  });
2581
2570
  }
2582
2571
  destroy() {
@@ -2594,6 +2583,299 @@ function useCommonState() {
2594
2583
  return toolService.state;
2595
2584
  }
2596
2585
 
2586
+ /**
2587
+ * 大模型接口
2588
+ */
2589
+ class LLMService {
2590
+ }
2591
+
2592
+ function usePopupPosition() {
2593
+ const selectionBridge = inject(SelectionBridge);
2594
+ const container = inject(VIEW_CONTAINER);
2595
+ const selection = inject(Selection);
2596
+ return function (width, height) {
2597
+ const containerRect = container.getBoundingClientRect();
2598
+ const rect = selectionBridge.getRect({
2599
+ slot: selection.focusSlot,
2600
+ offset: selection.focusOffset
2601
+ }) || { left: 0, top: 0, width: 0, height: 0 };
2602
+ let left = rect.left - width / 2;
2603
+ const right = left + width;
2604
+ if (right > containerRect.right) {
2605
+ left = containerRect.right - width;
2606
+ }
2607
+ if (left < containerRect.left) {
2608
+ left = containerRect.left;
2609
+ }
2610
+ let top = rect.top - height - 10;
2611
+ if (top < 10) {
2612
+ top = rect.top + rect.height + 10;
2613
+ }
2614
+ return {
2615
+ left: left - containerRect.left,
2616
+ top: top - containerRect.top,
2617
+ };
2618
+ };
2619
+ }
2620
+
2621
+ function AiTool(props) {
2622
+ const llmService = inject(LLMService);
2623
+ const selection = inject(Selection);
2624
+ const commander = inject(Commander);
2625
+ const editorService = inject(EditorService);
2626
+ let isClickFromSelf = false;
2627
+ const sub = fromEvent(document, 'click').subscribe(() => {
2628
+ if (isClickFromSelf) {
2629
+ isClickFromSelf = false;
2630
+ return;
2631
+ }
2632
+ editorService.hideInlineToolbar = false;
2633
+ viewModel.showModal = false;
2634
+ });
2635
+ onUnmounted(() => {
2636
+ sub.unsubscribe();
2637
+ });
2638
+ const viewModel = reactive({
2639
+ showModal: false,
2640
+ content: '',
2641
+ type: 'translate'
2642
+ });
2643
+ const dropdownRef = createRef();
2644
+ let subscription = new Subscription();
2645
+ function continueContent() {
2646
+ var _a;
2647
+ viewModel.type = 'continue';
2648
+ viewModel.content = '';
2649
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2650
+ viewModel.showModal = true;
2651
+ dropdownRef.current.isShow(false);
2652
+ subscription.unsubscribe();
2653
+ subscription = llmService.continue({
2654
+ text: document.getSelection().toString()
2655
+ }).subscribe((text) => {
2656
+ viewModel.content += text;
2657
+ });
2658
+ }
2659
+ function polish() {
2660
+ var _a;
2661
+ viewModel.type = 'polish';
2662
+ viewModel.content = '';
2663
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2664
+ viewModel.showModal = true;
2665
+ dropdownRef.current.isShow(false);
2666
+ subscription.unsubscribe();
2667
+ subscription = llmService.polish({
2668
+ text: document.getSelection().toString()
2669
+ }).subscribe((text) => {
2670
+ viewModel.content += text;
2671
+ });
2672
+ }
2673
+ function simplify() {
2674
+ var _a;
2675
+ viewModel.type = 'simplify';
2676
+ viewModel.content = '';
2677
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2678
+ viewModel.showModal = true;
2679
+ dropdownRef.current.isShow(false);
2680
+ subscription.unsubscribe();
2681
+ subscription = llmService.simplify({
2682
+ text: document.getSelection().toString()
2683
+ }).subscribe((text) => {
2684
+ viewModel.content += text;
2685
+ });
2686
+ }
2687
+ function enrich() {
2688
+ var _a;
2689
+ viewModel.type = 'enrich';
2690
+ viewModel.content = '';
2691
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2692
+ viewModel.showModal = true;
2693
+ dropdownRef.current.isShow(false);
2694
+ subscription.unsubscribe();
2695
+ subscription = llmService.enrich({
2696
+ text: document.getSelection().toString()
2697
+ }).subscribe((text) => {
2698
+ viewModel.content += text;
2699
+ });
2700
+ }
2701
+ function translate(lang) {
2702
+ var _a;
2703
+ viewModel.type = 'translate';
2704
+ viewModel.content = '';
2705
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2706
+ viewModel.showModal = true;
2707
+ dropdownRef.current.isShow(false);
2708
+ subscription.unsubscribe();
2709
+ subscription = llmService.translate({
2710
+ text: document.getSelection().toString(),
2711
+ targetLanguage: lang
2712
+ }).subscribe((text) => {
2713
+ viewModel.content += text;
2714
+ });
2715
+ }
2716
+ function summarize() {
2717
+ var _a;
2718
+ viewModel.type = 'summarize';
2719
+ viewModel.content = '';
2720
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2721
+ viewModel.showModal = true;
2722
+ dropdownRef.current.isShow(false);
2723
+ subscription.unsubscribe();
2724
+ subscription = llmService.summarize({
2725
+ text: document.getSelection().toString(),
2726
+ }).subscribe((text) => {
2727
+ viewModel.content += text;
2728
+ });
2729
+ }
2730
+ const aiContentRef = createRef();
2731
+ const parser = inject(Parser);
2732
+ function insert() {
2733
+ var _a;
2734
+ selection.collapse();
2735
+ aiContentRef.current.childNodes.forEach(node => {
2736
+ const slot = parser.parse(node instanceof HTMLElement ? node : node.textContent || '', new Slot([
2737
+ ContentType.BlockComponent,
2738
+ ContentType.InlineComponent,
2739
+ ContentType.Text
2740
+ ]));
2741
+ commander.paste(slot, aiContentRef.current.innerText);
2742
+ });
2743
+ viewModel.showModal = false;
2744
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2745
+ }
2746
+ function replace() {
2747
+ var _a;
2748
+ if (!selection.isCollapsed) {
2749
+ commander.delete();
2750
+ }
2751
+ insert();
2752
+ (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
2753
+ }
2754
+ const md = new MarkdownIt({
2755
+ html: true,
2756
+ breaks: true,
2757
+ linkify: true
2758
+ });
2759
+ function renderMarkdown(markdown) {
2760
+ const html = md.render(markdown);
2761
+ const tempDiv = document.createElement('div');
2762
+ tempDiv.innerHTML = html;
2763
+ function parseNode(node) {
2764
+ if (node.nodeType === Node.TEXT_NODE) {
2765
+ return node.textContent;
2766
+ }
2767
+ if (node.nodeType === Node.ELEMENT_NODE) {
2768
+ const element = node;
2769
+ const TagName = element.tagName.toLowerCase();
2770
+ const children = Array.from(element.childNodes).map(parseNode);
2771
+ const props = {};
2772
+ if (element.className) {
2773
+ props.class = element.className;
2774
+ }
2775
+ switch (TagName) {
2776
+ case 'h1':
2777
+ case 'h2':
2778
+ case 'h3':
2779
+ case 'h4':
2780
+ case 'h5':
2781
+ case 'h6':
2782
+ case 'p':
2783
+ case 'strong':
2784
+ case 'em':
2785
+ case 'code':
2786
+ case 'pre':
2787
+ case 'blockquote':
2788
+ case 'ul':
2789
+ case 'ol':
2790
+ case 'li':
2791
+ case 'span':
2792
+ case 'div':
2793
+ return jsx(TagName, Object.assign({}, props, { children: children }));
2794
+ case 'br':
2795
+ return jsx("br", {});
2796
+ case 'a':
2797
+ props.href = element.getAttribute('href') || '';
2798
+ return jsx("a", Object.assign({}, props, { children: children }));
2799
+ case 'img':
2800
+ props.src = element.getAttribute('src') || '';
2801
+ props.alt = element.getAttribute('alt') || '';
2802
+ return jsx("img", Object.assign({}, props));
2803
+ case 'hr':
2804
+ return jsx("hr", {});
2805
+ default:
2806
+ return jsx("span", Object.assign({}, props, { children: children }));
2807
+ }
2808
+ }
2809
+ return null;
2810
+ }
2811
+ return Array.from(tempDiv.childNodes).map(parseNode);
2812
+ }
2813
+ const commonState = useCommonState();
2814
+ const popupPosition = usePopupPosition();
2815
+ return withScopedCSS(scopedId$f, () => {
2816
+ const rect = popupPosition(400, 210);
2817
+ const b = commonState().inSourceCode || commonState().readonly && !selection.isCollapsed;
2818
+ return (jsxs(Fragment, { children: [jsx(Dropdown, { ref: dropdownRef, disabled: b, width: '160px', menu: !viewModel.showModal ? jsxs("div", { onClick: () => isClickFromSelf = true, children: [jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-continuation" }), onClick: continueContent, children: "\u7EED\u5199" }), jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-magic-wand" }), onClick: polish, children: "\u6DA6\u8272" }), jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-simplify" }), onClick: simplify, children: "\u7B80\u5316\u5185\u5BB9" }), jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-enrich" }), onClick: enrich, children: "\u4E30\u5BCC\u5185\u5BB9" }), jsx(Divider, {}), jsx(Dropdown, { style: {
2819
+ display: 'block'
2820
+ }, abreast: true, menu: jsxs("div", { onClick: () => isClickFromSelf = true, children: [jsx(MenuItem, { onClick: () => translate('中文'), children: "\u4E2D\u6587" }), jsx(MenuItem, { onClick: () => translate('英语'), children: "\u82F1\u8BED" }), jsx(MenuItem, { onClick: () => translate('西班牙语'), children: "\u897F\u73ED\u7259\u8BED" }), jsx(MenuItem, { onClick: () => translate('日语'), children: "\u65E5\u8BED" })] }), children: jsx(MenuItem, { arrow: true, icon: jsx("span", { class: "xnote-icon-translation" }), children: "\u7FFB\u8BD1" }) }), jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-summary" }), onClick: summarize, children: "\u603B\u7ED3" })] }) : null, children: jsx(Button, { arrow: true, disabled: b, children: jsx("span", { class: "xnote-icon-ai" }) }) }), viewModel.showModal &&
2821
+ jsx(Popup, { left: rect.left, top: rect.top, children: jsxs("div", { onClick: () => {
2822
+ isClickFromSelf = true;
2823
+ }, class: "input-group", children: [jsx("div", { class: "ai-content", ref: aiContentRef, children: renderMarkdown(viewModel.content) }), jsxs("div", { class: "btn-group", children: [jsx(Button, { type: "button", onClick: replace, children: "\u66FF\u6362" }), jsx(Button, { type: "button", onClick: insert, children: "\u63D2\u5165" })] })] }) })] }));
2824
+ });
2825
+ }
2826
+
2827
+ var scopedId$e = "vf-2a8a65";
2828
+
2829
+ let RefreshService = class RefreshService {
2830
+ constructor() {
2831
+ Object.defineProperty(this, "onRefresh", {
2832
+ enumerable: true,
2833
+ configurable: true,
2834
+ writable: true,
2835
+ value: new Subject()
2836
+ });
2837
+ }
2838
+ };
2839
+ RefreshService = __decorate([
2840
+ Injectable()
2841
+ ], RefreshService);
2842
+
2843
+ const textAlignAttr = new Attribute('textAlign', {
2844
+ render(node, formatValue) {
2845
+ node.styles.set('text-align', formatValue);
2846
+ }
2847
+ });
2848
+ const textAlignAttrLoader = {
2849
+ match(element) {
2850
+ return !!element.style.textAlign;
2851
+ },
2852
+ read(element) {
2853
+ return {
2854
+ attribute: textAlignAttr,
2855
+ value: element.style.textAlign
2856
+ };
2857
+ }
2858
+ };
2859
+ function registerTextAlignShortcut(textbus) {
2860
+ const keyboard = textbus.get(Keyboard);
2861
+ const commander = textbus.get(Commander);
2862
+ keyboard.addShortcut({
2863
+ keymap: {
2864
+ key: 'lrej'.split(''),
2865
+ modKey: true
2866
+ },
2867
+ action(key) {
2868
+ const valueMap = {
2869
+ l: 'left',
2870
+ r: 'right',
2871
+ e: 'center',
2872
+ j: 'justify'
2873
+ };
2874
+ commander.applyAttribute(textAlignAttr, valueMap[key]);
2875
+ }
2876
+ });
2877
+ }
2878
+
2597
2879
  function AttrTool(props) {
2598
2880
  const commander = inject(Commander);
2599
2881
  const selection = inject(Selection);
@@ -5021,44 +5303,9 @@ function ItalicTool() {
5021
5303
 
5022
5304
  var scopedId$c = "vf-e74208";
5023
5305
 
5024
- let EditorService = class EditorService {
5025
- constructor() {
5026
- Object.defineProperty(this, "hideInlineToolbar", {
5027
- enumerable: true,
5028
- configurable: true,
5029
- writable: true,
5030
- value: false
5031
- });
5032
- Object.defineProperty(this, "canShowLeftToolbar", {
5033
- enumerable: true,
5034
- configurable: true,
5035
- writable: true,
5036
- value: true
5037
- });
5038
- Object.defineProperty(this, "onLeftToolbarCanVisibleChange", {
5039
- enumerable: true,
5040
- configurable: true,
5041
- writable: true,
5042
- value: new Subject()
5043
- });
5044
- }
5045
- changeLeftToolbarVisible(b) {
5046
- this.canShowLeftToolbar = b;
5047
- this.onLeftToolbarCanVisibleChange.next();
5048
- }
5049
- };
5050
- EditorService = __decorate([
5051
- Injectable({
5052
- provideIn: 'root'
5053
- })
5054
- ], EditorService);
5055
-
5056
5306
  function LinkTool(props) {
5057
- const selectionBridge = inject(SelectionBridge);
5058
- const selection = inject(Selection);
5059
5307
  const commander = inject(Commander);
5060
5308
  const editorService = inject(EditorService);
5061
- const container = inject(VIEW_CONTAINER);
5062
5309
  const isShow = createSignal(false);
5063
5310
  const value = createSignal('');
5064
5311
  function setLink(ev) {
@@ -5082,19 +5329,16 @@ function LinkTool(props) {
5082
5329
  sub.unsubscribe();
5083
5330
  });
5084
5331
  const commonState = useCommonState();
5332
+ const popupPosition = usePopupPosition();
5085
5333
  return withScopedCSS(scopedId$c, () => {
5086
- const containerRect = container.getBoundingClientRect();
5087
- const rect = isShow() ? selectionBridge.getRect({
5088
- slot: selection.focusSlot,
5089
- offset: selection.focusOffset
5090
- }) : {};
5334
+ const rect = popupPosition(224, 38);
5091
5335
  return (jsxs("span", { children: [jsx(Button, { disabled: commonState().inSourceCode || commonState().readonly, onClick: () => {
5092
5336
  var _a;
5093
5337
  isShow.set(true);
5094
5338
  isClickFromSelf = true;
5095
5339
  (_a = props.hideToolbar) === null || _a === void 0 ? void 0 : _a.call(props);
5096
5340
  }, children: jsx("span", { class: "xnote-icon-link" }) }), isShow() &&
5097
- jsx(Popup, { left: rect.left - containerRect.left, top: rect.top + rect.height - containerRect.top, children: jsxs("form", { onSubmit: setLink, onClick: () => {
5341
+ jsx(Popup, { left: rect.left, top: rect.top, children: jsxs("form", { onSubmit: setLink, onClick: () => {
5098
5342
  isClickFromSelf = true;
5099
5343
  }, class: "input-group", children: [jsx("input", { onChange: ev => {
5100
5344
  value.set(ev.target.value);
@@ -6147,6 +6391,7 @@ const InlineToolbar = withAnnotation({
6147
6391
  mousedownSubscription.unsubscribe();
6148
6392
  mouseupSubscription.unsubscribe();
6149
6393
  });
6394
+ const llmService = inject(LLMService, null);
6150
6395
  return withScopedCSS(scopedId$8, () => {
6151
6396
  return (jsxs("div", { class: ['toolbar', props.theme], ref: toolbarRef, style: {
6152
6397
  left: viewPosition.left + 'px',
@@ -6155,7 +6400,7 @@ const InlineToolbar = withAnnotation({
6155
6400
  opacity: viewPosition.opacity,
6156
6401
  display: editorService.hideInlineToolbar ? 'none' : '',
6157
6402
  transitionDuration: viewPosition.transitionDuration + 's'
6158
- }, children: [jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, { hideToolbar: hideToolbar }) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }));
6403
+ }, children: [llmService && jsx(ToolbarItem, { children: jsx(AiTool, { hideToolbar: hideToolbar }) }), jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, { hideToolbar: hideToolbar }) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }));
6159
6404
  });
6160
6405
  });
6161
6406
 
@@ -6212,8 +6457,9 @@ const StaticToolbar = withAnnotation({
6212
6457
  onUnmounted(() => {
6213
6458
  subscription.unsubscribe();
6214
6459
  });
6460
+ const llmService = inject(LLMService, null);
6215
6461
  return withScopedCSS(scopedId$7, () => {
6216
- return (jsxs("div", { class: ['toolbar', props.theme], children: [jsx(ToolbarItem, { children: jsx(UndoTool, {}) }), jsx(ToolbarItem, { children: jsx(RedoTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(InsertTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, {}) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }));
6462
+ return (jsxs("div", { class: ['toolbar', props.theme], children: [jsx(ToolbarItem, { children: jsx(UndoTool, {}) }), jsx(ToolbarItem, { children: jsx(RedoTool, {}) }), jsx(SplitLine, {}), llmService && jsx(ToolbarItem, { children: jsx(AiTool, {}) }), jsx(ToolbarItem, { children: jsx(InsertTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, {}) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }));
6217
6463
  });
6218
6464
  });
6219
6465
 
@@ -6260,7 +6506,7 @@ class StaticToolbarPlugin {
6260
6506
  }
6261
6507
  }
6262
6508
 
6263
- var scopedId$6 = "vf-25fd9c";
6509
+ var scopedId$6 = "vf-927bfc";
6264
6510
 
6265
6511
  const SuspensionToolbar = withAnnotation({
6266
6512
  providers: [RefreshService, ToolService]
@@ -6295,14 +6541,15 @@ const SuspensionToolbar = withAnnotation({
6295
6541
  }), delay(100)).subscribe(() => {
6296
6542
  styles.opacity = 1;
6297
6543
  }));
6544
+ const llmService = inject(LLMService, null);
6298
6545
  return withScopedCSS(scopedId$6, () => {
6299
- return (jsxs("div", { class: ['toolbar', props.theme, {
6546
+ return (jsx("div", { class: ['toolbar', props.theme, {
6300
6547
  suspension: styles.top === 0 ? '' : 'suspension'
6301
6548
  }], style: {
6302
6549
  top: styles.top + 'px',
6303
6550
  opacity: styles.opacity,
6304
6551
  pointerEvents: styles.opacity === 0 ? 'none' : 'initial',
6305
- }, children: [jsx(ToolbarItem, { children: jsx(UndoTool, {}) }), jsx(ToolbarItem, { children: jsx(RedoTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(InsertTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, {}) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }));
6552
+ }, children: jsxs("div", { class: "toolbar-tools", children: [jsx(ToolbarItem, { children: jsx(UndoTool, {}) }), jsx(ToolbarItem, { children: jsx(RedoTool, {}) }), jsx(SplitLine, {}), llmService && jsx(ToolbarItem, { children: jsx(AiTool, {}) }), jsx(ToolbarItem, { children: jsx(InsertTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BlockTool, {}) }), jsx(ToolbarItem, { children: jsx(AttrTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(BoldTool, {}) }), jsx(ToolbarItem, { children: jsx(ItalicTool, {}) }), jsx(ToolbarItem, { children: jsx(StrikeThroughTool, {}) }), jsx(ToolbarItem, { children: jsx(UnderlineTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(FontSizeTool, {}) }), jsx(ToolbarItem, { children: jsx(FontFamilyTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(LinkTool, {}) }), jsx(ToolbarItem, { children: jsx(CodeTool, {}) }), jsx(ToolbarItem, { children: jsx(TextColorTool, {}) }), jsx(ToolbarItem, { children: jsx(TextBackgroundColorTool, {}) }), jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(SubscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(SuperscriptTool, {}) }), jsx(ToolbarItem, { children: jsx(CleanFormatsTool, {}) }), query.queryComponent(TableComponent).state === QueryStateType.Enabled && jsxs(Fragment$1, { children: [jsx(SplitLine, {}), jsx(ToolbarItem, { children: jsx(MergeCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(SplitCellsTool, {}) }), jsx(ToolbarItem, { children: jsx(CellBackgroundTool, {}) }), jsx(ToolbarItem, { children: jsx(CellAlignTool, {}) })] }, "table")] }) }));
6306
6553
  });
6307
6554
  });
6308
6555
 
@@ -6330,6 +6577,7 @@ class SuspensionToolbarPlugin {
6330
6577
  setup(injector) {
6331
6578
  const host = injector.get(VIEW_CONTAINER);
6332
6579
  const container = document.createElement('div');
6580
+ container.style.cssText = 'display:flex;justify-content:center;';
6333
6581
  this.app = createApp(jsx(SuspensionToolbar, { theme: this.options.theme }), {
6334
6582
  context: injector
6335
6583
  });
@@ -8107,4 +8355,4 @@ class Editor extends Textbus {
8107
8355
  }
8108
8356
  }
8109
8357
 
8110
- export { AtComponent, AtComponentView, AttrTool, BlockTool, BlockquoteComponent, BlockquoteView, BoldTool, Button, CellAlignTool, CellBackgroundTool, CleanFormatsTool, CodeTool, ColorPicker, ComponentToolbar, Divider, DragResize, Dropdown, DropdownContextService, DropdownMenuContainer, DropdownMenuPortal, DropdownService, Editor, EditorService, FileUploader, FontFamilyTool, FontSizeTool, HighlightBoxComponent, HighlightBoxView, ImageComponent, ImageView, InlineToolbar, InlineToolbarPlugin, InsertMenu, InsertTool, ItalicTool, KatexComponent, KatexComponentView, Keymap, LeftToolbar, LeftToolbarPlugin, LinkJump, LinkTool, ListComponent, ListComponentView, Matcher, MenuHeading, MenuItem, MergeCellsTool, Organization, OutputInjectionToken, ParagraphComponent, ParagraphView, Picker, Popup, RedoTool, RefreshService, RootComponent, RootView, SourceCodeComponent, SourceCodeView, SplitCellsTool, SplitLine, StaticToolbar, StaticToolbarPlugin, StrikeThroughTool, SubscriptTool, SuperscriptTool, SuspensionToolbar, SuspensionToolbarPlugin, TableComponent, TableComponentView, TextBackgroundColorTool, TextColorTool, TodolistComponent, TodolistView, ToolbarItem, UnderlineTool, UndoTool, VideoComponent, VideoView, XNoteMessageBus, atComponentLoader, backgroundColorFormatLoader, backgroundColorFormatter, blockquoteComponentLoader, boldFormatLoader, boldFormatter, cellAlignAttr, cellAlignAttrLoader, cellBackgroundAttr, cellBackgroundAttrLoader, codeFormatLoader, codeFormatter, colorFormatLoader, colorFormatter, deltaToBlock, fontFamilyFormatLoader, fontFamilyFormatter, fontSizeFormatLoader, fontSizeFormatter, headingAttr, headingAttrLoader, highlightBoxComponentLoader, imageComponentLoader, isSupportFont, italicFormatLoader, italicFormatter, katexComponentLoader, languageList, linkFormatLoader, linkFormatter, listComponentLoader, paragraphComponentLoader, registerAtShortcut, registerBlockquoteShortcut, registerBoldShortcut, registerCodeShortcut, registerHeadingShortcut, registerItalicShortcut, registerListShortcut, registerStrikeThroughShortcut, registerTextAlignShortcut, registerTextIndentShortcut, registerUnderlineShortcut, rootComponentLoader, sourceCodeComponentLoader, sourceCodeThemes, strikeThroughFormatLoader, strikeThroughFormatter, subscriptFormatLoader, subscriptFormatter, superscriptFormatLoader, superscriptFormatter, tableComponentLoader, textAlignAttr, textAlignAttrLoader, textIndentAttr, textIndentAttrLoader, toBlockquote, toList, todolistComponentLoader, toggleBold, toggleCode, toggleItalic, toggleStrikeThrough, toggleUnderline, underlineFormatLoader, underlineFormatter, useActiveBlock, useBlockContent, useBlockTransform, useOutput, useReadonly, videoComponentLoader };
8358
+ export { AiTool, AtComponent, AtComponentView, AttrTool, BlockTool, BlockquoteComponent, BlockquoteView, BoldTool, Button, CellAlignTool, CellBackgroundTool, CleanFormatsTool, CodeTool, ColorPicker, ComponentToolbar, Divider, DragResize, Dropdown, DropdownContextService, DropdownMenuContainer, DropdownMenuPortal, DropdownService, Editor, EditorService, FileUploader, FontFamilyTool, FontSizeTool, HighlightBoxComponent, HighlightBoxView, ImageComponent, ImageView, InlineToolbar, InlineToolbarPlugin, InsertMenu, InsertTool, ItalicTool, KatexComponent, KatexComponentView, Keymap, LLMService, LeftToolbar, LeftToolbarPlugin, LinkJump, LinkTool, ListComponent, ListComponentView, Matcher, MenuHeading, MenuItem, MergeCellsTool, Organization, OutputInjectionToken, ParagraphComponent, ParagraphView, Picker, Popup, RedoTool, RefreshService, RootComponent, RootView, SourceCodeComponent, SourceCodeView, SplitCellsTool, SplitLine, StaticToolbar, StaticToolbarPlugin, StrikeThroughTool, SubscriptTool, SuperscriptTool, SuspensionToolbar, SuspensionToolbarPlugin, TableComponent, TableComponentView, TextBackgroundColorTool, TextColorTool, TodolistComponent, TodolistView, ToolbarItem, UnderlineTool, UndoTool, VideoComponent, VideoView, XNoteMessageBus, atComponentLoader, backgroundColorFormatLoader, backgroundColorFormatter, blockquoteComponentLoader, boldFormatLoader, boldFormatter, cellAlignAttr, cellAlignAttrLoader, cellBackgroundAttr, cellBackgroundAttrLoader, codeFormatLoader, codeFormatter, colorFormatLoader, colorFormatter, deltaToBlock, fontFamilyFormatLoader, fontFamilyFormatter, fontSizeFormatLoader, fontSizeFormatter, headingAttr, headingAttrLoader, highlightBoxComponentLoader, imageComponentLoader, isSupportFont, italicFormatLoader, italicFormatter, katexComponentLoader, languageList, linkFormatLoader, linkFormatter, listComponentLoader, paragraphComponentLoader, registerAtShortcut, registerBlockquoteShortcut, registerBoldShortcut, registerCodeShortcut, registerHeadingShortcut, registerItalicShortcut, registerListShortcut, registerStrikeThroughShortcut, registerTextAlignShortcut, registerTextIndentShortcut, registerUnderlineShortcut, rootComponentLoader, sourceCodeComponentLoader, sourceCodeThemes, strikeThroughFormatLoader, strikeThroughFormatter, subscriptFormatLoader, subscriptFormatter, superscriptFormatLoader, superscriptFormatter, tableComponentLoader, textAlignAttr, textAlignAttrLoader, textIndentAttr, textIndentAttrLoader, toBlockquote, toList, todolistComponentLoader, toggleBold, toggleCode, toggleItalic, toggleStrikeThrough, toggleUnderline, underlineFormatLoader, underlineFormatter, useActiveBlock, useBlockContent, useBlockTransform, useOutput, useReadonly, videoComponentLoader };