@kerebron/extension-basic-editor 0.4.27 → 0.4.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/esm/ExtensionBaseKeymap.d.ts +7 -0
  2. package/esm/ExtensionBaseKeymap.d.ts.map +1 -0
  3. package/esm/ExtensionBaseKeymap.js +55 -0
  4. package/esm/ExtensionBasicCodeEditor.d.ts +11 -0
  5. package/esm/ExtensionBasicCodeEditor.d.ts.map +1 -0
  6. package/esm/ExtensionBasicCodeEditor.js +61 -0
  7. package/esm/ExtensionBasicEditor.d.ts +49 -0
  8. package/esm/ExtensionBasicEditor.d.ts.map +1 -0
  9. package/esm/ExtensionBasicEditor.js +94 -0
  10. package/esm/ExtensionDropcursor.d.ts +19 -0
  11. package/esm/ExtensionDropcursor.d.ts.map +1 -0
  12. package/esm/ExtensionDropcursor.js +186 -0
  13. package/esm/ExtensionGapcursor.d.ts +32 -0
  14. package/esm/ExtensionGapcursor.d.ts.map +1 -0
  15. package/esm/ExtensionGapcursor.js +249 -0
  16. package/esm/ExtensionHistory.d.ts +14 -0
  17. package/esm/ExtensionHistory.d.ts.map +1 -0
  18. package/esm/ExtensionHistory.js +34 -0
  19. package/esm/ExtensionHtml.d.ts +15 -0
  20. package/esm/ExtensionHtml.d.ts.map +1 -0
  21. package/esm/ExtensionHtml.js +99 -0
  22. package/esm/ExtensionMediaUpload.d.ts +24 -0
  23. package/esm/ExtensionMediaUpload.d.ts.map +1 -0
  24. package/esm/ExtensionMediaUpload.js +167 -0
  25. package/esm/ExtensionSelection.d.ts +11 -0
  26. package/esm/ExtensionSelection.d.ts.map +1 -0
  27. package/esm/ExtensionSelection.js +229 -0
  28. package/esm/ExtensionTextAlign.d.ts +11 -0
  29. package/esm/ExtensionTextAlign.d.ts.map +1 -0
  30. package/esm/ExtensionTextAlign.js +39 -0
  31. package/esm/MarkBookmark.d.ts +8 -0
  32. package/esm/MarkBookmark.d.ts.map +1 -0
  33. package/esm/MarkBookmark.js +16 -0
  34. package/esm/MarkChange.d.ts +8 -0
  35. package/esm/MarkChange.d.ts.map +1 -0
  36. package/esm/MarkChange.js +13 -0
  37. package/esm/MarkCode.d.ts +11 -0
  38. package/esm/MarkCode.d.ts.map +1 -0
  39. package/esm/MarkCode.js +23 -0
  40. package/esm/MarkHighlight.d.ts +8 -0
  41. package/esm/MarkHighlight.d.ts.map +1 -0
  42. package/esm/MarkHighlight.js +35 -0
  43. package/esm/MarkItalic.d.ts +11 -0
  44. package/esm/MarkItalic.d.ts.map +1 -0
  45. package/esm/MarkItalic.js +29 -0
  46. package/esm/MarkLink.d.ts +8 -0
  47. package/esm/MarkLink.d.ts.map +1 -0
  48. package/esm/MarkLink.js +29 -0
  49. package/esm/MarkStrike.d.ts +11 -0
  50. package/esm/MarkStrike.d.ts.map +1 -0
  51. package/esm/MarkStrike.js +26 -0
  52. package/esm/MarkStrong.d.ts +11 -0
  53. package/esm/MarkStrong.d.ts.map +1 -0
  54. package/esm/MarkStrong.js +38 -0
  55. package/esm/MarkSubscript.d.ts +11 -0
  56. package/esm/MarkSubscript.d.ts.map +1 -0
  57. package/esm/MarkSubscript.js +30 -0
  58. package/esm/MarkSuperscript.d.ts +11 -0
  59. package/esm/MarkSuperscript.d.ts.map +1 -0
  60. package/esm/MarkSuperscript.js +30 -0
  61. package/esm/MarkTextColor.d.ts +8 -0
  62. package/esm/MarkTextColor.d.ts.map +1 -0
  63. package/esm/MarkTextColor.js +27 -0
  64. package/esm/MarkUnderline.d.ts +11 -0
  65. package/esm/MarkUnderline.d.ts.map +1 -0
  66. package/esm/MarkUnderline.js +33 -0
  67. package/esm/NodeAside.d.ts +8 -0
  68. package/esm/NodeAside.d.ts.map +1 -0
  69. package/esm/NodeAside.js +16 -0
  70. package/esm/NodeBlockquote.d.ts +13 -0
  71. package/esm/NodeBlockquote.d.ts.map +1 -0
  72. package/esm/NodeBlockquote.js +34 -0
  73. package/esm/NodeBookmark.d.ts +8 -0
  74. package/esm/NodeBookmark.d.ts.map +1 -0
  75. package/esm/NodeBookmark.js +19 -0
  76. package/esm/NodeBulletList.d.ts +13 -0
  77. package/esm/NodeBulletList.d.ts.map +1 -0
  78. package/esm/NodeBulletList.js +34 -0
  79. package/esm/NodeCodeBlock.d.ts +9 -0
  80. package/esm/NodeCodeBlock.d.ts.map +1 -0
  81. package/esm/NodeCodeBlock.js +50 -0
  82. package/esm/NodeDefinitionDesc.d.ts +8 -0
  83. package/esm/NodeDefinitionDesc.d.ts.map +1 -0
  84. package/esm/NodeDefinitionDesc.js +16 -0
  85. package/esm/NodeDefinitionList.d.ts +13 -0
  86. package/esm/NodeDefinitionList.d.ts.map +1 -0
  87. package/esm/NodeDefinitionList.js +28 -0
  88. package/esm/NodeDefinitionTerm.d.ts +8 -0
  89. package/esm/NodeDefinitionTerm.d.ts.map +1 -0
  90. package/esm/NodeDefinitionTerm.js +16 -0
  91. package/esm/NodeDocument.d.ts +7 -0
  92. package/esm/NodeDocument.d.ts.map +1 -0
  93. package/esm/NodeDocument.js +19 -0
  94. package/esm/NodeDocumentCode.d.ts +7 -0
  95. package/esm/NodeDocumentCode.d.ts.map +1 -0
  96. package/esm/NodeDocumentCode.js +29 -0
  97. package/esm/NodeFrontmatter.d.ts +8 -0
  98. package/esm/NodeFrontmatter.d.ts.map +1 -0
  99. package/esm/NodeFrontmatter.js +16 -0
  100. package/esm/NodeHardBreak.d.ts +14 -0
  101. package/esm/NodeHardBreak.d.ts.map +1 -0
  102. package/esm/NodeHardBreak.js +67 -0
  103. package/esm/NodeHeading.d.ts +13 -0
  104. package/esm/NodeHeading.d.ts.map +1 -0
  105. package/esm/NodeHeading.js +49 -0
  106. package/esm/NodeHorizontalRule.d.ts +11 -0
  107. package/esm/NodeHorizontalRule.d.ts.map +1 -0
  108. package/esm/NodeHorizontalRule.js +29 -0
  109. package/esm/NodeImage.d.ts +8 -0
  110. package/esm/NodeImage.d.ts.map +1 -0
  111. package/esm/NodeImage.js +33 -0
  112. package/esm/NodeInlineShortCode.d.ts +11 -0
  113. package/esm/NodeInlineShortCode.d.ts.map +1 -0
  114. package/esm/NodeInlineShortCode.js +39 -0
  115. package/esm/NodeListItem.d.ts +14 -0
  116. package/esm/NodeListItem.d.ts.map +1 -0
  117. package/esm/NodeListItem.js +201 -0
  118. package/esm/NodeMath.d.ts +8 -0
  119. package/esm/NodeMath.d.ts.map +1 -0
  120. package/esm/NodeMath.js +99 -0
  121. package/esm/NodeOrderedList.d.ts +23 -0
  122. package/esm/NodeOrderedList.d.ts.map +1 -0
  123. package/esm/NodeOrderedList.js +52 -0
  124. package/esm/NodeParagraph.d.ts +11 -0
  125. package/esm/NodeParagraph.d.ts.map +1 -0
  126. package/esm/NodeParagraph.js +44 -0
  127. package/esm/NodeTaskItem.d.ts +24 -0
  128. package/esm/NodeTaskItem.d.ts.map +1 -0
  129. package/esm/NodeTaskItem.js +146 -0
  130. package/esm/NodeTaskList.d.ts +11 -0
  131. package/esm/NodeTaskList.d.ts.map +1 -0
  132. package/esm/NodeTaskList.js +25 -0
  133. package/esm/NodeText.d.ts +7 -0
  134. package/esm/NodeText.d.ts.map +1 -0
  135. package/esm/NodeText.js +9 -0
  136. package/esm/NodeVideo.d.ts +8 -0
  137. package/esm/NodeVideo.d.ts.map +1 -0
  138. package/esm/NodeVideo.js +45 -0
  139. package/esm/package.json +3 -0
  140. package/esm/remote-selection/ExtensionRemoteSelection.d.ts +24 -0
  141. package/esm/remote-selection/ExtensionRemoteSelection.d.ts.map +1 -0
  142. package/esm/remote-selection/ExtensionRemoteSelection.js +22 -0
  143. package/esm/remote-selection/remoteSelectionPlugin.d.ts +25 -0
  144. package/esm/remote-selection/remoteSelectionPlugin.d.ts.map +1 -0
  145. package/esm/remote-selection/remoteSelectionPlugin.js +96 -0
  146. package/package.json +2 -3
@@ -0,0 +1,67 @@
1
+ import { Node } from '@kerebron/editor';
2
+ import { firstCommand } from '@kerebron/editor/commands';
3
+ export class NodeHardBreak extends Node {
4
+ name = 'br';
5
+ requires = ['doc'];
6
+ options = {
7
+ keepMarks: true,
8
+ };
9
+ getNodeSpec() {
10
+ return {
11
+ inline: true,
12
+ group: 'inline',
13
+ selectable: false,
14
+ linebreakReplacement: true,
15
+ parseDOM: [{ tag: 'br' }],
16
+ toDOM() {
17
+ return ['br'];
18
+ },
19
+ };
20
+ }
21
+ getCommandFactories(editor, type) {
22
+ // TODO: refactor commands
23
+ // const comm2: Command = (state: EditorState, dispatch?: (tr: Transaction) => void) => {
24
+ // const { selection, storedMarks } = state
25
+ // if (selection.$from.parent.type.spec.isolating) {
26
+ // return false
27
+ // }
28
+ // const { keepMarks } = this.options
29
+ // // const { splittableMarks } = editor.extensionManager
30
+ // const splittableMarks = [];
31
+ // const marks = storedMarks
32
+ // || (selection.$to.parentOffset && selection.$from.marks())
33
+ // return editor.chain()
34
+ // .insertContent({ type: this.name })
35
+ // .command(({ tr, dispatch }) => {
36
+ // if (dispatch && marks && keepMarks) {
37
+ // for (const mark of marks) {
38
+ // console.log('mteset', mark.type);
39
+ // }
40
+ // const filteredMarks = marks
41
+ // .filter(mark => splittableMarks.includes(mark.type.name))
42
+ // tr.ensureMarks(filteredMarks)
43
+ // }
44
+ // return true
45
+ // })
46
+ // .run();
47
+ // }
48
+ const setHardBreak = firstCommand(editor.run.exitCode);
49
+ return {
50
+ 'setHardBreak': () => setHardBreak,
51
+ };
52
+ }
53
+ getKeyboardShortcuts() {
54
+ // https://stackoverflow.com/a/73619128
55
+ const mac = typeof navigator != 'undefined'
56
+ ? /Mac|iP(hone|[oa]d)/.test(navigator?.platform)
57
+ : false;
58
+ const shortcuts = {
59
+ 'Ctrl-Enter': 'setHardBreak',
60
+ };
61
+ if (mac) {
62
+ shortcuts['Mod-Enter'] = 'setHardBreak';
63
+ shortcuts['Shift-Enter'] = 'setHardBreak';
64
+ }
65
+ return shortcuts;
66
+ }
67
+ }
@@ -0,0 +1,13 @@
1
+ import type { NodeSpec, NodeType } from 'prosemirror-model';
2
+ import { type CoreEditor, Node } from '@kerebron/editor';
3
+ import { type CommandFactories, type CommandShortcuts } from '@kerebron/editor/commands';
4
+ import { type InputRule } from '@kerebron/editor/plugins/input-rules';
5
+ export declare class NodeHeading extends Node {
6
+ name: string;
7
+ requires: string[];
8
+ getNodeSpec(): NodeSpec;
9
+ getInputRules(type: NodeType): InputRule[];
10
+ getCommandFactories(editor: CoreEditor, type: NodeType): Partial<CommandFactories>;
11
+ getKeyboardShortcuts(): Partial<CommandShortcuts>;
12
+ }
13
+ //# sourceMappingURL=NodeHeading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeHeading.d.ts","sourceRoot":"","sources":["../src/NodeHeading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,sCAAsC,CAAC;AAI9C,qBAAa,WAAY,SAAQ,IAAI;IAC1B,IAAI,SAAa;IAC1B,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;IAoBvB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;IAc1C,mBAAmB,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC;IAWnB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAS3D"}
@@ -0,0 +1,49 @@
1
+ import { Node } from '@kerebron/editor';
2
+ import { textblockTypeInputRule, } from '@kerebron/editor/plugins/input-rules';
3
+ const maxLevel = 6;
4
+ export class NodeHeading extends Node {
5
+ name = 'heading';
6
+ requires = ['doc'];
7
+ getNodeSpec() {
8
+ return {
9
+ attrs: { level: { default: 1 } },
10
+ content: 'inline*',
11
+ group: 'block',
12
+ defining: true,
13
+ parseDOM: [
14
+ { tag: 'h1', attrs: { level: 1 } },
15
+ { tag: 'h2', attrs: { level: 2 } },
16
+ { tag: 'h3', attrs: { level: 3 } },
17
+ { tag: 'h4', attrs: { level: 4 } },
18
+ { tag: 'h5', attrs: { level: 5 } },
19
+ { tag: 'h6', attrs: { level: 6 } },
20
+ ],
21
+ toDOM(node) {
22
+ return ['h' + node.attrs.level, 0];
23
+ },
24
+ };
25
+ }
26
+ getInputRules(type) {
27
+ /// Given a node type and a maximum level, creates an input rule that
28
+ /// turns up to that number of `#` characters followed by a space at
29
+ /// the start of a textblock into a heading whose level corresponds to
30
+ /// the number of `#` signs.
31
+ return [
32
+ textblockTypeInputRule(new RegExp('^(#{1,' + maxLevel + '})\\s$'), type, (match) => ({ level: match[1].length })),
33
+ ];
34
+ }
35
+ getCommandFactories(editor, type) {
36
+ const commands = {};
37
+ for (let i = 1; i <= maxLevel; i++) {
38
+ commands['setHeading' + i] = () => editor.commandFactories.setBlockType(type, { level: i });
39
+ }
40
+ return commands;
41
+ }
42
+ getKeyboardShortcuts() {
43
+ const keys = {};
44
+ for (let i = 1; i <= maxLevel; i++) {
45
+ keys['Shift-Ctrl-' + i] = 'setHeading' + i;
46
+ }
47
+ return keys;
48
+ }
49
+ }
@@ -0,0 +1,11 @@
1
+ import type { NodeSpec, NodeType } from 'prosemirror-model';
2
+ import { type CoreEditor, Node } from '@kerebron/editor';
3
+ import type { CommandFactories, CommandShortcuts } from '@kerebron/editor/commands';
4
+ export declare class NodeHorizontalRule extends Node {
5
+ name: string;
6
+ requires: string[];
7
+ getNodeSpec(): NodeSpec;
8
+ getCommandFactories(editor: CoreEditor, type: NodeType): Partial<CommandFactories>;
9
+ getKeyboardShortcuts(): Partial<CommandShortcuts>;
10
+ }
11
+ //# sourceMappingURL=NodeHorizontalRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeHorizontalRule.d.ts","sourceRoot":"","sources":["../src/NodeHorizontalRule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAEnC,qBAAa,kBAAmB,SAAQ,IAAI;IACjC,IAAI,SAAQ;IACrB,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;IAUvB,mBAAmB,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC;IAanB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAK3D"}
@@ -0,0 +1,29 @@
1
+ import { Node } from '@kerebron/editor';
2
+ export class NodeHorizontalRule extends Node {
3
+ name = 'hr';
4
+ requires = ['doc'];
5
+ getNodeSpec() {
6
+ return {
7
+ group: 'block',
8
+ parseDOM: [{ tag: 'hr' }],
9
+ toDOM() {
10
+ return ['hr'];
11
+ },
12
+ };
13
+ }
14
+ getCommandFactories(editor, type) {
15
+ return {
16
+ 'setHorizontalRule': () => (state, dispatch) => {
17
+ if (dispatch) {
18
+ dispatch(state.tr.replaceSelectionWith(type.create()).scrollIntoView());
19
+ }
20
+ return true;
21
+ },
22
+ };
23
+ }
24
+ getKeyboardShortcuts() {
25
+ return {
26
+ 'Mod-_': 'setHorizontalRule',
27
+ };
28
+ }
29
+ }
@@ -0,0 +1,8 @@
1
+ import { type NodeSpec } from 'prosemirror-model';
2
+ import { Node } from '@kerebron/editor';
3
+ export declare class NodeImage extends Node {
4
+ name: string;
5
+ requires: string[];
6
+ getNodeSpec(): NodeSpec;
7
+ }
8
+ //# sourceMappingURL=NodeImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeImage.d.ts","sourceRoot":"","sources":["../src/NodeImage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,qBAAa,SAAU,SAAQ,IAAI;IACxB,IAAI,SAAW;IACxB,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;CA4BjC"}
@@ -0,0 +1,33 @@
1
+ import { Node } from '@kerebron/editor';
2
+ export class NodeImage extends Node {
3
+ name = 'image';
4
+ requires = ['doc'];
5
+ getNodeSpec() {
6
+ return {
7
+ inline: true,
8
+ attrs: {
9
+ src: {},
10
+ alt: { default: null },
11
+ title: { default: null },
12
+ },
13
+ group: 'inline',
14
+ draggable: true,
15
+ parseDOM: [
16
+ {
17
+ tag: 'img[src]',
18
+ getAttrs(dom) {
19
+ return {
20
+ src: dom.getAttribute('src'),
21
+ title: dom.getAttribute('title'),
22
+ alt: dom.getAttribute('alt'),
23
+ };
24
+ },
25
+ },
26
+ ],
27
+ toDOM(node) {
28
+ const { src, alt, title } = node.attrs;
29
+ return ['img', { src, alt, title }];
30
+ },
31
+ };
32
+ }
33
+ }
@@ -0,0 +1,11 @@
1
+ import { NodeSpec, NodeType } from 'prosemirror-model';
2
+ import { Node } from '@kerebron/editor';
3
+ import { type InputRule } from '@kerebron/editor/plugins/input-rules';
4
+ export declare function fixCharacters(text: string): string;
5
+ export declare class NodeInlineShortCode extends Node {
6
+ name: string;
7
+ requires: string[];
8
+ getNodeSpec(): NodeSpec;
9
+ getInputRules(type: NodeType): InputRule[];
10
+ }
11
+ //# sourceMappingURL=NodeInlineShortCode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeInlineShortCode.d.ts","sourceRoot":"","sources":["../src/NodeInlineShortCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,sCAAsC,CAAC;AAE9C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,UASzC;AAED,qBAAa,mBAAoB,SAAQ,IAAI;IAClC,IAAI,SAAsB;IACnC,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;IAgBvB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;CAcpD"}
@@ -0,0 +1,39 @@
1
+ import { Node } from '@kerebron/editor';
2
+ import { replaceInlineNode, } from '@kerebron/editor/plugins/input-rules';
3
+ export function fixCharacters(text) {
4
+ return text
5
+ .replace(/’/g, "'")
6
+ .replace(/“/g, '"')
7
+ .replace(/”/g, '"')
8
+ // deno-lint-ignore no-control-regex
9
+ .replace(/\x0b/g, ' ')
10
+ .replace(/\u201d/g, '"')
11
+ .replace(/\u201c/g, '"');
12
+ }
13
+ export class NodeInlineShortCode extends Node {
14
+ name = 'shortcode-inline';
15
+ requires = ['doc'];
16
+ getNodeSpec() {
17
+ return {
18
+ inline: true,
19
+ group: 'inline',
20
+ selectable: true,
21
+ attrs: {
22
+ content: {},
23
+ },
24
+ atom: true,
25
+ parseDOM: [{ tag: 'span.kb-shortcode-inline' }],
26
+ toDOM(node) {
27
+ return ['span', { class: 'kb-shortcode-inline' }, node.attrs.content];
28
+ },
29
+ };
30
+ }
31
+ getInputRules(type) {
32
+ return [
33
+ replaceInlineNode(/\{\{[^}]+\}\}/, type, (match) => {
34
+ const content = fixCharacters(match[0].substring(2, match[0].length - 2));
35
+ return { content };
36
+ }),
37
+ ];
38
+ }
39
+ }
@@ -0,0 +1,14 @@
1
+ import { type Attrs, NodeSpec, type NodeType } from 'prosemirror-model';
2
+ import { type CoreEditor, Node } from '@kerebron/editor';
3
+ import { type Command, type CommandFactories, type CommandShortcuts } from '@kerebron/editor/commands';
4
+ export declare function splitListItem(itemType: NodeType, itemAttrs?: Attrs): Command;
5
+ export declare function liftListItem(itemType: NodeType): Command;
6
+ export declare function sinkListItem(itemType: NodeType): Command;
7
+ export declare class NodeListItem extends Node {
8
+ name: string;
9
+ requires: string[];
10
+ getNodeSpec(): NodeSpec;
11
+ getCommandFactories(editor: CoreEditor, type: NodeType): Partial<CommandFactories>;
12
+ getKeyboardShortcuts(): Partial<CommandShortcuts>;
13
+ }
14
+ //# sourceMappingURL=NodeListItem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeListItem.d.ts","sourceRoot":"","sources":["../src/NodeListItem.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EAGV,QAAQ,EACR,KAAK,QAAQ,EAEd,MAAM,mBAAmB,CAAC;AAO3B,OAAO,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAUnC,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,CAsE5E;AAwBD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAgBxD;AAuGD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CA0CxD;AAED,qBAAa,YAAa,SAAQ,IAAI;IAC3B,IAAI,SAAe;IAC5B,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;IAWvB,mBAAmB,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC;IAQnB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAO3D"}
@@ -0,0 +1,201 @@
1
+ import { Fragment, NodeRange, Slice, } from 'prosemirror-model';
2
+ import { Selection } from 'prosemirror-state';
3
+ import { Node } from '@kerebron/editor';
4
+ import { canJoin, canSplit, liftTarget, ReplaceAroundStep, } from 'prosemirror-transform';
5
+ /// Build a command that splits a non-empty textblock at the top level
6
+ /// of a list item by also splitting that list item.
7
+ export function splitListItem(itemType, itemAttrs) {
8
+ const cmd = function (state, dispatch) {
9
+ const { $from, $to, node } = state.selection;
10
+ if ((node && node.isBlock) || $from.depth < 2 || !$from.sameParent($to)) {
11
+ return false;
12
+ }
13
+ const grandParent = $from.node(-1);
14
+ if (grandParent.type != itemType)
15
+ return false;
16
+ if ($from.parent.content.size == 0 &&
17
+ $from.node(-1).childCount == $from.indexAfter(-1)) {
18
+ // In an empty block. If this is a nested list, the wrapping
19
+ // list item should be split. Otherwise, bail out and let next
20
+ // command handle lifting.
21
+ if ($from.depth == 3 || $from.node(-3).type != itemType ||
22
+ $from.index(-2) != $from.node(-2).childCount - 1)
23
+ return false;
24
+ if (dispatch) {
25
+ let wrap = Fragment.empty;
26
+ const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3;
27
+ // Build a fragment containing empty versions of the structure
28
+ // from the outer list item to the parent node of the cursor
29
+ for (let d = $from.depth - depthBefore; d >= $from.depth - 3; d--) {
30
+ wrap = Fragment.from($from.node(d).copy(wrap));
31
+ }
32
+ let depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount
33
+ ? 1
34
+ : $from.indexAfter(-2) < $from.node(-3).childCount
35
+ ? 2
36
+ : 3;
37
+ // Add a second list item with an empty default start node
38
+ wrap = wrap.append(Fragment.from(itemType.createAndFill()));
39
+ let start = $from.before($from.depth - (depthBefore - 1));
40
+ let tr = state.tr.replace(start, $from.after(-depthAfter), new Slice(wrap, 4 - depthBefore, 0));
41
+ let sel = -1;
42
+ tr.doc.nodesBetween(start, tr.doc.content.size, (node, pos) => {
43
+ if (sel > -1)
44
+ return false;
45
+ if (node.isTextblock && node.content.size == 0)
46
+ sel = pos + 1;
47
+ });
48
+ if (sel > -1)
49
+ tr.setSelection(Selection.near(tr.doc.resolve(sel)));
50
+ dispatch(tr.scrollIntoView());
51
+ }
52
+ return true;
53
+ }
54
+ let nextType = $to.pos == $from.end()
55
+ ? grandParent.contentMatchAt(0).defaultType
56
+ : null;
57
+ let tr = state.tr.delete($from.pos, $to.pos);
58
+ let types = nextType
59
+ ? [itemAttrs ? { type: itemType, attrs: itemAttrs } : null, {
60
+ type: nextType,
61
+ }]
62
+ : undefined;
63
+ if (!canSplit(tr.doc, $from.pos, 2, types))
64
+ return false;
65
+ if (dispatch)
66
+ dispatch(tr.split($from.pos, 2, types).scrollIntoView());
67
+ return true;
68
+ };
69
+ cmd.displayName = `splitListItem(${itemType.name})`;
70
+ return cmd;
71
+ }
72
+ /// Acts like [`splitListItem`](#schema-list.splitListItem), but
73
+ /// without resetting the set of active marks at the cursor.
74
+ function splitListItemKeepMarks(itemType, itemAttrs) {
75
+ let split = splitListItem(itemType, itemAttrs);
76
+ return (state, dispatch) => {
77
+ return split(state, dispatch && ((tr) => {
78
+ let marks = state.storedMarks ||
79
+ (state.selection.$to.parentOffset && state.selection.$from.marks());
80
+ if (marks)
81
+ tr.ensureMarks(marks);
82
+ dispatch(tr);
83
+ }));
84
+ };
85
+ }
86
+ /// Create a command to lift the list item around the selection up into
87
+ /// a wrapping list.
88
+ export function liftListItem(itemType) {
89
+ return function (state, dispatch) {
90
+ let { $from, $to } = state.selection;
91
+ let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
92
+ if (!range)
93
+ return false;
94
+ if (!dispatch)
95
+ return true;
96
+ if ($from.node(range.depth - 1).type == itemType) { // Inside a parent list
97
+ return liftToOuterList(state, dispatch, itemType, range);
98
+ } // Outer list node
99
+ else {
100
+ return liftOutOfList(state, dispatch, range);
101
+ }
102
+ };
103
+ }
104
+ function liftToOuterList(state, dispatch, itemType, range) {
105
+ let tr = state.tr, end = range.end, endOfList = range.$to.end(range.depth);
106
+ if (end < endOfList) {
107
+ // There are siblings after the lifted items, which must become
108
+ // children of the last item
109
+ tr.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList, new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true));
110
+ range = new NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth);
111
+ }
112
+ const target = liftTarget(range);
113
+ if (target == null)
114
+ return false;
115
+ tr.lift(range, target);
116
+ let $after = tr.doc.resolve(tr.mapping.map(end, -1) - 1);
117
+ if (canJoin(tr.doc, $after.pos) &&
118
+ $after.nodeBefore.type == $after.nodeAfter.type)
119
+ tr.join($after.pos);
120
+ dispatch(tr.scrollIntoView());
121
+ return true;
122
+ }
123
+ function liftOutOfList(state, dispatch, range) {
124
+ let tr = state.tr, list = range.parent;
125
+ // Merge the list items into a single big item
126
+ for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) {
127
+ pos -= list.child(i).nodeSize;
128
+ tr.delete(pos - 1, pos + 1);
129
+ }
130
+ let $start = tr.doc.resolve(range.start), item = $start.nodeAfter;
131
+ if (tr.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize) {
132
+ return false;
133
+ }
134
+ let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount;
135
+ let parent = $start.node(-1), indexBefore = $start.index(-1);
136
+ if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment.empty : Fragment.from(list)))) {
137
+ return false;
138
+ }
139
+ let start = $start.pos, end = start + item.nodeSize;
140
+ // Strip off the surrounding list. At the sides where we're not at
141
+ // the end of the list, the existing list is closed. At sides where
142
+ // this is the end, it is overwritten to its end.
143
+ tr.step(new ReplaceAroundStep(start - (atStart ? 1 : 0), end + (atEnd ? 1 : 0), start + 1, end - 1, new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty)))
144
+ .append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1));
145
+ dispatch(tr.scrollIntoView());
146
+ return true;
147
+ }
148
+ /// Create a command to sink the list item around the selection down
149
+ /// into an inner list.
150
+ export function sinkListItem(itemType) {
151
+ return function (state, dispatch) {
152
+ const { $from, $to } = state.selection;
153
+ const range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType);
154
+ if (!range)
155
+ return false;
156
+ const startIndex = range.startIndex;
157
+ if (startIndex == 0)
158
+ return false;
159
+ const parent = range.parent, nodeBefore = parent.child(startIndex - 1);
160
+ if (nodeBefore.type != itemType)
161
+ return false;
162
+ if (dispatch) {
163
+ const nestedBefore = nodeBefore.lastChild &&
164
+ nodeBefore.lastChild.type == parent.type;
165
+ const inner = Fragment.from(nestedBefore ? itemType.create() : null);
166
+ const slice = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0);
167
+ const before = range.start, after = range.end;
168
+ dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice, 1, true))
169
+ .scrollIntoView());
170
+ }
171
+ return true;
172
+ };
173
+ }
174
+ export class NodeListItem extends Node {
175
+ name = 'list_item';
176
+ requires = ['doc'];
177
+ getNodeSpec() {
178
+ return {
179
+ content: 'paragraph block*',
180
+ parseDOM: [{ tag: 'li' }],
181
+ defining: true,
182
+ toDOM() {
183
+ return ['li', 0];
184
+ },
185
+ };
186
+ }
187
+ getCommandFactories(editor, type) {
188
+ return {
189
+ 'splitListItem': () => splitListItem(type),
190
+ 'liftListItem': () => liftListItem(type),
191
+ 'sinkListItem': () => sinkListItem(type),
192
+ };
193
+ }
194
+ getKeyboardShortcuts() {
195
+ return {
196
+ 'Enter': 'splitListItem',
197
+ 'Tab': 'sinkListItem',
198
+ 'Shift-Tab': 'liftListItem',
199
+ };
200
+ }
201
+ }
@@ -0,0 +1,8 @@
1
+ import { type NodeSpec } from 'prosemirror-model';
2
+ import { Node } from '@kerebron/editor';
3
+ export declare class NodeMath extends Node {
4
+ name: string;
5
+ requires: string[];
6
+ getNodeSpec(): NodeSpec;
7
+ }
8
+ //# sourceMappingURL=NodeMath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeMath.d.ts","sourceRoot":"","sources":["../src/NodeMath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAMxC,qBAAa,QAAS,SAAQ,IAAI;IACvB,IAAI,SAAU;IACvB,QAAQ,WAAW;IAEV,WAAW,IAAI,QAAQ;CA8CjC"}
@@ -0,0 +1,99 @@
1
+ import { Node } from '@kerebron/editor';
2
+ // import { MathMLToLaTeX } from 'mathml-to-latex';
3
+ // const latex = MathMLToLaTeX.convert(mathMl);
4
+ // https://mathlive.io/mathfield/
5
+ export class NodeMath extends Node {
6
+ name = 'math';
7
+ requires = ['doc'];
8
+ getNodeSpec() {
9
+ return {
10
+ inline: true,
11
+ attrs: {
12
+ lang: { default: 'mathml' },
13
+ content: {},
14
+ },
15
+ group: 'inline',
16
+ draggable: true,
17
+ // parseDOM: [
18
+ // {
19
+ // tag: 'math',
20
+ // getAttrs(dom: HTMLElement) {
21
+ // return {
22
+ // content: dom.outerHTML,
23
+ // };
24
+ // },
25
+ // },
26
+ // ],
27
+ parseDOM: [{
28
+ tag: 'math',
29
+ getAttrs: (dom) => ({
30
+ lang: 'mathml',
31
+ content: new XMLSerializer().serializeToString(dom),
32
+ }),
33
+ }],
34
+ toDOM(node) {
35
+ const parser = new DOMParser();
36
+ const parsed = parser.parseFromString(node.attrs.content, 'application/xml');
37
+ // Check for parsing errors (e.g., invalid XML)
38
+ const errorNode = parsed.getElementsByTagName('parsererror');
39
+ if (errorNode.length > 0) {
40
+ return ['span', { class: 'mathml-error' }, 'Invalid MathML'];
41
+ }
42
+ // Import and return the parsed MathML element
43
+ return document.importNode(parsed.documentElement, true);
44
+ // const { xml } = node.attrs;
45
+ // return ['math', {}, []];
46
+ },
47
+ };
48
+ }
49
+ }
50
+ /*
51
+ MathML vs. LaTeX: Which is Better for Web Math Equations?
52
+ Neither is universally "better"—it depends on your goals (authoring, rendering, accessibility, or storage). MathML and LaTeX serve different primary purposes but can complement each other on the web (e.g., via converters like MathJax). Here's a comparison focused on web use:
53
+ Key Differences
54
+
55
+ Purpose:
56
+
57
+ LaTeX: A human-readable markup language for typesetting math (e.g., $E=mc^2$). It's concise and widely used for authoring documents, papers, and web input. Not native to HTML; requires a processor (e.g., MathJax, KaTeX) to render as HTML/CSS/SVG.
58
+ MathML: An XML-based standard (part of HTML5) for describing math structure and presentation (Presentation MathML for visuals; Content MathML for semantics). Designed for direct embedding in web pages (e.g., <math><mi>E</mi>=<mi>m</mi><msup><mi>c</mi><mn>2</mn></msup></math>). Browsers like Firefox and Safari support it natively; others need polyfills.
59
+
60
+
61
+ Ease of Authoring:
62
+
63
+ LaTeX: Wins for humans—shorter, intuitive syntax familiar to mathematicians. Easier to write/edit manually or in editors like Overleaf. Verbose MathML is painful for hand-coding complex equations.
64
+ MathML: Better for programmatic generation (e.g., from tools or APIs) due to its structured XML. Use WYSIWYG editors (like those above) to avoid writing tags.
65
+
66
+
67
+ Rendering on Web:
68
+
69
+ LaTeX: Requires a JS library (MathJax ~300KB, KaTeX lighter ~100KB) for cross-browser display. Renders beautifully everywhere but adds load time and JS dependency. No native browser support.
70
+ MathML: Native in Firefox/Safari (fast, no JS). Improving in Chrome/Edge (as of 2023+), but still needs MathJax fallback for full support. Outputs scalable HTML/CSS without images.
71
+
72
+
73
+ Accessibility:
74
+
75
+ MathML: Superior—semantic structure allows screen readers (e.g., NVDA with MathCAT, JAWS) to read equations meaningfully (e.g., "E equals m times c squared"). Essential for WCAG/ADA compliance.
76
+ LaTeX: Poor native accessibility; screen readers treat it as plain text. MathJax can convert to MathML internally for better support, but raw LaTeX fails.
77
+
78
+
79
+ Performance & Compatibility:
80
+
81
+ LaTeX: Faster authoring, but rendering depends on the library. Universal via JS, but increases page weight.
82
+ MathML: Lightweight native rendering where supported; more robust for search engines/parsing (e.g., Google indexes MathML). Less portable outside web (LaTeX dominates PDFs/print).
83
+
84
+
85
+ Storage/Interoperability:
86
+
87
+ LaTeX: Compact for databases/files. Easy to convert to MathML (via tools like texmath or Pandoc).
88
+ MathML: Better for web standards (XML parsable), but bulkier. Ideal for exchange between math tools.
89
+
90
+
91
+
92
+ Recommendation
93
+
94
+ Use LaTeX if your focus is easy input/authoring (e.g., users typing equations) and you're okay with a renderer like MathJax. It's more practical for most web projects today due to familiarity and tools. Store as LaTeX, render via JS, and convert to MathML for accessibility if needed.
95
+ Use MathML if prioritizing native web standards, accessibility, or programmatic output (e.g., from editors). It's "better" for semantic web math and future-proofing (browser support is growing), but pair with LaTeX input for usability.
96
+ Hybrid Approach: Best for web—author in LaTeX, convert/output MathML for display/storage. Libraries like MathJax handle both seamlessly (input LaTeX, output rendered MathML). This gives LaTeX's simplicity with MathML's benefits.
97
+
98
+ If accessibility is key, always generate MathML (even from LaTeX source). Test in browsers: LaTeX+MathJax works everywhere; pure MathML shines in Firefox but needs fallbacks elsewhere.
99
+ */
@@ -0,0 +1,23 @@
1
+ import { NodeSpec, NodeType } from 'prosemirror-model';
2
+ import { type CoreEditor, Node } from '@kerebron/editor';
3
+ import { type InputRule } from '@kerebron/editor/plugins/input-rules';
4
+ import { type CommandFactories, type CommandShortcuts } from '@kerebron/editor/commands';
5
+ export declare class NodeOrderedList extends Node {
6
+ name: string;
7
+ requires: string[];
8
+ attributes: {
9
+ type: {
10
+ default: string;
11
+ fromDom(element: HTMLElement): any;
12
+ };
13
+ start: {
14
+ default: number;
15
+ fromDom(element: HTMLElement): number;
16
+ };
17
+ };
18
+ getNodeSpec(): NodeSpec;
19
+ getInputRules(type: NodeType): InputRule[];
20
+ getCommandFactories(editor: CoreEditor, type: NodeType): Partial<CommandFactories>;
21
+ getKeyboardShortcuts(): Partial<CommandShortcuts>;
22
+ }
23
+ //# sourceMappingURL=NodeOrderedList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodeOrderedList.d.ts","sourceRoot":"","sources":["../src/NodeOrderedList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAMzD,OAAO,EACL,KAAK,SAAS,EAEf,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAEnC,qBAAa,eAAgB,SAAQ,IAAI;IAC9B,IAAI,SAAkB;IAC/B,QAAQ,WAAW;IAEV,UAAU;;;6BAGE,WAAW;;;;6BAQX,WAAW;;MAM9B;IAEO,WAAW,IAAI,QAAQ;IAWvB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE;IAa1C,mBAAmB,CAC1B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,gBAAgB,CAAC;IAMnB,oBAAoB,IAAI,OAAO,CAAC,gBAAgB,CAAC;CAK3D"}