@prosekit/extensions 0.5.2 → 0.6.0

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 (33) hide show
  1. package/dist/_tsup-dts-rollup.d.ts +87 -6
  2. package/dist/{chunk-DZAKXWWF.js → chunk-2JYT2MT7.js} +21 -41
  3. package/dist/{chunk-LVMTQOWG.js → chunk-PYT3MOTF.js} +14 -31
  4. package/dist/chunk-ZPEMHYTU.js +140 -0
  5. package/dist/list/style.css +4 -8
  6. package/dist/placeholder/style.css +1 -1
  7. package/dist/prosekit-extensions-autocomplete.js +33 -62
  8. package/dist/prosekit-extensions-blockquote.js +2 -2
  9. package/dist/prosekit-extensions-bold.js +3 -7
  10. package/dist/prosekit-extensions-code-block.js +61 -81
  11. package/dist/prosekit-extensions-code.js +1 -1
  12. package/dist/prosekit-extensions-enter-rule.js +1 -1
  13. package/dist/prosekit-extensions-heading.js +6 -13
  14. package/dist/prosekit-extensions-image.js +5 -14
  15. package/dist/prosekit-extensions-input-rule.js +1 -1
  16. package/dist/prosekit-extensions-italic.js +1 -1
  17. package/dist/prosekit-extensions-link.js +16 -31
  18. package/dist/prosekit-extensions-list.js +2 -4
  19. package/dist/prosekit-extensions-mark-rule.js +1 -1
  20. package/dist/prosekit-extensions-mention.js +4 -6
  21. package/dist/prosekit-extensions-placeholder.js +9 -20
  22. package/dist/prosekit-extensions-readonly.js +1 -1
  23. package/dist/prosekit-extensions-search.d.ts +3 -0
  24. package/dist/prosekit-extensions-search.js +49 -0
  25. package/dist/prosekit-extensions-strike.js +1 -1
  26. package/dist/prosekit-extensions-table.js +30 -68
  27. package/dist/prosekit-extensions-text-align.js +2 -4
  28. package/dist/prosekit-extensions-virtual-selection.js +6 -12
  29. package/dist/search/style.css +13 -0
  30. package/dist/shiki-import-UFUFVKJ2.js +5 -0
  31. package/package.json +19 -7
  32. package/dist/chunk-ZOBSD7ZH.js +0 -189
  33. package/dist/shiki-import-25BJYIO2.js +0 -5
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineInputRule
3
- } from "./chunk-LVMTQOWG.js";
3
+ } from "./chunk-PYT3MOTF.js";
4
4
 
5
5
  // src/list/index.ts
6
6
  import {
@@ -50,9 +50,7 @@ function defineListCommands() {
50
50
  toggleList: createToggleListCommand,
51
51
  unwrapList: createUnwrapListCommand,
52
52
  wrapInList: createWrapInListCommand,
53
- insertList: (attrs) => {
54
- return insertNode({ type: "list", attrs });
55
- }
53
+ insertList: (attrs) => insertNode({ type: "list", attrs })
56
54
  });
57
55
  }
58
56
  function defineList() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineMarkRule
3
- } from "./chunk-ZOBSD7ZH.js";
3
+ } from "./chunk-ZPEMHYTU.js";
4
4
  export {
5
5
  defineMarkRule
6
6
  };
@@ -8,18 +8,18 @@ import {
8
8
  function defineMentionSpec() {
9
9
  return defineNodeSpec({
10
10
  name: "mention",
11
- atom: true,
11
+ atom: !0,
12
12
  group: "inline",
13
13
  attrs: {
14
14
  id: {},
15
15
  value: {},
16
16
  kind: { default: "" }
17
17
  },
18
- inline: true,
18
+ inline: !0,
19
19
  leafText: (node) => node.attrs.value.toString(),
20
20
  parseDOM: [
21
21
  {
22
- tag: `span[data-mention]`,
22
+ tag: "span[data-mention]",
23
23
  getAttrs: (dom) => ({
24
24
  id: dom.getAttribute("data-id") || "",
25
25
  kind: dom.getAttribute("data-mention") || "",
@@ -41,9 +41,7 @@ function defineMentionSpec() {
41
41
  }
42
42
  function defineMentionCommands() {
43
43
  return defineCommands({
44
- insertMention: (attrs) => {
45
- return insertNode({ type: "mention", attrs });
46
- }
44
+ insertMention: (attrs) => insertNode({ type: "mention", attrs })
47
45
  });
48
46
  }
49
47
  function defineMention() {
@@ -11,35 +11,24 @@ function createPlaceholderPlugin(options) {
11
11
  key: new PluginKey("prosekit-placeholder"),
12
12
  props: {
13
13
  decorations: (state) => {
14
- if (options.strategy === "doc" && !isDocEmpty(state.doc)) {
14
+ if (options.strategy === "doc" && !isDocEmpty(state.doc) || isInCodeBlock(state.selection))
15
15
  return null;
16
- }
17
- if (isInCodeBlock(state.selection)) {
18
- return null;
19
- }
20
- const placeholderText = options.placeholder;
21
- const deco = createPlaceholderDecoration(state, placeholderText);
22
- if (!deco) {
23
- return null;
24
- }
25
- return DecorationSet.create(state.doc, [deco]);
16
+ let placeholderText = options.placeholder, deco = createPlaceholderDecoration(state, placeholderText);
17
+ return deco ? DecorationSet.create(state.doc, [deco]) : null;
26
18
  }
27
19
  }
28
20
  });
29
21
  }
30
22
  function isDocEmpty(doc) {
31
23
  var _a;
32
- return doc.childCount <= 1 && !((_a = doc.firstChild) == null ? void 0 : _a.content.size);
24
+ return doc.childCount <= 1 && !((_a = doc.firstChild) != null && _a.content.size);
33
25
  }
34
26
  function createPlaceholderDecoration(state, placeholderText) {
35
- const { selection } = state;
36
- if (!selection.empty)
37
- return null;
38
- const $pos = selection.$anchor;
39
- const node = $pos.parent;
40
- if (node.content.size > 0)
41
- return null;
42
- const before = $pos.before();
27
+ let { selection } = state;
28
+ if (!selection.empty) return null;
29
+ let $pos = selection.$anchor, node = $pos.parent;
30
+ if (node.content.size > 0) return null;
31
+ let before = $pos.before();
43
32
  return Decoration.node(before, before + node.nodeSize, {
44
33
  class: "prosekit-placeholder",
45
34
  "data-placeholder": placeholderText
@@ -7,7 +7,7 @@ function defineReadonly() {
7
7
  var plugin = new ProseMirrorPlugin({
8
8
  key: new PluginKey("prosekey-readonly"),
9
9
  props: {
10
- editable: () => false
10
+ editable: () => !1
11
11
  }
12
12
  });
13
13
  export {
@@ -0,0 +1,3 @@
1
+ export { defineSearchQuery } from './_tsup-dts-rollup';
2
+ export { defineSearchCommands } from './_tsup-dts-rollup';
3
+ export { SearchQueryOptions } from './_tsup-dts-rollup';
@@ -0,0 +1,49 @@
1
+ // src/search/index.ts
2
+ import { defineCommands, definePlugin } from "@prosekit/core";
3
+ import {
4
+ SearchQuery,
5
+ findNext,
6
+ findNextNoWrap,
7
+ findPrev,
8
+ findPrevNoWrap,
9
+ replaceAll,
10
+ replaceCurrent,
11
+ replaceNext,
12
+ replaceNextNoWrap,
13
+ search
14
+ } from "prosemirror-search";
15
+ function defineSearchQuery(options) {
16
+ let query = new SearchQuery(options);
17
+ return definePlugin(search({ initialQuery: query }));
18
+ }
19
+ function scrollActiveIntoView(view) {
20
+ if (view.isDestroyed) return;
21
+ let active = view.dom.querySelector(".ProseMirror-active-search-match");
22
+ active == null || active.scrollIntoView({
23
+ block: "nearest",
24
+ inline: "nearest",
25
+ behavior: "smooth"
26
+ });
27
+ }
28
+ function withScrollActiveIntoView(command) {
29
+ return (state, dispatch, view) => {
30
+ let result = command(state, dispatch, view);
31
+ return result && dispatch && view && setTimeout(() => scrollActiveIntoView(view), 50), result;
32
+ };
33
+ }
34
+ function defineSearchCommands() {
35
+ return defineCommands({
36
+ findNext: () => withScrollActiveIntoView(findNext),
37
+ findPrev: () => withScrollActiveIntoView(findPrev),
38
+ findNextNoWrap: () => withScrollActiveIntoView(findNextNoWrap),
39
+ findPrevNoWrap: () => withScrollActiveIntoView(findPrevNoWrap),
40
+ replaceNext: () => withScrollActiveIntoView(replaceNext),
41
+ replaceNextNoWrap: () => withScrollActiveIntoView(replaceNextNoWrap),
42
+ replaceCurrent: () => withScrollActiveIntoView(replaceCurrent),
43
+ replaceAll: () => withScrollActiveIntoView(replaceAll)
44
+ });
45
+ }
46
+ export {
47
+ defineSearchCommands,
48
+ defineSearchQuery
49
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineMarkInputRule
3
- } from "./chunk-LVMTQOWG.js";
3
+ } from "./chunk-PYT3MOTF.js";
4
4
 
5
5
  // src/strike/index.ts
6
6
  import {
@@ -10,23 +10,13 @@ import {
10
10
  } from "@prosekit/core";
11
11
  import { TextSelection } from "@prosekit/pm/state";
12
12
  function createEmptyTable(schema, row, col, header) {
13
- const table = getNodeType(schema, "table");
14
- const tableRow = getNodeType(schema, "tableRow");
15
- const tableCell = getNodeType(schema, "tableCell");
16
- const tableHeaderCell = getNodeType(schema, "tableHeaderCell");
17
- const createHeaderRow = () => {
18
- return tableRow.createAndFill(
19
- null,
20
- Array.from({ length: col }, () => tableHeaderCell.createAndFill())
21
- );
22
- };
23
- const createBodyRow = () => {
24
- return tableRow.createAndFill(
25
- null,
26
- Array.from({ length: col }, () => tableCell.createAndFill())
27
- );
28
- };
29
- const rows = [
13
+ let table = getNodeType(schema, "table"), tableRow = getNodeType(schema, "tableRow"), tableCell = getNodeType(schema, "tableCell"), tableHeaderCell = getNodeType(schema, "tableHeaderCell"), createHeaderRow = () => tableRow.createAndFill(
14
+ null,
15
+ Array.from({ length: col }, () => tableHeaderCell.createAndFill())
16
+ ), createBodyRow = () => tableRow.createAndFill(
17
+ null,
18
+ Array.from({ length: col }, () => tableCell.createAndFill())
19
+ ), rows = [
30
20
  ...Array.from({ length: header ? 1 : 0 }, createHeaderRow),
31
21
  ...Array.from({ length: header ? row - 1 : row }, createBodyRow)
32
22
  ];
@@ -38,41 +28,27 @@ function insertTable({
38
28
  header
39
29
  }) {
40
30
  return (state, dispatch, view) => {
41
- const table = createEmptyTable(state.schema, row, col, header);
31
+ let table = createEmptyTable(state.schema, row, col, header);
42
32
  return insertNode({ node: table })(state, dispatch, view);
43
33
  };
44
34
  }
45
35
  var exitTable = (state, dispatch) => {
46
- const { $head, $anchor } = state.selection;
47
- if (!$head.sameParent($anchor)) {
48
- return false;
49
- }
50
- let tableStart = -1;
51
- let tableDepth = -1;
52
- for (let depth = $head.depth; depth >= 0; depth--) {
53
- const node2 = $head.node(depth);
54
- if (node2.type.spec.tableRole === "table") {
55
- tableStart = $head.before(depth);
56
- tableDepth = depth;
57
- }
58
- }
59
- if (tableStart < 0 || tableDepth <= 0) {
60
- return false;
61
- }
62
- const above = $head.node(tableDepth - 1);
63
- const after = $head.indexAfter(tableDepth - 1);
64
- const type = defaultBlockAt(above.contentMatchAt(after));
65
- const node = type == null ? void 0 : type.createAndFill();
66
- if (!type || !node || !above.canReplaceWith(after, after, type)) {
67
- return false;
68
- }
36
+ let { $head, $anchor } = state.selection;
37
+ if (!$head.sameParent($anchor))
38
+ return !1;
39
+ let tableStart = -1, tableDepth = -1;
40
+ for (let depth = $head.depth; depth >= 0; depth--)
41
+ $head.node(depth).type.spec.tableRole === "table" && (tableStart = $head.before(depth), tableDepth = depth);
42
+ if (tableStart < 0 || tableDepth <= 0)
43
+ return !1;
44
+ let above = $head.node(tableDepth - 1), after = $head.indexAfter(tableDepth - 1), type = defaultBlockAt(above.contentMatchAt(after)), node = type == null ? void 0 : type.createAndFill();
45
+ if (!type || !node || !above.canReplaceWith(after, after, type))
46
+ return !1;
69
47
  if (dispatch) {
70
- const pos = $head.after(tableDepth);
71
- const tr = state.tr.replaceWith(pos, pos, node);
72
- tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1));
73
- dispatch(tr.scrollIntoView());
48
+ let pos = $head.after(tableDepth), tr = state.tr.replaceWith(pos, pos, node);
49
+ tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1)), dispatch(tr.scrollIntoView());
74
50
  }
75
- return true;
51
+ return !0;
76
52
  };
77
53
  function defineTableCommands() {
78
54
  return defineCommands({
@@ -95,15 +71,11 @@ var cellAttrs = {
95
71
  colspan: { default: 1 },
96
72
  rowspan: { default: 1 },
97
73
  colwidth: { default: null }
98
- };
99
- var cellContent = "block+";
74
+ }, cellContent = "block+";
100
75
  function getCellAttrs(dom) {
101
- if (typeof dom === "string") {
76
+ if (typeof dom == "string")
102
77
  return {};
103
- }
104
- const widthAttr = dom.getAttribute("data-colwidth");
105
- const widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null;
106
- const colspan = Number(dom.getAttribute("colspan") || 1);
78
+ let widthAttr = dom.getAttribute("data-colwidth"), widths = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(",").map((s) => Number(s)) : null, colspan = Number(dom.getAttribute("colspan") || 1);
107
79
  return {
108
80
  colspan,
109
81
  rowspan: Number(dom.getAttribute("rowspan") || 1),
@@ -111,25 +83,15 @@ function getCellAttrs(dom) {
111
83
  };
112
84
  }
113
85
  function setCellAttrs(node) {
114
- const pmAttrs = node.attrs;
115
- const domAttrs = {};
116
- if (pmAttrs.colspan !== 1) {
117
- domAttrs.colspan = pmAttrs.colspan;
118
- }
119
- if (pmAttrs.rowspan !== 1) {
120
- domAttrs.rowspan = pmAttrs.rowspan;
121
- }
122
- if (pmAttrs.colwidth) {
123
- domAttrs["data-colwidth"] = pmAttrs.colwidth.join(",");
124
- }
125
- return domAttrs;
86
+ let pmAttrs = node.attrs, domAttrs = {};
87
+ return pmAttrs.colspan !== 1 && (domAttrs.colspan = pmAttrs.colspan), pmAttrs.rowspan !== 1 && (domAttrs.rowspan = pmAttrs.rowspan), pmAttrs.colwidth && (domAttrs["data-colwidth"] = pmAttrs.colwidth.join(",")), domAttrs;
126
88
  }
127
89
  function defineTableSpec() {
128
90
  return defineNodeSpec({
129
91
  name: "table",
130
92
  tableRole: "table",
131
93
  content: "tableRow+",
132
- isolating: true,
94
+ isolating: !0,
133
95
  group: "block",
134
96
  parseDOM: [{ tag: "table" }],
135
97
  toDOM() {
@@ -154,7 +116,7 @@ function defineTableCellSpec() {
154
116
  tableRole: "cell",
155
117
  content: cellContent,
156
118
  attrs: cellAttrs,
157
- isolating: true,
119
+ isolating: !0,
158
120
  parseDOM: [{ tag: "td", getAttrs: (dom) => getCellAttrs(dom) }],
159
121
  toDOM(node) {
160
122
  return ["td", setCellAttrs(node), 0];
@@ -167,7 +129,7 @@ function defineTableHeaderCellSpec() {
167
129
  tableRole: "header_cell",
168
130
  content: cellContent,
169
131
  attrs: cellAttrs,
170
- isolating: true,
132
+ isolating: !0,
171
133
  parseDOM: [{ tag: "th", getAttrs: (dom) => getCellAttrs(dom) }],
172
134
  toDOM(node) {
173
135
  return ["th", setCellAttrs(node), 0];
@@ -11,11 +11,9 @@ function defineTextAlignAttr(type, defaultValue) {
11
11
  type,
12
12
  attr: "textAlign",
13
13
  default: defaultValue,
14
- splittable: true,
14
+ splittable: !0,
15
15
  toDOM: (value) => value ? ["style", `text-align:${value};`] : null,
16
- parseDOM: (node) => {
17
- return node.style.getPropertyValue("text-align") || null;
18
- }
16
+ parseDOM: (node) => node.style.getPropertyValue("text-align") || null
19
17
  });
20
18
  }
21
19
  function defineTextAlignAttrs(types, defaultValue) {
@@ -21,7 +21,7 @@ function getFocusState(state) {
21
21
  var virtualSelectionPlugin = new ProseMirrorPlugin({
22
22
  key,
23
23
  state: {
24
- init: () => false,
24
+ init: () => !1,
25
25
  apply: (tr, value) => {
26
26
  var _a;
27
27
  return (_a = getFocusMeta(tr)) != null ? _a : value;
@@ -30,22 +30,16 @@ var virtualSelectionPlugin = new ProseMirrorPlugin({
30
30
  props: {
31
31
  handleDOMEvents: {
32
32
  focus: (view) => {
33
- view.dispatch(setFocusMeta(view.state.tr, false));
33
+ view.dispatch(setFocusMeta(view.state.tr, !1));
34
34
  },
35
35
  blur: (view) => {
36
- const { dom, root } = view;
37
- const activeElement = root.activeElement;
38
- if (activeElement === dom)
39
- return;
40
- view.dispatch(setFocusMeta(view.state.tr, true));
36
+ let { dom, root } = view;
37
+ root.activeElement !== dom && view.dispatch(setFocusMeta(view.state.tr, !0));
41
38
  }
42
39
  },
43
40
  decorations: (state) => {
44
- const { selection, doc } = state;
45
- if (selection.empty || !getFocusState(state)) {
46
- return null;
47
- }
48
- return DecorationSet.create(doc, [
41
+ let { selection, doc } = state;
42
+ return selection.empty || !getFocusState(state) ? null : DecorationSet.create(doc, [
49
43
  Decoration.inline(selection.from, selection.to, {
50
44
  class: "prosekit-virtual-selection"
51
45
  })
@@ -0,0 +1,13 @@
1
+ /* src/search/style.css */
2
+ .ProseMirror-search-match {
3
+ background-color: #ffff0054;
4
+ box-shadow: 0 0 0 2px #ffff0054;
5
+ border-radius: 2px;
6
+ }
7
+ .ProseMirror.ProseMirror-focused .ProseMirror-active-search-match::selection,
8
+ .ProseMirror:not(.ProseMirror-focused) .ProseMirror-active-search-match {
9
+ background-color: #ff6a0054;
10
+ box-shadow: 0 0 0 2px #ff6a0054;
11
+ border-radius: 2px;
12
+ scroll-margin: 8px;
13
+ }
@@ -0,0 +1,5 @@
1
+ // src/code-block/shiki-import.ts
2
+ import { getSingletonHighlighter } from "shiki/bundle/full";
3
+ export {
4
+ getSingletonHighlighter
5
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.5.2",
4
+ "version": "0.6.0",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -126,6 +126,14 @@
126
126
  "import": "./dist/prosekit-extensions-readonly.js",
127
127
  "default": "./dist/prosekit-extensions-readonly.js"
128
128
  },
129
+ "./search": {
130
+ "types": "./dist/prosekit-extensions-search.d.ts",
131
+ "import": "./dist/prosekit-extensions-search.js",
132
+ "default": "./dist/prosekit-extensions-search.js"
133
+ },
134
+ "./search/style.css": {
135
+ "default": "./dist/search/style.css"
136
+ },
129
137
  "./strike": {
130
138
  "types": "./dist/prosekit-extensions-strike.d.ts",
131
139
  "import": "./dist/prosekit-extensions-strike.js",
@@ -162,17 +170,18 @@
162
170
  "dist"
163
171
  ],
164
172
  "dependencies": {
165
- "@prosekit/core": "^0.5.4",
166
- "@prosekit/pm": "^0.1.4",
167
173
  "prosemirror-dropcursor": "^1.8.1",
168
174
  "prosemirror-flat-list": "^0.5.0",
169
- "prosemirror-highlight": "^0.6.0",
175
+ "prosemirror-highlight": "^0.8.0",
176
+ "prosemirror-search": "^0.1.0",
170
177
  "prosemirror-tables": "^1.3.7",
171
- "shiki": "^1.6.1"
178
+ "shiki": "^1.9.0",
179
+ "@prosekit/core": "^0.6.0",
180
+ "@prosekit/pm": "^0.1.5"
172
181
  },
173
182
  "devDependencies": {
174
- "tsup": "^8.0.2",
175
- "typescript": "^5.4.5",
183
+ "tsup": "^8.1.0",
184
+ "typescript": "^5.5.2",
176
185
  "vitest": "^1.6.0",
177
186
  "@prosekit/dev": "0.0.0"
178
187
  },
@@ -240,6 +249,9 @@
240
249
  "readonly": [
241
250
  "./dist/prosekit-extensions-readonly.d.ts"
242
251
  ],
252
+ "search": [
253
+ "./dist/prosekit-extensions-search.d.ts"
254
+ ],
243
255
  "strike": [
244
256
  "./dist/prosekit-extensions-strike.d.ts"
245
257
  ],
@@ -1,189 +0,0 @@
1
- // src/mark-rule/extension.ts
2
- import {
3
- defineFacet,
4
- defineFacetPayload,
5
- pluginFacet
6
- } from "@prosekit/core";
7
- import {
8
- PluginKey,
9
- ProseMirrorPlugin
10
- } from "@prosekit/pm/state";
11
-
12
- // src/mark-rule/apply.ts
13
- import {
14
- OBJECT_REPLACEMENT_CHARACTER,
15
- getMarkType,
16
- maybeRun
17
- } from "@prosekit/core";
18
- import "@prosekit/pm/model";
19
- import "@prosekit/pm/state";
20
-
21
- // src/mark-rule/range.ts
22
- import "@prosekit/pm/state";
23
- function getSpanTextRanges($from, $to) {
24
- const nodeRange = $from.blockRange($to);
25
- if (!nodeRange) {
26
- return [];
27
- }
28
- const stack = [];
29
- let start = nodeRange.start;
30
- for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {
31
- const child = nodeRange.parent.child(i);
32
- stack.push([start, child]);
33
- start += child.nodeSize;
34
- }
35
- const ranges = [];
36
- while (stack.length > 0) {
37
- const [start2, node] = stack.pop();
38
- if (node.type.spec.code) {
39
- continue;
40
- }
41
- if (node.type.isTextblock) {
42
- ranges.push([start2 + 1, start2 + 1 + node.content.size]);
43
- continue;
44
- }
45
- node.forEach((child, offset) => {
46
- stack.push([start2 + offset + 1, child]);
47
- });
48
- }
49
- return ranges;
50
- }
51
- function getInlineTextRange($from, $to) {
52
- return [$from.start(), $to.end()];
53
- }
54
- function getTextRanges(doc, from, to) {
55
- const $from = doc.resolve(from);
56
- const $to = doc.resolve(to);
57
- if ($from.sameParent($to) && $from.parent.isTextblock) {
58
- return [getInlineTextRange($from, $to)];
59
- } else {
60
- const nodeRange = $from.blockRange($to);
61
- if (!nodeRange) {
62
- return [];
63
- }
64
- return getSpanTextRanges($from, $to);
65
- }
66
- }
67
- function getMapRange(transactions, oldState, newState) {
68
- let lo = oldState.selection.from;
69
- let hi = oldState.selection.to;
70
- for (const tr of transactions) {
71
- for (const map of tr.mapping.maps) {
72
- lo = map.map(lo);
73
- hi = map.map(hi);
74
- map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
75
- lo = Math.min(lo, hi, newStart);
76
- hi = Math.max(lo, hi, newEnd);
77
- });
78
- }
79
- }
80
- lo = Math.min(lo, hi, newState.selection.from);
81
- hi = Math.min(lo, hi, newState.selection.to);
82
- return [lo, hi];
83
- }
84
- function getCheckRanges(transactions, oldState, newState) {
85
- const [from, to] = getMapRange(transactions, oldState, newState);
86
- return getTextRanges(newState.doc, from, to);
87
- }
88
-
89
- // src/mark-rule/apply.ts
90
- function getExpectedMarkings(rules, doc, from, to) {
91
- const text = doc.textBetween(from, to, null, OBJECT_REPLACEMENT_CHARACTER);
92
- const ranges = [];
93
- for (const rule of rules) {
94
- rule.regex.lastIndex = 0;
95
- const matches = text.matchAll(rule.regex);
96
- const markType = getMarkType(doc.type.schema, rule.type);
97
- for (const match of matches) {
98
- const index = match.index;
99
- if (index == null)
100
- continue;
101
- const attrs = maybeRun(rule.attrs, match);
102
- const mark = markType.create(attrs);
103
- ranges.push([from + index, from + index + match[0].length, mark]);
104
- }
105
- }
106
- ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1]);
107
- const result = [];
108
- let freeIndex = 0;
109
- for (const range of ranges) {
110
- if (range[0] >= freeIndex) {
111
- result.push(range);
112
- freeIndex = range[1];
113
- }
114
- }
115
- return result;
116
- }
117
- function getReceivedMarkings(rules, doc, from, to) {
118
- const result = [];
119
- const schema = doc.type.schema;
120
- const markTypes = rules.map((rule) => getMarkType(schema, rule.type));
121
- doc.nodesBetween(from, to, (node, pos) => {
122
- if (!node.isInline) {
123
- return;
124
- }
125
- for (const markType of markTypes) {
126
- const mark = node.marks.find((mark2) => mark2.type === markType);
127
- if (mark) {
128
- result.push([pos, pos + node.nodeSize, mark]);
129
- }
130
- }
131
- });
132
- return result;
133
- }
134
- function markRangeEquals(a, b) {
135
- return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2]);
136
- }
137
- function markRangeDiffs(a, b) {
138
- return a.filter((x) => !b.some((y) => markRangeEquals(x, y)));
139
- }
140
- function applyMarkRules(rules, transactions, oldState, newState) {
141
- if (transactions.length === 0 || transactions.every((tr2) => !tr2.docChanged)) {
142
- return null;
143
- }
144
- const ranges = getCheckRanges(transactions, oldState, newState);
145
- const toRemove = [];
146
- const toCreate = [];
147
- for (const [from, to] of ranges) {
148
- const expected = getExpectedMarkings(rules, newState.doc, from, to);
149
- const received = getReceivedMarkings(rules, newState.doc, from, to);
150
- toRemove.push(...markRangeDiffs(received, expected));
151
- toCreate.push(...markRangeDiffs(expected, received));
152
- }
153
- if (toCreate.length === 0 && toRemove.length === 0) {
154
- return null;
155
- }
156
- const tr = newState.tr;
157
- for (const [from, to, mark] of toRemove) {
158
- tr.removeMark(from, to, mark);
159
- }
160
- for (const [from, to, mark] of toCreate) {
161
- tr.addMark(from, to, mark);
162
- }
163
- return tr;
164
- }
165
-
166
- // src/mark-rule/extension.ts
167
- function defineMarkRule(options) {
168
- return defineFacetPayload(markRuleFacet, [options]);
169
- }
170
- var markRuleFacet = defineFacet({
171
- reduce: () => {
172
- let rules = [];
173
- const plugin = new ProseMirrorPlugin({
174
- key: new PluginKey("prosekit-mark-rule"),
175
- appendTransaction: (transactions, oldState, newState) => {
176
- return applyMarkRules(rules, transactions, oldState, newState);
177
- }
178
- });
179
- return function reducer(input) {
180
- rules = input;
181
- return plugin;
182
- };
183
- },
184
- parent: pluginFacet
185
- });
186
-
187
- export {
188
- defineMarkRule
189
- };
@@ -1,5 +0,0 @@
1
- // src/code-block/shiki-import.ts
2
- import { getHighlighter } from "shiki/bundle/full";
3
- export {
4
- getHighlighter
5
- };