@textbus/xnote 0.0.1-alpha.14 → 0.0.1-alpha.16

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,8 +1,8 @@
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, createRef, withAnnotation, onUpdated, onMounted, InjectionToken, viewfly, createDynamicRef, getCurrentInstance, watch, ReflectiveInjector } from '@viewfly/core';
4
- import { Subject, Selection, fromEvent, Subscription, Attribute, Keyboard, Commander, Controller, useContext, onBreak, onContentInsert, ContentType, Slot, Component, Registry, createVNode, BehaviorSubject, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, Query, QueryStateType, onFocusIn, onFocusOut, onDestroy, onGetRanges, Formatter, onParentSlotUpdated, Textbus, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, merge, debounceTime, throttleTime, delay, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
5
- import { VIEW_CONTAINER, DomAdapter, Input, SelectionBridge, VIEW_DOCUMENT, BrowserModule, Parser } from '@textbus/platform-browser';
4
+ import { Subject, Selection, fromEvent, Subscription, Attribute, Keyboard, Commander, Controller, useContext, onBreak, onContentInsert, ContentType, Slot, Component, Registry, Query, QueryStateType, createVNode, BehaviorSubject, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, onFocusIn, onFocusOut, onDestroy, onGetRanges, Formatter, onParentSlotUpdated, Textbus, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, merge, debounceTime, throttleTime, delay, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
5
+ import { VIEW_CONTAINER, isMac, DomAdapter, Input, SelectionBridge, VIEW_DOCUMENT, BrowserModule, Parser } from '@textbus/platform-browser';
6
6
  import { createPortal, DomRenderer, createApp, HTMLRenderer, OutputTranslator } from '@viewfly/platform-browser';
7
7
  import { useProduce } from '@viewfly/hooks';
8
8
  import highlightjs from 'highlight.js';
@@ -10,7 +10,7 @@ import { any2Hsl, hsl2Rgb } from '@tanbo/color';
10
10
  import { ViewflyAdapter, ViewflyVDomAdapter } from '@textbus/adapter-viewfly';
11
11
  import { CollaborateModule } from '@textbus/collaborate';
12
12
 
13
- var scopedId$l = "vf-3d0183";
13
+ var scopedId$m = "vf-3d0183";
14
14
 
15
15
  /******************************************************************************
16
16
  Copyright (c) Microsoft Corporation.
@@ -131,7 +131,7 @@ function Button(props) {
131
131
  subscription.unsubscribe();
132
132
  });
133
133
  }
134
- return withScopedCSS(scopedId$l, () => {
134
+ return withScopedCSS(scopedId$m, () => {
135
135
  return (jsxs("button", Object.assign({ type: "button" }, props, { class: [
136
136
  'btn',
137
137
  {
@@ -143,10 +143,10 @@ function Button(props) {
143
143
  });
144
144
  }
145
145
 
146
- var scopedId$k = "vf-ac7e8d";
146
+ var scopedId$l = "vf-ac7e8d";
147
147
 
148
148
  function ComponentToolbar(props) {
149
- return withScopedCSS(scopedId$k, () => {
149
+ return withScopedCSS(scopedId$l, () => {
150
150
  return (jsx("div", { class: "component-toolbar", style: props.style, children: jsx("div", { class: [
151
151
  'toolbar',
152
152
  {
@@ -156,15 +156,15 @@ function ComponentToolbar(props) {
156
156
  });
157
157
  }
158
158
 
159
- var scopedId$j = "vf-ede279";
159
+ var scopedId$k = "vf-ede279";
160
160
 
161
161
  function Divider() {
162
- return withScopedCSS(scopedId$j, () => {
162
+ return withScopedCSS(scopedId$k, () => {
163
163
  return jsx("div", { class: "divider" });
164
164
  });
165
165
  }
166
166
 
167
- var scopedId$i = "vf-4c1803";
167
+ var scopedId$j = "vf-4c1803";
168
168
 
169
169
  function DragResize(props) {
170
170
  const isShow = createSignal(false);
@@ -272,16 +272,16 @@ function DragResize(props) {
272
272
  unUp.unsubscribe();
273
273
  });
274
274
  }
275
- return withScopedCSS(scopedId$i, () => {
275
+ return withScopedCSS(scopedId$j, () => {
276
276
  return (jsxs("div", { class: "drag-resize", onClick: selectComponent, children: [jsx("div", { class: "container", ref: ref, children: props.children }), jsxs("div", { class: ['resize-tool', {
277
277
  active: isShow()
278
278
  }], children: [jsxs("div", { class: "mask", ref: mask, children: [component.state.width, "*", component.state.height] }), 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" })] })] })] }));
279
279
  });
280
280
  }
281
281
 
282
- var scopedId$h = "vf-a99c5e";
282
+ var scopedId$i = "vf-a99c5e";
283
283
 
284
- var scopedId$g = "vf-ab6f55";
284
+ var scopedId$h = "vf-ab6f55";
285
285
 
286
286
  const DropdownMenuPortal = withAnnotation({
287
287
  providers: [
@@ -373,7 +373,7 @@ const DropdownMenuPortal = withAnnotation({
373
373
  dropdownContextService.canHide = true;
374
374
  dropdownContextService.hide();
375
375
  }
376
- return createPortal(withScopedCSS(scopedId$g, () => {
376
+ return createPortal(withScopedCSS(scopedId$h, () => {
377
377
  return (jsx("div", { onMouseenter: onEnter, onMouseleave: onLeave, ref: menuRef, style: {
378
378
  width: props.width
379
379
  }, class: "dropdown-menu", children: jsx("div", { class: "dropdown-menu-content", children: props.children }) }));
@@ -439,7 +439,7 @@ const Dropdown = withAnnotation({
439
439
  dropdownContextService.hide(false);
440
440
  }
441
441
  },
442
- $render: withScopedCSS(scopedId$h, () => {
442
+ $render: withScopedCSS(scopedId$i, () => {
443
443
  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", children: props.children }), jsx("div", { class: "dropdown-btn-arrow" })] }), isShow() && jsx(DropdownMenuPortal, { noTrigger: props.trigger === 'none', width: props.width, abreast: props.abreast, triggerRef: triggerRef, children: Array.isArray(props.menu) ?
444
444
  props.menu.map(menu => {
445
445
  return (jsx("div", { class: "dropdown-menu-item", onClick: () => {
@@ -455,6 +455,42 @@ const Dropdown = withAnnotation({
455
455
  };
456
456
  });
457
457
 
458
+ var scopedId$g = "vf-9dad68";
459
+
460
+ function Keymap(props) {
461
+ const arr = [];
462
+ const keymap = props.keymap;
463
+ if (keymap.ctrlKey) {
464
+ arr.push(isMac() ? jsx("span", { class: "xnote-icon-command" }) : 'Ctrl');
465
+ }
466
+ if (keymap.shiftKey) {
467
+ if (arr.length) {
468
+ arr.push('+');
469
+ }
470
+ arr.push(isMac() ? jsx("span", { class: "xnote-icon-shift" }) : 'Shift');
471
+ }
472
+ if (keymap.altKey) {
473
+ if (arr.length) {
474
+ arr.push('+');
475
+ }
476
+ arr.push(isMac() ? jsx("span", { class: "xnote-icon-opt" }) : 'Alt');
477
+ }
478
+ if (keymap.key) {
479
+ if (arr.length) {
480
+ arr.push('+');
481
+ }
482
+ if (Array.isArray(keymap.key)) {
483
+ arr.push(jsx("span", { children: keymap.key.join('/') }));
484
+ }
485
+ else {
486
+ arr.push(jsx("span", { children: keymap.key }));
487
+ }
488
+ }
489
+ return withScopedCSS(scopedId$g, () => {
490
+ return (jsx("span", { class: "keymap", children: arr }));
491
+ });
492
+ }
493
+
458
494
  var scopedId$f = "vf-acaa5f";
459
495
 
460
496
  function MenuHeading(props) {
@@ -463,7 +499,7 @@ function MenuHeading(props) {
463
499
  });
464
500
  }
465
501
 
466
- var scopedId$e = "vf-678daa";
502
+ var scopedId$e = "vf-c3b9dc";
467
503
 
468
504
  function MenuItem(props) {
469
505
  const dropdownContextService = inject(DropdownContextService, null);
@@ -484,7 +520,7 @@ function MenuItem(props) {
484
520
  (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, props.value);
485
521
  }
486
522
  return withScopedCSS(scopedId$e, () => {
487
- return (jsxs("div", { class: ['menu-item', { disabled: props.disabled, active: props.arrow && isActive() }], onClick: click, children: [jsxs("div", { children: [props.icon && jsx("span", { class: "menu-icon", children: props.icon }), props.children] }), props.arrow ?
523
+ 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 ?
488
524
  jsx("div", { class: "arrow", children: jsx("span", { class: "xnote-icon-arrow-right" }) }) :
489
525
  jsx("div", { class: [
490
526
  'menu-check',
@@ -603,10 +639,14 @@ function registerHeadingShortcut(textbus) {
603
639
  const selection = textbus.get(Selection);
604
640
  keyboard.addShortcut({
605
641
  keymap: {
606
- key: '123456'.split(''),
642
+ key: '0123456'.split(''),
607
643
  ctrlKey: true
608
644
  },
609
645
  action(key) {
646
+ if (key === '0') {
647
+ commander.unApplyAttribute(headingAttr);
648
+ return;
649
+ }
610
650
  commander.applyAttribute(headingAttr, 'h' + key);
611
651
  }
612
652
  });
@@ -697,6 +737,55 @@ BlockquoteComponent.zenCoding = {
697
737
  };
698
738
  }
699
739
  };
740
+ function toBlockquote(textbus) {
741
+ const query = textbus.get(Query);
742
+ const commander = textbus.get(Commander);
743
+ const selection = textbus.get(Selection);
744
+ const state = query.queryComponent(BlockquoteComponent);
745
+ if (state.state === QueryStateType.Enabled) {
746
+ const current = state.value;
747
+ const parent = current.parent;
748
+ const index = parent.indexOf(current);
749
+ parent.retain(index);
750
+ commander.removeComponent(current);
751
+ current.__slots__.get(0).sliceContent().forEach(i => {
752
+ parent.insert(i);
753
+ });
754
+ }
755
+ else {
756
+ const block = new BlockquoteComponent(textbus);
757
+ const slot = block.state.slot;
758
+ if (selection.startSlot === selection.endSlot) {
759
+ const parentComponent = selection.startSlot.parent;
760
+ const parentSlot = parentComponent.parent;
761
+ const position = parentSlot.indexOf(parentComponent);
762
+ slot.insert(parentComponent);
763
+ parentSlot.retain(position);
764
+ parentSlot.insert(block);
765
+ }
766
+ else {
767
+ const commonAncestorSlot = selection.commonAncestorSlot;
768
+ const scope = selection.getCommonAncestorSlotScope();
769
+ commonAncestorSlot.cut(scope.startOffset, scope.endOffset).sliceContent().forEach(i => {
770
+ slot.insert(i);
771
+ });
772
+ commonAncestorSlot.retain(scope.startOffset);
773
+ commonAncestorSlot.insert(block);
774
+ }
775
+ }
776
+ }
777
+ function registerBlockquoteShortcut(textbus) {
778
+ const keyboard = textbus.get(Keyboard);
779
+ keyboard.addShortcut({
780
+ keymap: {
781
+ ctrlKey: true,
782
+ key: '\''
783
+ },
784
+ action() {
785
+ toBlockquote(textbus);
786
+ }
787
+ });
788
+ }
700
789
  function BlockquoteView(props) {
701
790
  const adapter = inject(DomAdapter);
702
791
  const readonly = useReadonly();
@@ -709,8 +798,8 @@ function BlockquoteView(props) {
709
798
  };
710
799
  }
711
800
  const blockquoteComponentLoader = {
712
- match(element) {
713
- return element.tagName === 'BLOCKQUOTE';
801
+ match(element, returnableContentTypes) {
802
+ return returnableContentTypes.includes(ContentType.BlockComponent) && element.tagName === 'BLOCKQUOTE';
714
803
  },
715
804
  read(element, textbus, slotParser) {
716
805
  const delta = slotParser(new Slot([
@@ -863,8 +952,8 @@ function ParagraphView(props) {
863
952
  };
864
953
  }
865
954
  const paragraphComponentLoader = {
866
- match(element) {
867
- return element.dataset.compoment === ParagraphComponent.componentName || /P|H[1-6]/.test(element.tagName);
955
+ match(element, returnableContentTypes) {
956
+ return returnableContentTypes.includes(ContentType.BlockComponent) && element.dataset.compoment === ParagraphComponent.componentName || /P|H[1-6]/.test(element.tagName);
868
957
  },
869
958
  read(element, textbus, slotParser) {
870
959
  const content = /P|H[1-6]/.test(element.tagName) ? element : element.children[0];
@@ -943,6 +1032,15 @@ const languageList = [{
943
1032
  }, {
944
1033
  label: 'Go',
945
1034
  value: 'Go'
1035
+ }, {
1036
+ label: 'Kotlin',
1037
+ value: 'kotlin'
1038
+ }, {
1039
+ label: 'Python',
1040
+ value: 'python'
1041
+ }, {
1042
+ label: 'PHP',
1043
+ value: 'php'
946
1044
  }, {
947
1045
  label: 'JSON',
948
1046
  value: 'JSON',
@@ -985,11 +1083,16 @@ const languageList = [{
985
1083
  }, {
986
1084
  label: 'Dart',
987
1085
  value: 'dart',
1086
+ }, {
1087
+ label: 'Rust',
1088
+ value: 'rust',
988
1089
  }, {
989
1090
  label: '',
990
1091
  value: '',
991
1092
  }];
992
1093
  const sourceCodeThemes = [
1094
+ 'xnote-dark',
1095
+ 'xnote-dark-blue',
993
1096
  'github',
994
1097
  'atom-one-dark',
995
1098
  'foundation',
@@ -1287,7 +1390,7 @@ function SourceCodeView(props) {
1287
1390
  }
1288
1391
  const input = inject(Input);
1289
1392
  function updateCaret() {
1290
- input.caret.refresh(false);
1393
+ input.caret.refresh();
1291
1394
  }
1292
1395
  const readonly = useReadonly();
1293
1396
  const output = useOutput();
@@ -1407,9 +1510,10 @@ function SourceCodeView(props) {
1407
1510
  };
1408
1511
  }
1409
1512
  const sourceCodeComponentLoader = {
1410
- match(element) {
1411
- return (element.tagName === 'DIV' && element.dataset.component === SourceCodeComponent.componentName) ||
1412
- element.tagName === 'PRE';
1513
+ match(element, returnableContentTypes) {
1514
+ return returnableContentTypes.includes(ContentType.BlockComponent) &&
1515
+ ((element.tagName === 'DIV' && element.dataset.component === SourceCodeComponent.componentName) ||
1516
+ element.tagName === 'PRE');
1413
1517
  },
1414
1518
  read(el, textbus) {
1415
1519
  let slots = [];
@@ -1607,25 +1711,25 @@ function AttrTool(props) {
1607
1711
  const states = checkStates();
1608
1712
  return (jsx(Dropdown, { style: props.style, abreast: props.abreast, onCheck: updateAttr, trigger: 'hover', menu: [
1609
1713
  {
1610
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-left" }), checked: states.textAlign === 'left', children: "\u5DE6\u5BF9\u9F50" }),
1714
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-left" }), desc: jsx(Keymap, { keymap: { key: 'L', ctrlKey: true } }), checked: states.textAlign === 'left', children: "\u5DE6\u5BF9\u9F50" }),
1611
1715
  value: 't-l'
1612
1716
  }, {
1613
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-right" }), checked: states.textAlign === 'right', children: "\u53F3\u5BF9\u9F50" }),
1717
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-right" }), desc: jsx(Keymap, { keymap: { key: 'R', ctrlKey: true } }), checked: states.textAlign === 'right', children: "\u53F3\u5BF9\u9F50" }),
1614
1718
  value: 't-r'
1615
1719
  }, {
1616
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-center" }), checked: states.textAlign === 'center', children: "\u5C45\u4E2D\u5BF9\u9F50" }),
1720
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-center" }), desc: jsx(Keymap, { keymap: { key: 'E', ctrlKey: true } }), checked: states.textAlign === 'center', children: "\u5C45\u4E2D\u5BF9\u9F50" }),
1617
1721
  value: 't-c'
1618
1722
  }, {
1619
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-justify" }), checked: states.textAlign === 'justify', children: "\u5206\u6563\u5BF9\u9F50" }),
1723
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-paragraph-justify" }), desc: jsx(Keymap, { keymap: { key: 'J', ctrlKey: true } }), checked: states.textAlign === 'justify', children: "\u5206\u6563\u5BF9\u9F50" }),
1620
1724
  value: 't-j'
1621
1725
  }, {
1622
1726
  label: jsx(Divider, {}),
1623
1727
  value: ''
1624
1728
  }, {
1625
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-indent-increase" }), children: "\u589E\u52A0\u7F29\u8FDB" }),
1729
+ label: jsx(MenuItem, { desc: jsx(Keymap, { keymap: { key: '<', ctrlKey: true } }), icon: jsx("span", { class: "xnote-icon-indent-increase" }), children: "\u589E\u52A0\u7F29\u8FDB" }),
1626
1730
  value: 'i+'
1627
1731
  }, {
1628
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-indent-decrease" }), children: "\u51CF\u5C11\u7F29\u8FDB" }),
1732
+ label: jsx(MenuItem, { desc: jsx(Keymap, { keymap: { key: '>', ctrlKey: true } }), icon: jsx("span", { class: "xnote-icon-indent-decrease" }), children: "\u51CF\u5C11\u7F29\u8FDB" }),
1629
1733
  value: 'i-'
1630
1734
  }
1631
1735
  ], children: props.children || jsx(Button, { arrow: true, highlight: false, children: jsx("span", { class: `xnote-icon-paragraph-${states.textAlign || 'left'} icon` }) }) }));
@@ -1654,17 +1758,18 @@ class TableComponent extends Component {
1654
1758
  });
1655
1759
  }
1656
1760
  constructor(textbus, state = {
1657
- layoutWidth: Array.from({ length: 3 }).fill(100),
1761
+ layoutWidth: Array.from({ length: 5 }).fill(100),
1658
1762
  rows: Array.from({ length: 3 }).map(() => {
1659
1763
  return {
1660
1764
  height: defaultRowHeight,
1661
- cells: Array.from({ length: 3 }).map(() => {
1765
+ cells: Array.from({ length: 5 }).map(() => {
1766
+ const p = new ParagraphComponent(textbus);
1767
+ const slot = new Slot([ContentType.BlockComponent]);
1768
+ slot.insert(p);
1662
1769
  return {
1663
1770
  rowspan: 1,
1664
1771
  colspan: 1,
1665
- slot: new Slot([
1666
- ContentType.BlockComponent
1667
- ])
1772
+ slot
1668
1773
  };
1669
1774
  })
1670
1775
  };
@@ -1765,31 +1870,31 @@ class TableComponent extends Component {
1765
1870
  }
1766
1871
  });
1767
1872
  }
1768
- afterContentCheck() {
1769
- const selection = this.selection;
1770
- const rows = this.state.rows;
1771
- rows.forEach(row => {
1772
- row.cells.forEach(cell => {
1773
- const slot = cell.slot;
1774
- if (slot.isEmpty) {
1775
- const childSlot = new Slot([
1776
- ContentType.Text,
1777
- ContentType.InlineComponent
1778
- ]);
1779
- const p = new ParagraphComponent(this.textbus, {
1780
- slot: childSlot
1781
- });
1782
- slot.insert(p);
1783
- if (slot === selection.anchorSlot) {
1784
- selection.setAnchor(childSlot, 0);
1785
- }
1786
- if (slot === selection.focusSlot) {
1787
- selection.setFocus(childSlot, 0);
1788
- }
1789
- }
1790
- });
1791
- });
1792
- }
1873
+ // afterContentCheck() {
1874
+ // const selection = this.selection
1875
+ // const rows = this.state.rows
1876
+ // rows.forEach(row => {
1877
+ // row.cells.forEach(cell => {
1878
+ // const slot = cell.slot
1879
+ // if (slot.isEmpty) {
1880
+ // const childSlot = new Slot([
1881
+ // ContentType.Text,
1882
+ // ContentType.InlineComponent
1883
+ // ])
1884
+ // const p = new ParagraphComponent(this.textbus, {
1885
+ // slot: childSlot
1886
+ // })
1887
+ // slot.insert(p)
1888
+ // if (slot === selection.anchorSlot) {
1889
+ // selection.setAnchor(childSlot, 0)
1890
+ // }
1891
+ // if (slot === selection.focusSlot) {
1892
+ // selection.setFocus(childSlot, 0)
1893
+ // }
1894
+ // }
1895
+ // })
1896
+ // })
1897
+ // }
1793
1898
  deleteColumn(index) {
1794
1899
  this.state.layoutWidth.splice(index, 1);
1795
1900
  this.state.rows.forEach(row => {
@@ -2044,6 +2149,40 @@ const todolistComponentLoader = {
2044
2149
  }
2045
2150
  };
2046
2151
 
2152
+ function toList(textbus, type) {
2153
+ const commander = textbus.get(Commander);
2154
+ commander.transform({
2155
+ targetType: ListComponent.type,
2156
+ slotFactory() {
2157
+ return new Slot([
2158
+ ContentType.InlineComponent,
2159
+ ContentType.Text
2160
+ ]);
2161
+ },
2162
+ stateFactory(slots) {
2163
+ return slots.map((slot, index) => {
2164
+ return new ListComponent(textbus, {
2165
+ type,
2166
+ reorder: index === 0,
2167
+ slot
2168
+ });
2169
+ });
2170
+ }
2171
+ });
2172
+ }
2173
+ function registerListShortcut(textbus) {
2174
+ const keyboard = textbus.get(Keyboard);
2175
+ keyboard.addShortcut({
2176
+ keymap: {
2177
+ key: ['o', 'u'],
2178
+ ctrlKey: true,
2179
+ shiftKey: true
2180
+ },
2181
+ action(key) {
2182
+ toList(textbus, key === 'o' ? 'OrderedList' : 'UnorderedList');
2183
+ }
2184
+ });
2185
+ }
2047
2186
  class ListComponent extends Component {
2048
2187
  static fromJSON(textbus, json) {
2049
2188
  return new ListComponent(textbus, {
@@ -2130,7 +2269,7 @@ class ListComponent extends Component {
2130
2269
  key: 'Tab'
2131
2270
  },
2132
2271
  action: () => {
2133
- updateAfterList(this);
2272
+ Promise.resolve().then(() => updateAfterList(this));
2134
2273
  return false;
2135
2274
  }
2136
2275
  });
@@ -2274,8 +2413,8 @@ function ListComponentView(props) {
2274
2413
  };
2275
2414
  }
2276
2415
  const listComponentLoader = {
2277
- match(element) {
2278
- return element.tagName === 'UL' || element.tagName === 'OL';
2416
+ match(element, returnableContentTypes) {
2417
+ return returnableContentTypes.includes(ContentType.BlockComponent) && (element.tagName === 'UL' || element.tagName === 'OL');
2279
2418
  },
2280
2419
  read(element, textbus, slotParser) {
2281
2420
  const type = element.tagName === 'OL' ? 'OrderedList' : 'UnorderedList';
@@ -2448,62 +2587,10 @@ function useBlockTransform() {
2448
2587
  break;
2449
2588
  case 'ol':
2450
2589
  case 'ul':
2451
- {
2452
- commander.transform({
2453
- targetType: ListComponent.type,
2454
- slotFactory() {
2455
- return new Slot([
2456
- ContentType.InlineComponent,
2457
- ContentType.Text
2458
- ]);
2459
- },
2460
- stateFactory(slots) {
2461
- return slots.map((slot, index) => {
2462
- return new ListComponent(textbus, {
2463
- type: value === 'ol' ? 'OrderedList' : 'UnorderedList',
2464
- reorder: index === 0,
2465
- slot
2466
- });
2467
- });
2468
- }
2469
- });
2470
- }
2590
+ toList(textbus, value === 'ol' ? 'OrderedList' : 'UnorderedList');
2471
2591
  break;
2472
2592
  case 'blockquote':
2473
- {
2474
- const state = query.queryComponent(BlockquoteComponent);
2475
- if (state.state === QueryStateType.Enabled) {
2476
- const current = state.value;
2477
- const parent = current.parent;
2478
- const index = parent.indexOf(current);
2479
- parent.retain(index);
2480
- commander.removeComponent(current);
2481
- current.__slots__.get(0).sliceContent().forEach(i => {
2482
- parent.insert(i);
2483
- });
2484
- }
2485
- else {
2486
- const block = new BlockquoteComponent(textbus);
2487
- const slot = block.state.slot;
2488
- if (selection.startSlot === selection.endSlot) {
2489
- const parentComponent = selection.startSlot.parent;
2490
- const parentSlot = parentComponent.parent;
2491
- const position = parentSlot.indexOf(parentComponent);
2492
- slot.insert(parentComponent);
2493
- parentSlot.retain(position);
2494
- parentSlot.insert(block);
2495
- }
2496
- else {
2497
- const commonAncestorSlot = selection.commonAncestorSlot;
2498
- const scope = selection.getCommonAncestorSlotScope();
2499
- commonAncestorSlot.cut(scope.startOffset, scope.endOffset).sliceContent().forEach(i => {
2500
- slot.insert(i);
2501
- });
2502
- commonAncestorSlot.retain(scope.startOffset);
2503
- commonAncestorSlot.insert(block);
2504
- }
2505
- }
2506
- }
2593
+ toBlockquote(textbus);
2507
2594
  break;
2508
2595
  case 'sourceCode':
2509
2596
  {
@@ -2620,25 +2707,46 @@ function BlockTool() {
2620
2707
  }
2621
2708
  return (jsx(Dropdown, { onCheck: transform, trigger: 'hover', menu: [
2622
2709
  {
2623
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-pilcrow" }), checked: states.paragraph, children: "\u6B63\u6587" }),
2710
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-pilcrow" }), desc: jsx(Keymap, { keymap: {
2711
+ ctrlKey: true,
2712
+ key: '0'
2713
+ } }), checked: states.paragraph, children: "\u6B63\u6587" }),
2624
2714
  value: 'paragraph'
2625
2715
  }, {
2626
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h1" }), checked: states.h1, children: "\u4E00\u7EA7\u6807\u9898" }),
2716
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h1" }), desc: jsx(Keymap, { keymap: {
2717
+ ctrlKey: true,
2718
+ key: '1'
2719
+ } }), checked: states.h1, children: "\u4E00\u7EA7\u6807\u9898" }),
2627
2720
  value: 'h1'
2628
2721
  }, {
2629
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h2" }), checked: states.h2, children: "\u4E8C\u7EA7\u6807\u9898" }),
2722
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h2" }), desc: jsx(Keymap, { keymap: {
2723
+ ctrlKey: true,
2724
+ key: '2'
2725
+ } }), checked: states.h2, children: "\u4E8C\u7EA7\u6807\u9898" }),
2630
2726
  value: 'h2'
2631
2727
  }, {
2632
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h3" }), checked: states.h3, children: "\u4E09\u7EA7\u6807\u9898" }),
2728
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h3" }), desc: jsx(Keymap, { keymap: {
2729
+ ctrlKey: true,
2730
+ key: '3'
2731
+ } }), checked: states.h3, children: "\u4E09\u7EA7\u6807\u9898" }),
2633
2732
  value: 'h3'
2634
2733
  }, {
2635
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h4" }), checked: states.h4, children: "\u56DB\u7EA7\u6807\u9898" }),
2734
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h4" }), desc: jsx(Keymap, { keymap: {
2735
+ ctrlKey: true,
2736
+ key: '4'
2737
+ } }), checked: states.h4, children: "\u56DB\u7EA7\u6807\u9898" }),
2636
2738
  value: 'h4'
2637
2739
  }, {
2638
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h5" }), checked: states.h5, children: "\u4E94\u7EA7\u6807\u9898" }),
2740
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h5" }), desc: jsx(Keymap, { keymap: {
2741
+ ctrlKey: true,
2742
+ key: '5'
2743
+ } }), checked: states.h5, children: "\u4E94\u7EA7\u6807\u9898" }),
2639
2744
  value: 'h5'
2640
2745
  }, {
2641
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h6" }), checked: states.h6, children: "\u516D\u7EA7\u6807\u9898" }),
2746
+ label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-heading-h6" }), desc: jsx(Keymap, { keymap: {
2747
+ ctrlKey: true,
2748
+ key: '6'
2749
+ } }), checked: states.h6, children: "\u516D\u7EA7\u6807\u9898" }),
2642
2750
  value: 'h6'
2643
2751
  }, {
2644
2752
  label: jsx(Divider, {}),
@@ -2647,13 +2755,13 @@ function BlockTool() {
2647
2755
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-checkbox-checked" }), checked: states.todolist, children: "\u5F85\u529E\u4E8B\u9879" }),
2648
2756
  value: 'todolist'
2649
2757
  }, {
2650
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-list-numbered" }), checked: states.orderedList, children: "\u6709\u5E8F\u5217\u8868" }),
2758
+ label: jsx(MenuItem, { desc: jsx(Keymap, { keymap: { key: 'O', shiftKey: true, ctrlKey: true } }), icon: jsx("span", { class: "xnote-icon-list-numbered" }), checked: states.orderedList, children: "\u6709\u5E8F\u5217\u8868" }),
2651
2759
  value: 'ol'
2652
2760
  }, {
2653
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-list" }), checked: states.unorderedList, children: "\u65E0\u5E8F\u5217\u8868" }),
2761
+ label: jsx(MenuItem, { desc: jsx(Keymap, { keymap: { key: 'U', shiftKey: true, ctrlKey: true } }), icon: jsx("span", { class: "xnote-icon-list" }), checked: states.unorderedList, children: "\u65E0\u5E8F\u5217\u8868" }),
2654
2762
  value: 'ul'
2655
2763
  }, {
2656
- label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-quotes-right" }), checked: states.blockquote, children: "\u5F15\u7528" }),
2764
+ label: jsx(MenuItem, { desc: jsx(Keymap, { keymap: { key: '\'', ctrlKey: true } }), icon: jsx("span", { class: "xnote-icon-quotes-right" }), checked: states.blockquote, children: "\u5F15\u7528" }),
2657
2765
  value: 'blockquote'
2658
2766
  }, {
2659
2767
  label: jsx(MenuItem, { icon: jsx("span", { class: "xnote-icon-source-code" }), checked: states.sourceCode, children: "\u4EE3\u7801\u5757" }),
@@ -3088,7 +3196,7 @@ function ColorTool(props) {
3088
3196
  ];
3089
3197
  return withScopedCSS(scopedId$a, () => {
3090
3198
  const vm = viewModel();
3091
- return (jsx(Dropdown, { style: props.style, abreast: props.abreast, trigger: 'hover', menu: jsxs("div", { children: [jsx("div", { class: "color-type", children: "\u6587\u5B57\u989C\u8272" }), jsxs("div", { class: "text-colors", children: [jsx("div", { class: {
3199
+ return (jsx(Dropdown, { style: props.style, width: '180px', abreast: props.abreast, trigger: 'hover', menu: jsxs("div", { children: [jsx("div", { class: "color-type", children: "\u6587\u5B57\u989C\u8272" }), jsxs("div", { class: "text-colors", children: [jsx("div", { class: {
3092
3200
  active: textColor() === ''
3093
3201
  }, onClick: () => {
3094
3202
  var _a;
@@ -3558,7 +3666,9 @@ function InsertTool(props) {
3558
3666
  {
3559
3667
  const table = new TableComponent(textbus);
3560
3668
  insertComponent(table);
3561
- selection.setPosition(table.state.rows[0].cells[0].slot, 0);
3669
+ textbus.nextTick(() => {
3670
+ selection.selectFirstPosition(table, true, true);
3671
+ });
3562
3672
  }
3563
3673
  break;
3564
3674
  case 'todolist':
@@ -4587,7 +4697,7 @@ function Scroll(props) {
4587
4697
  const el = scrollRef.current;
4588
4698
  function update() {
4589
4699
  if (props.isFocus()) {
4590
- input.caret.refresh(false);
4700
+ input.caret.refresh();
4591
4701
  }
4592
4702
  updateShowShadow(draft => {
4593
4703
  draft.leftEnd = el.scrollLeft === 0;
@@ -4879,9 +4989,6 @@ const TableComponentView = withAnnotation({
4879
4989
  }
4880
4990
  rowMapping.set(row, Math.random());
4881
4991
  });
4882
- Promise.resolve().then(() => {
4883
- props.component.afterContentCheck();
4884
- });
4885
4992
  if (readonly() || output()) {
4886
4993
  return (jsx("div", { class: "xnote-table", "data-component": props.component.name, "data-layout-width": state.layoutWidth, ref: props.rootRef, children: jsx("div", { class: "xnote-table-container", children: jsxs("table", { class: [
4887
4994
  'xnote-table-content',
@@ -4946,6 +5053,8 @@ const tableComponentLoader = {
4946
5053
  });
4947
5054
  const delta = slotParser(new Slot([
4948
5055
  ContentType.BlockComponent,
5056
+ ContentType.InlineComponent,
5057
+ ContentType.Text
4949
5058
  ]), cell).toDelta();
4950
5059
  const results = deltaToBlock(delta, textbus);
4951
5060
  results.forEach(i => {
@@ -4971,6 +5080,8 @@ const tableComponentLoader = {
4971
5080
  });
4972
5081
  const delta = slotParser(new Slot([
4973
5082
  ContentType.BlockComponent,
5083
+ ContentType.InlineComponent,
5084
+ ContentType.Text
4974
5085
  ]), cell).toDelta();
4975
5086
  const results = deltaToBlock(delta, textbus);
4976
5087
  results.forEach(i => {
@@ -5195,6 +5306,8 @@ class Editor extends Textbus {
5195
5306
  registerTextAlignShortcut(textbus);
5196
5307
  registerTextIndentShortcut(textbus);
5197
5308
  registerAtShortcut(textbus);
5309
+ registerListShortcut(textbus);
5310
+ registerBlockquoteShortcut(textbus);
5198
5311
  } }, editorConfig));
5199
5312
  this.editorConfig = editorConfig;
5200
5313
  this.translator = new OutputTranslator();
@@ -5236,4 +5349,4 @@ class Editor extends Textbus {
5236
5349
  }
5237
5350
  }
5238
5351
 
5239
- export { AtComponent, AtComponentView, AttrTool, BlockTool, BlockquoteComponent, BlockquoteView, BoldTool, Button, CodeTool, ColorTool, ComponentToolbar, Divider, DragResize, Dropdown, DropdownContextService, DropdownMenuPortal, DropdownService, Editor, EditorService, FontFamilyTool, FontSizeTool, HighlightBoxComponent, HighlightBoxView, ImageComponent, ImageView, InsertTool, ItalicTool, LeftToolbar, LeftToolbarPlugin, LinkTool, ListComponent, ListComponentView, Matcher, MenuHeading, MenuItem, Organization, OutputInjectionToken, ParagraphComponent, ParagraphView, Popup, RefreshService, RootComponent, RootView, SourceCodeComponent, SourceCodeView, StrikeThroughTool, TableComponent, TableComponentView, TodolistComponent, TodolistView, Toolbar, ToolbarItem, ToolbarPlugin, UnderlineTool, VideoComponent, VideoView, atComponentLoader, autoComplete, backgroundColorFormatLoader, backgroundColorFormatter, blockquoteComponentLoader, boldFormatLoader, boldFormatter, codeFormatLoader, codeFormatter, colorFormatLoader, colorFormatter, deltaToBlock, fontFamilyFormatLoader, fontFamilyFormatter, fontSizeFormatLoader, fontSizeFormatter, headingAttr, headingAttrLoader, highlightBoxComponentLoader, imageComponentLoader, isSupportFont, italicFormatLoader, italicFormatter, languageList, linkFormatLoader, linkFormatter, listComponentLoader, paragraphComponentLoader, registerAtShortcut, registerBoldShortcut, registerCodeShortcut, registerHeadingShortcut, registerItalicShortcut, registerStrikeThroughShortcut, registerTextAlignShortcut, registerTextIndentShortcut, registerUnderlineShortcut, rootComponentLoader, sourceCodeComponentLoader, sourceCodeThemes, strikeThroughFormatLoader, strikeThroughFormatter, tableComponentLoader, textAlignAttr, textAlignAttrLoader, textIndentAttr, textIndentAttrLoader, todolistComponentLoader, toggleBold, toggleCode, toggleItalic, toggleStrikeThrough, toggleUnderline, underlineFormatLoader, underlineFormatter, useActiveBlock, useBlockContent, useBlockTransform, useOutput, useReadonly, videoComponentLoader };
5352
+ export { AtComponent, AtComponentView, AttrTool, BlockTool, BlockquoteComponent, BlockquoteView, BoldTool, Button, CodeTool, ColorTool, ComponentToolbar, Divider, DragResize, Dropdown, DropdownContextService, DropdownMenuPortal, DropdownService, Editor, EditorService, FontFamilyTool, FontSizeTool, HighlightBoxComponent, HighlightBoxView, ImageComponent, ImageView, InsertTool, ItalicTool, Keymap, LeftToolbar, LeftToolbarPlugin, LinkTool, ListComponent, ListComponentView, Matcher, MenuHeading, MenuItem, Organization, OutputInjectionToken, ParagraphComponent, ParagraphView, Popup, RefreshService, RootComponent, RootView, SourceCodeComponent, SourceCodeView, StrikeThroughTool, TableComponent, TableComponentView, TodolistComponent, TodolistView, Toolbar, ToolbarItem, ToolbarPlugin, UnderlineTool, VideoComponent, VideoView, atComponentLoader, autoComplete, backgroundColorFormatLoader, backgroundColorFormatter, blockquoteComponentLoader, boldFormatLoader, boldFormatter, codeFormatLoader, codeFormatter, colorFormatLoader, colorFormatter, deltaToBlock, fontFamilyFormatLoader, fontFamilyFormatter, fontSizeFormatLoader, fontSizeFormatter, headingAttr, headingAttrLoader, highlightBoxComponentLoader, imageComponentLoader, isSupportFont, italicFormatLoader, italicFormatter, languageList, linkFormatLoader, linkFormatter, listComponentLoader, paragraphComponentLoader, registerAtShortcut, registerBlockquoteShortcut, registerBoldShortcut, registerCodeShortcut, registerHeadingShortcut, registerItalicShortcut, registerListShortcut, registerStrikeThroughShortcut, registerTextAlignShortcut, registerTextIndentShortcut, registerUnderlineShortcut, rootComponentLoader, sourceCodeComponentLoader, sourceCodeThemes, strikeThroughFormatLoader, strikeThroughFormatter, tableComponentLoader, textAlignAttr, textAlignAttrLoader, textIndentAttr, textIndentAttrLoader, toBlockquote, toList, todolistComponentLoader, toggleBold, toggleCode, toggleItalic, toggleStrikeThrough, toggleUnderline, underlineFormatLoader, underlineFormatter, useActiveBlock, useBlockContent, useBlockTransform, useOutput, useReadonly, videoComponentLoader };