@domternal/core 0.7.2 → 0.7.4

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.
package/dist/index.d.cts CHANGED
@@ -2745,9 +2745,8 @@ declare function insertChildrenZoneSibling(state: EditorState, dispatch: ((tr: T
2745
2745
  * - `tr` has no prior steps (lift steps captured from a fresh state must
2746
2746
  * replay against the same starting state as `tr`)
2747
2747
  *
2748
- * Returns true if the lift was applied to `tr`. The caller can keep
2749
- * chaining work on `tr` (e.g. `setBlockType`, `wrapIn`) on the new
2750
- * top-level paragraph.
2748
+ * Returns true if a lift was applied to `tr`. The caller can keep chaining
2749
+ * work on `tr` (e.g. `setBlockType`, `wrapIn`) at the new cursor position.
2751
2750
  */
2752
2751
  declare function liftCurrentListItem(state: EditorState, tr: Transaction): boolean;
2753
2752
 
@@ -3039,6 +3038,15 @@ interface WrappingInputRuleOptions {
3039
3038
  * the same type above the newly wrapped node.
3040
3039
  */
3041
3040
  joinPredicate?: (match: RegExpMatchArray, node: Node$1) => boolean;
3041
+ /**
3042
+ * When `true`, also join with an adjacent same-type node AFTER the newly
3043
+ * wrapped node, not just the one before. Lists set this so creating a list
3044
+ * item on a paragraph between two same-type lists merges all three into one
3045
+ * (Notion groups consecutive list items into a single list). Off by default
3046
+ * so wrappers like blockquote, where adjacent blocks stay separate, are
3047
+ * unaffected. Honours `joinPredicate` against the following node.
3048
+ */
3049
+ joinForward?: boolean;
3042
3050
  /**
3043
3051
  * Optional guard predicate. When provided, the rule only fires if
3044
3052
  * this returns true. Use this to prevent wrapping in certain contexts
package/dist/index.d.ts CHANGED
@@ -2745,9 +2745,8 @@ declare function insertChildrenZoneSibling(state: EditorState, dispatch: ((tr: T
2745
2745
  * - `tr` has no prior steps (lift steps captured from a fresh state must
2746
2746
  * replay against the same starting state as `tr`)
2747
2747
  *
2748
- * Returns true if the lift was applied to `tr`. The caller can keep
2749
- * chaining work on `tr` (e.g. `setBlockType`, `wrapIn`) on the new
2750
- * top-level paragraph.
2748
+ * Returns true if a lift was applied to `tr`. The caller can keep chaining
2749
+ * work on `tr` (e.g. `setBlockType`, `wrapIn`) at the new cursor position.
2751
2750
  */
2752
2751
  declare function liftCurrentListItem(state: EditorState, tr: Transaction): boolean;
2753
2752
 
@@ -3039,6 +3038,15 @@ interface WrappingInputRuleOptions {
3039
3038
  * the same type above the newly wrapped node.
3040
3039
  */
3041
3040
  joinPredicate?: (match: RegExpMatchArray, node: Node$1) => boolean;
3041
+ /**
3042
+ * When `true`, also join with an adjacent same-type node AFTER the newly
3043
+ * wrapped node, not just the one before. Lists set this so creating a list
3044
+ * item on a paragraph between two same-type lists merges all three into one
3045
+ * (Notion groups consecutive list items into a single list). Off by default
3046
+ * so wrappers like blockquote, where adjacent blocks stay separate, are
3047
+ * unaffected. Honours `joinPredicate` against the following node.
3048
+ */
3049
+ joinForward?: boolean;
3042
3050
  /**
3043
3051
  * Optional guard predicate. When provided, the rule only fires if
3044
3052
  * this returns true. Use this to prevent wrapping in certain contexts
package/dist/index.js CHANGED
@@ -1125,7 +1125,7 @@ var markInputRulePatterns = {
1125
1125
  highlight: /(?:==)([^=]+)(?:==)$/
1126
1126
  };
1127
1127
  function wrappingInputRule(options) {
1128
- const { find: find2, type, getAttributes = null, joinPredicate, undoable, guard } = options;
1128
+ const { find: find2, type, getAttributes = null, joinPredicate, undoable, guard, joinForward } = options;
1129
1129
  return new InputRule(
1130
1130
  find2,
1131
1131
  (state, match, start, end) => {
@@ -1141,6 +1141,21 @@ function wrappingInputRule(options) {
1141
1141
  if (before?.type === type && canJoin(tr.doc, start - 1) && (!joinPredicate || joinPredicate(match, before))) {
1142
1142
  tr.join(start - 1);
1143
1143
  }
1144
+ if (joinForward) {
1145
+ const $cursor = tr.selection.$from;
1146
+ for (let d = $cursor.depth; d >= 0; d--) {
1147
+ if ($cursor.node(d).type === type) {
1148
+ const after = $cursor.after(d);
1149
+ if (after < tr.doc.content.size && canJoin(tr.doc, after)) {
1150
+ const nodeAfter = tr.doc.nodeAt(after);
1151
+ if (nodeAfter?.type === type && (!joinPredicate || joinPredicate(match, nodeAfter))) {
1152
+ tr.join(after);
1153
+ }
1154
+ }
1155
+ break;
1156
+ }
1157
+ }
1158
+ }
1144
1159
  return tr;
1145
1160
  },
1146
1161
  undoable !== void 0 ? { undoable } : {}
@@ -1961,6 +1976,7 @@ function isInListItemLabel($pos) {
1961
1976
  }
1962
1977
 
1963
1978
  // src/utils/liftCurrentListItem.ts
1979
+ var LIST_ITEM_TYPES = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
1964
1980
  function liftCurrentListItem(state, tr) {
1965
1981
  if (!tr.selection.empty) return false;
1966
1982
  if (tr.steps.length !== 0) return false;
@@ -1968,6 +1984,16 @@ function liftCurrentListItem(state, tr) {
1968
1984
  const listItemDepth = findListItemAncestorDepth($from);
1969
1985
  if (listItemDepth === -1) return false;
1970
1986
  if ($from.index(listItemDepth) !== 0) return false;
1987
+ const wrapperParent = $from.node(listItemDepth - 2);
1988
+ const isNested = LIST_ITEM_TYPES.has(wrapperParent.type.name);
1989
+ if (isNested) {
1990
+ const range = $from.blockRange();
1991
+ if (!range) return false;
1992
+ const target = liftTarget(range);
1993
+ if (target === null) return false;
1994
+ tr.lift(range, target);
1995
+ return true;
1996
+ }
1971
1997
  const listItemType = $from.node(listItemDepth).type;
1972
1998
  return liftListItem(listItemType)(state, (liftTr) => {
1973
1999
  for (const step of liftTr.steps) tr.step(step);
@@ -2175,13 +2201,13 @@ var lift = () => ({ tr, dispatch }) => {
2175
2201
  };
2176
2202
 
2177
2203
  // src/utils/listItemCursorContext.ts
2178
- var LIST_ITEM_TYPES = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
2204
+ var LIST_ITEM_TYPES2 = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
2179
2205
  function getListItemCursorContext($from) {
2180
2206
  if ($from.parent.type.name !== "paragraph") return null;
2181
2207
  const itemDepth = $from.depth - 1;
2182
2208
  if (itemDepth < 1) return null;
2183
2209
  const itemNode = $from.node(itemDepth);
2184
- if (!LIST_ITEM_TYPES.has(itemNode.type.name)) return null;
2210
+ if (!LIST_ITEM_TYPES2.has(itemNode.type.name)) return null;
2185
2211
  const wrapperDepth = itemDepth - 1;
2186
2212
  const childIndex = $from.index(itemDepth);
2187
2213
  return {
@@ -4077,7 +4103,7 @@ function defaultBubbleContexts(editor) {
4077
4103
  }
4078
4104
 
4079
4105
  // src/utils/insertAsListItemChild.ts
4080
- var LIST_ITEM_TYPES2 = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
4106
+ var LIST_ITEM_TYPES3 = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
4081
4107
  var LIST_WRAPPER_TYPES = /* @__PURE__ */ new Set(["bulletList", "orderedList", "taskList"]);
4082
4108
  function insertAsListItemChild(args) {
4083
4109
  const { tr, wrapperPos, targetItemPos, blockNode, sourceRange } = args;
@@ -4090,7 +4116,7 @@ function insertAsListItemChild(args) {
4090
4116
  if (targetItemPos !== void 0) {
4091
4117
  if (targetItemPos < 0 || targetItemPos >= tr.doc.content.size) return { ok: false };
4092
4118
  const candidate = tr.doc.nodeAt(targetItemPos);
4093
- if (!candidate || !LIST_ITEM_TYPES2.has(candidate.type.name)) return { ok: false };
4119
+ if (!candidate || !LIST_ITEM_TYPES3.has(candidate.type.name)) return { ok: false };
4094
4120
  if (targetItemPos < wrapperPos + 1 || targetItemPos >= wrapperPos + wrapper.nodeSize) {
4095
4121
  return { ok: false };
4096
4122
  }
@@ -4098,7 +4124,7 @@ function insertAsListItemChild(args) {
4098
4124
  targetItemStart = targetItemPos;
4099
4125
  } else {
4100
4126
  const last = wrapper.lastChild;
4101
- if (!last || !LIST_ITEM_TYPES2.has(last.type.name)) return { ok: false };
4127
+ if (!last || !LIST_ITEM_TYPES3.has(last.type.name)) return { ok: false };
4102
4128
  let pos = wrapperPos + 1;
4103
4129
  for (let i = 0; i < wrapper.childCount - 1; i++) {
4104
4130
  pos += wrapper.child(i).nodeSize;
@@ -5892,11 +5918,11 @@ var BulletList = Node2.create({
5892
5918
  }
5893
5919
  return [
5894
5920
  // - item
5895
- wrappingInputRule({ find: /^\s*[-]\s$/, type: nodeType, guard: notInsideList }),
5921
+ wrappingInputRule({ find: /^\s*[-]\s$/, type: nodeType, guard: notInsideList, joinForward: true }),
5896
5922
  // * item
5897
- wrappingInputRule({ find: /^\s*[*]\s$/, type: nodeType, guard: notInsideList }),
5923
+ wrappingInputRule({ find: /^\s*[*]\s$/, type: nodeType, guard: notInsideList, joinForward: true }),
5898
5924
  // + item
5899
- wrappingInputRule({ find: /^\s*[+]\s$/, type: nodeType, guard: notInsideList })
5925
+ wrappingInputRule({ find: /^\s*[+]\s$/, type: nodeType, guard: notInsideList, joinForward: true })
5900
5926
  ];
5901
5927
  }
5902
5928
  });
@@ -5997,6 +6023,7 @@ var OrderedList = Node2.create({
5997
6023
  find: /^(\d+)\.\s$/,
5998
6024
  type: nodeType,
5999
6025
  guard: notInsideList,
6026
+ joinForward: true,
6000
6027
  getAttributes: (match) => {
6001
6028
  const num = match[1];
6002
6029
  return { start: num ? parseInt(num, 10) : 1 };
@@ -6526,9 +6553,9 @@ var TaskList = Node2.create({
6526
6553
  }
6527
6554
  return [
6528
6555
  // [ ] at start of line creates unchecked task
6529
- wrappingInputRule({ find: /^\s*\[\s?\]\s$/, type: nodeType, guard: notInsideList }),
6556
+ wrappingInputRule({ find: /^\s*\[\s?\]\s$/, type: nodeType, guard: notInsideList, joinForward: true }),
6530
6557
  // [x] or [X] at start of line creates checked task
6531
- wrappingInputRule({ find: /^\s*\[[xX]\]\s$/, type: nodeType, guard: notInsideList })
6558
+ wrappingInputRule({ find: /^\s*\[[xX]\]\s$/, type: nodeType, guard: notInsideList, joinForward: true })
6532
6559
  ];
6533
6560
  }
6534
6561
  });
@@ -7711,12 +7738,12 @@ var Placeholder = Extension.create({
7711
7738
  ];
7712
7739
  }
7713
7740
  });
7714
- var LIST_ITEM_TYPES3 = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
7741
+ var LIST_ITEM_TYPES4 = /* @__PURE__ */ new Set(["listItem", "taskItem"]);
7715
7742
  var LIST_WRAPPER_TYPES2 = /* @__PURE__ */ new Set(["bulletList", "orderedList", "taskList"]);
7716
7743
  function isCursorInsideListItem(state) {
7717
7744
  const { $from } = state.selection;
7718
7745
  for (let d = $from.depth; d > 0; d--) {
7719
- if (LIST_ITEM_TYPES3.has($from.node(d).type.name)) return true;
7746
+ if (LIST_ITEM_TYPES4.has($from.node(d).type.name)) return true;
7720
7747
  }
7721
7748
  return false;
7722
7749
  }
@@ -7771,7 +7798,7 @@ function outdentBlockFromListItem(state, dispatch) {
7771
7798
  const { $from } = selection;
7772
7799
  let listItemDepth = -1;
7773
7800
  for (let d = $from.depth; d > 0; d--) {
7774
- if (LIST_ITEM_TYPES3.has($from.node(d).type.name)) {
7801
+ if (LIST_ITEM_TYPES4.has($from.node(d).type.name)) {
7775
7802
  listItemDepth = d;
7776
7803
  break;
7777
7804
  }