@prosekit/core 0.4.1 → 0.4.2

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.
@@ -127,6 +127,16 @@ declare interface BaseNodeViewOptions {
127
127
  export { BaseNodeViewOptions }
128
128
  export { BaseNodeViewOptions as BaseNodeViewOptions_alias_1 }
129
129
 
130
+ export declare function baseToggleMark(markType: MarkType, attrs?: Attrs | null, options?: {
131
+ removeWhenPresent: boolean;
132
+ }): Command;
133
+
134
+ export declare function cache<T>(fn: () => T): () => T;
135
+
136
+ declare const canUseRegexLookbehind: () => boolean;
137
+ export { canUseRegexLookbehind }
138
+ export { canUseRegexLookbehind as canUseRegexLookbehind_alias_1 }
139
+
130
140
  declare type ClickHandler = (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
131
141
  export { ClickHandler }
132
142
  export { ClickHandler as ClickHandler_alias_1 }
@@ -1087,9 +1097,21 @@ export { isMark }
1087
1097
  export { isMark as isMark_alias_1 }
1088
1098
 
1089
1099
  /**
1100
+ * Returns true if the given mark is missing in some part of the range.
1101
+ * Returns false if the entire range has the given mark.
1102
+ *
1090
1103
  * @internal
1091
1104
  */
1092
- export declare function isMarkActive(state: EditorState, type: string | MarkType, attrs?: Attrs | null): boolean;
1105
+ declare function isMarkAbsent(node: ProseMirrorNode, from: number, to: number, markType: MarkType, attrs?: Attrs | null): boolean;
1106
+ export { isMarkAbsent }
1107
+ export { isMarkAbsent as isMarkAbsent_alias_1 }
1108
+
1109
+ /**
1110
+ * @internal
1111
+ */
1112
+ declare function isMarkActive(state: EditorState, type: string | MarkType, attrs?: Attrs | null): boolean;
1113
+ export { isMarkActive }
1114
+ export { isMarkActive as isMarkActive_alias_1 }
1093
1115
 
1094
1116
  export declare function isNodeActive(state: EditorState, type: string | NodeType, attrs?: Attrs | null): boolean;
1095
1117
 
@@ -1233,6 +1255,13 @@ declare interface MarkSpecOptions<MarkName extends string = string> extends Mark
1233
1255
  export { MarkSpecOptions }
1234
1256
  export { MarkSpecOptions as MarkSpecOptions_alias_1 }
1235
1257
 
1258
+ /**
1259
+ * @internal
1260
+ */
1261
+ declare function maybeRun<T, R = T extends (...args: any[]) => void ? ReturnType<T> : T>(value: T, ...args: T extends (...args: any[]) => void ? Parameters<T> : never): R;
1262
+ export { maybeRun }
1263
+ export { maybeRun as maybeRun_alias_1 }
1264
+
1236
1265
  /**
1237
1266
  * A function that is called when the editor view is mounted.
1238
1267
  *
@@ -93,12 +93,16 @@ export { SelectionJSON } from './_tsup-dts-rollup';
93
93
  export { StateJSON } from './_tsup-dts-rollup';
94
94
  export { Priority } from './_tsup-dts-rollup';
95
95
  export { SimplifyUnion } from './_tsup-dts-rollup';
96
+ export { canUseRegexLookbehind } from './_tsup-dts-rollup';
96
97
  export { clsx } from './_tsup-dts-rollup';
97
98
  export { defaultBlockAt } from './_tsup-dts-rollup';
98
99
  export { _getId } from './_tsup-dts-rollup';
99
100
  export { getMarkType } from './_tsup-dts-rollup';
100
101
  export { getNodeType } from './_tsup-dts-rollup';
101
102
  export { isInCodeBlock } from './_tsup-dts-rollup';
103
+ export { isMarkAbsent } from './_tsup-dts-rollup';
104
+ export { isMarkActive } from './_tsup-dts-rollup';
105
+ export { maybeRun } from './_tsup-dts-rollup';
102
106
  export { elementFromJSON } from './_tsup-dts-rollup';
103
107
  export { elementFromNode } from './_tsup-dts-rollup';
104
108
  export { htmlFromJSON } from './_tsup-dts-rollup';
@@ -252,19 +252,85 @@ function setNodeAttrs(options) {
252
252
  }
253
253
 
254
254
  // src/commands/toggle-mark.ts
255
- import { toggleMark as baseToggleMark } from "@prosekit/pm/commands";
256
255
  import "@prosekit/pm/model";
257
256
  import "@prosekit/pm/state";
257
+ function markApplies(doc, ranges, type) {
258
+ for (const { $from, $to } of ranges) {
259
+ let can = $from.depth == 0 ? doc.inlineContent && doc.type.allowsMarkType(type) : false;
260
+ doc.nodesBetween($from.pos, $to.pos, (node) => {
261
+ if (can)
262
+ return false;
263
+ can = node.inlineContent && node.type.allowsMarkType(type);
264
+ });
265
+ if (can)
266
+ return true;
267
+ }
268
+ return false;
269
+ }
270
+ function baseToggleMark(markType, attrs = null, options) {
271
+ const removeWhenPresent = (options && options.removeWhenPresent) !== false;
272
+ return function(state, dispatch) {
273
+ const { empty, $cursor, ranges } = state.selection;
274
+ if (empty && !$cursor || !markApplies(state.doc, ranges, markType))
275
+ return false;
276
+ if (dispatch) {
277
+ if ($cursor) {
278
+ if (markType.isInSet(state.storedMarks || $cursor.marks()))
279
+ dispatch(state.tr.removeStoredMark(markType));
280
+ else
281
+ dispatch(state.tr.addStoredMark(markType.create(attrs)));
282
+ } else {
283
+ let add;
284
+ const tr = state.tr;
285
+ if (removeWhenPresent) {
286
+ add = !ranges.some(
287
+ (r) => state.doc.rangeHasMark(r.$from.pos, r.$to.pos, markType)
288
+ );
289
+ } else {
290
+ add = !ranges.every((r) => {
291
+ let missing = false;
292
+ tr.doc.nodesBetween(r.$from.pos, r.$to.pos, (node, pos, parent) => {
293
+ if (missing)
294
+ return false;
295
+ missing = !markType.isInSet(node.marks) && !!parent && parent.type.allowsMarkType(markType) && !(node.isText && /^\s*$/.test(
296
+ node.textBetween(
297
+ Math.max(0, r.$from.pos - pos),
298
+ Math.min(node.nodeSize, r.$to.pos - pos)
299
+ )
300
+ ));
301
+ });
302
+ return !missing;
303
+ });
304
+ }
305
+ for (const { $from, $to } of ranges) {
306
+ if (!add) {
307
+ tr.removeMark($from.pos, $to.pos, markType);
308
+ } else {
309
+ let from = $from.pos, to = $to.pos;
310
+ const start = $from.nodeAfter, end = $to.nodeBefore;
311
+ const spaceStart = start && start.isText ? /^\s*/.exec(start.text)[0].length : 0;
312
+ const spaceEnd = end && end.isText ? /\s*$/.exec(end.text)[0].length : 0;
313
+ if (from + spaceStart < to) {
314
+ from += spaceStart;
315
+ to -= spaceEnd;
316
+ }
317
+ tr.addMark(from, to, markType.create(attrs));
318
+ }
319
+ }
320
+ dispatch(tr.scrollIntoView());
321
+ }
322
+ }
323
+ return true;
324
+ };
325
+ }
258
326
  function toggleMark({
259
327
  type,
260
328
  attrs
261
329
  }) {
262
330
  return (state, dispatch, view) => {
263
- return baseToggleMark(getMarkType(state.schema, type), attrs)(
264
- state,
265
- dispatch,
266
- view
267
- );
331
+ return baseToggleMark(getMarkType(state.schema, type), attrs, {
332
+ removeWhenPresent: false
333
+ })(state, dispatch, view);
268
334
  };
269
335
  }
270
336
 
@@ -792,6 +858,18 @@ function updateExtension(prevInputs, prevConverters, extension, mode) {
792
858
  // src/editor/builder.ts
793
859
  import "@prosekit/pm/model";
794
860
 
861
+ // src/utils/is-mark-absent.ts
862
+ function isMarkAbsent(node, from, to, markType, attrs) {
863
+ const mark = attrs ? markType.create(attrs) : markType;
864
+ let missing = false;
865
+ node.nodesBetween(from, to, (node2, pos, parent) => {
866
+ if (missing)
867
+ return false;
868
+ missing = !mark.isInSet(node2.marks) && !!parent && parent.type.allowsMarkType(markType);
869
+ });
870
+ return missing;
871
+ }
872
+
795
873
  // src/utils/is-mark-active.ts
796
874
  function isMarkActive(state, type, attrs) {
797
875
  const { from, $from, to, empty } = state.selection;
@@ -800,26 +878,25 @@ function isMarkActive(state, type, attrs) {
800
878
  const mark = attrs ? markType.create(attrs) : markType;
801
879
  return !!mark.isInSet(state.storedMarks || $from.marks());
802
880
  } else {
803
- const markOrType = attrs ? markType.create(attrs) : markType;
804
- return state.doc.rangeHasMark(from, to, markOrType);
881
+ return !isMarkAbsent(state.doc, from, to, markType, attrs);
805
882
  }
806
883
  }
807
884
 
808
885
  // src/utils/type-assertion.ts
809
- import { Mark, ProseMirrorNode } from "@prosekit/pm/model";
886
+ import { Mark, ProseMirrorNode as ProseMirrorNode2 } from "@prosekit/pm/model";
810
887
  import {
811
888
  AllSelection,
812
889
  NodeSelection,
813
- TextSelection as TextSelection4
890
+ TextSelection as TextSelection5
814
891
  } from "@prosekit/pm/state";
815
892
  function isProseMirrorNode(node) {
816
- return node instanceof ProseMirrorNode;
893
+ return node instanceof ProseMirrorNode2;
817
894
  }
818
895
  function isMark(mark) {
819
896
  return mark instanceof Mark;
820
897
  }
821
898
  function isTextSelection(sel) {
822
- return sel instanceof TextSelection4;
899
+ return sel instanceof TextSelection5;
823
900
  }
824
901
  function isNodeSelection(sel) {
825
902
  return sel instanceof NodeSelection;
@@ -1931,6 +2008,26 @@ function defineText() {
1931
2008
  });
1932
2009
  }
1933
2010
 
2011
+ // src/utils/cache.ts
2012
+ function cache(fn) {
2013
+ let result = void 0;
2014
+ return () => {
2015
+ if (result === void 0) {
2016
+ result = fn();
2017
+ }
2018
+ return result;
2019
+ };
2020
+ }
2021
+
2022
+ // src/utils/can-use-regex-lookbehind.ts
2023
+ var canUseRegexLookbehind = cache(() => {
2024
+ try {
2025
+ return "ab".replace(new RegExp("(?<=a)b", "g"), "c") === "ac";
2026
+ } catch (error) {
2027
+ return false;
2028
+ }
2029
+ });
2030
+
1934
2031
  // src/utils/clsx.ts
1935
2032
  import clsxLite from "clsx/lite";
1936
2033
  var clsx = clsxLite;
@@ -1960,6 +2057,11 @@ function isInCodeBlock(selection) {
1960
2057
  return isCodeBlockType(selection.$from.parent.type) || isCodeBlockType(selection.$to.parent.type);
1961
2058
  }
1962
2059
 
2060
+ // src/utils/maybe-run.ts
2061
+ function maybeRun(value, ...args) {
2062
+ return typeof value === "function" ? value(...args) : value;
2063
+ }
2064
+
1963
2065
  // src/utils/unicode.ts
1964
2066
  var OBJECT_REPLACEMENT_CHARACTER = "\uFFFC";
1965
2067
 
@@ -1981,6 +2083,7 @@ export {
1981
2083
  ProseKitError,
1982
2084
  getId as _getId,
1983
2085
  addMark,
2086
+ canUseRegexLookbehind,
1984
2087
  clsx,
1985
2088
  createEditor,
1986
2089
  defaultBlockAt,
@@ -2029,6 +2132,8 @@ export {
2029
2132
  isAllSelection,
2030
2133
  isInCodeBlock,
2031
2134
  isMark,
2135
+ isMarkAbsent,
2136
+ isMarkActive,
2032
2137
  isNodeSelection,
2033
2138
  isProseMirrorNode,
2034
2139
  isTextSelection,
@@ -2036,6 +2141,7 @@ export {
2036
2141
  jsonFromNode,
2037
2142
  jsonFromState,
2038
2143
  keymapFacet,
2144
+ maybeRun,
2039
2145
  nodeFromElement,
2040
2146
  nodeFromHTML,
2041
2147
  nodeFromJSON,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.4.1",
4
+ "version": "0.4.2",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",