@domternal/core 0.2.1 → 0.3.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.
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { Selection, TextSelection, PluginKey, Plugin, NodeSelection, AllSelection, EditorState } from '@domternal/pm/state';
1
+ import { Plugin, PluginKey, Selection, TextSelection, NodeSelection, AllSelection, EditorState } from '@domternal/pm/state';
2
2
  export { PluginKey } from '@domternal/pm/state';
3
3
  import { DecorationSet, Decoration, EditorView } from '@domternal/pm/view';
4
4
  import { Slice, Fragment, Schema, Node as Node$1, DOMSerializer, DOMParser } from '@domternal/pm/model';
5
5
  import { keymap } from '@domternal/pm/keymap';
6
- import { textblockTypeInputRule, wrappingInputRule, InputRule, inputRules } from '@domternal/pm/inputrules';
7
6
  import { chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, baseKeymap, selectNodeBackward as selectNodeBackward$1 } from '@domternal/pm/commands';
8
- import { findWrapping, liftTarget } from '@domternal/pm/transform';
7
+ import { InputRule } from '@domternal/pm/inputrules';
8
+ import { findWrapping, canJoin, liftTarget } from '@domternal/pm/transform';
9
9
  import { liftListItem, sinkListItem, splitListItem, wrapRangeInList } from '@domternal/pm/schema-list';
10
10
  import { offset, flip, shift, autoUpdate, hide, computePosition } from '@floating-ui/dom';
11
11
  import { find } from 'linkifyjs';
@@ -108,6 +108,112 @@ var EventEmitter = class {
108
108
  return Array.from(this.callbacks.keys());
109
109
  }
110
110
  };
111
+ var MAX_MATCH = 500;
112
+ function run(view, from, to, text, rules, plugin) {
113
+ if (view.composing) return false;
114
+ const state = view.state;
115
+ const $from = state.doc.resolve(from);
116
+ const textBefore = $from.parent.textBetween(
117
+ Math.max(0, $from.parentOffset - MAX_MATCH),
118
+ $from.parentOffset,
119
+ null,
120
+ "\uFFFC"
121
+ ) + text;
122
+ for (const rawRule of rules) {
123
+ const rule = rawRule;
124
+ if (!rule.inCodeMark && $from.marks().some((m) => m.type.spec.code)) continue;
125
+ if ($from.parent.type.spec.code) {
126
+ if (!rule.inCode) continue;
127
+ } else if (rule.inCode === "only") {
128
+ continue;
129
+ }
130
+ const match = rule.match.exec(textBefore);
131
+ if (!match || match[0].length < text.length) continue;
132
+ const startPos = from - (match[0].length - text.length);
133
+ if (!rule.inCodeMark) {
134
+ const codeMarks = [];
135
+ state.doc.nodesBetween(startPos, $from.pos, (node) => {
136
+ if (node.isInline && node.marks.some((m) => m.type.spec.code)) codeMarks.push(true);
137
+ });
138
+ if (codeMarks.length > 0) continue;
139
+ }
140
+ const tr = rule.handler(state, match, startPos, to);
141
+ if (!tr) continue;
142
+ if (rule.undoable) {
143
+ tr.setMeta(plugin, { transform: tr, from, to, text });
144
+ }
145
+ view.dispatch(tr);
146
+ return true;
147
+ }
148
+ return false;
149
+ }
150
+ function undoInputRule(plugin, state, dispatch) {
151
+ const undoable = plugin.getState(state);
152
+ if (!undoable) return false;
153
+ if (dispatch) {
154
+ const tr = state.tr;
155
+ const toUndo = undoable.transform;
156
+ for (let j = toUndo.steps.length - 1; j >= 0; j--) {
157
+ const step = toUndo.steps[j];
158
+ const doc = toUndo.docs[j];
159
+ if (step && doc) tr.step(step.invert(doc));
160
+ }
161
+ if (undoable.text) {
162
+ const marks = tr.doc.resolve(undoable.from).marks();
163
+ tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks));
164
+ const endPos = undoable.from + undoable.text.length;
165
+ if (endPos <= tr.doc.content.size) {
166
+ tr.setSelection(TextSelection.create(tr.doc, endPos));
167
+ }
168
+ } else {
169
+ tr.delete(undoable.from, undoable.to);
170
+ }
171
+ dispatch(tr);
172
+ }
173
+ return true;
174
+ }
175
+ function inputRulesPlugin({ rules }) {
176
+ const plugin = new Plugin({
177
+ state: {
178
+ init() {
179
+ return null;
180
+ },
181
+ apply(tr, prev) {
182
+ const stored = tr.getMeta(plugin);
183
+ if (stored) return stored;
184
+ if (tr.getMeta("appendedTransaction")) return prev;
185
+ return tr.selectionSet || tr.docChanged ? null : prev;
186
+ }
187
+ },
188
+ props: {
189
+ handleTextInput(view, from, to, text) {
190
+ return run(view, from, to, text, rules, plugin);
191
+ },
192
+ handleKeyDown(view, event) {
193
+ if (event.key === "Backspace" && !event.ctrlKey && !event.metaKey && !event.altKey) {
194
+ return undoInputRule(plugin, view.state, (tr) => {
195
+ view.dispatch(tr);
196
+ });
197
+ }
198
+ return false;
199
+ },
200
+ handleDOMEvents: {
201
+ compositionend: (view) => {
202
+ setTimeout(() => {
203
+ const { $cursor } = view.state.selection;
204
+ if ($cursor) {
205
+ run(view, $cursor.pos, $cursor.pos, "", rules, plugin);
206
+ }
207
+ });
208
+ }
209
+ }
210
+ },
211
+ // Tag so external undoInputRule can also find this plugin
212
+ isInputRules: true
213
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
214
+ });
215
+ return plugin;
216
+ }
111
217
 
112
218
  // src/helpers/callOrReturn.ts
113
219
  function callOrReturn(value, context, ...args) {
@@ -485,14 +591,14 @@ var ExtensionManager = class {
485
591
  */
486
592
  buildPlugins() {
487
593
  const plugins = [];
594
+ const rules = this.collectInputRules();
595
+ if (rules.length > 0) {
596
+ plugins.push(inputRulesPlugin({ rules }));
597
+ }
488
598
  const shortcuts = this.collectKeyboardShortcuts();
489
599
  if (Object.keys(shortcuts).length > 0) {
490
600
  plugins.push(keymap(shortcuts));
491
601
  }
492
- const rules = this.collectInputRules();
493
- if (rules.length > 0) {
494
- plugins.push(inputRules({ rules }));
495
- }
496
602
  for (const ext of this._extensions) {
497
603
  const addPlugins = ext.config.addProseMirrorPlugins;
498
604
  if (addPlugins) {
@@ -935,7 +1041,7 @@ function isDocumentEmpty(doc) {
935
1041
  });
936
1042
  }
937
1043
  function markInputRule(options) {
938
- const { find: find2, type, getAttributes } = options;
1044
+ const { find: find2, type, getAttributes, undoable } = options;
939
1045
  return new InputRule(
940
1046
  find2,
941
1047
  (state, match, start, end) => {
@@ -952,7 +1058,8 @@ function markInputRule(options) {
952
1058
  tr.addMark(start, start + textContent.length, type.create(attributes ?? void 0));
953
1059
  tr.removeStoredMark(type);
954
1060
  return tr;
955
- }
1061
+ },
1062
+ undoable !== void 0 ? { undoable } : {}
956
1063
  );
957
1064
  }
958
1065
  var markInputRulePatterns = {
@@ -977,6 +1084,69 @@ var markInputRulePatterns = {
977
1084
  */
978
1085
  highlight: /(?:==)([^=]+)(?:==)$/
979
1086
  };
1087
+ function wrappingInputRule(options) {
1088
+ const { find: find2, type, getAttributes = null, joinPredicate, undoable, guard } = options;
1089
+ return new InputRule(
1090
+ find2,
1091
+ (state, match, start, end) => {
1092
+ if (guard && !guard(state)) return null;
1093
+ const attrs = getAttributes instanceof Function ? getAttributes(match) : getAttributes;
1094
+ const tr = state.tr.delete(start, end);
1095
+ const $start = tr.doc.resolve(start);
1096
+ const range = $start.blockRange();
1097
+ const wrapping = range && findWrapping(range, type, attrs);
1098
+ if (!wrapping) return null;
1099
+ tr.wrap(range, wrapping);
1100
+ const before = tr.doc.resolve(start - 1).nodeBefore;
1101
+ if (before?.type === type && canJoin(tr.doc, start - 1) && (!joinPredicate || joinPredicate(match, before))) {
1102
+ tr.join(start - 1);
1103
+ }
1104
+ return tr;
1105
+ },
1106
+ undoable !== void 0 ? { undoable } : {}
1107
+ );
1108
+ }
1109
+ function notInsideList(state) {
1110
+ const { $from } = state.selection;
1111
+ for (let d = $from.depth; d > 0; d--) {
1112
+ const name = $from.node(d).type.name;
1113
+ if (name === "listItem" || name === "taskItem") return false;
1114
+ }
1115
+ return true;
1116
+ }
1117
+ function textblockTypeInputRule(options) {
1118
+ const { find: find2, type, getAttributes = null, undoable } = options;
1119
+ return new InputRule(
1120
+ find2,
1121
+ (state, match, start, end) => {
1122
+ const $start = state.doc.resolve(start);
1123
+ const attrs = getAttributes instanceof Function ? getAttributes(match) : getAttributes;
1124
+ if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), type)) return null;
1125
+ return state.tr.delete(start, end).setBlockType(start, start, type, attrs);
1126
+ },
1127
+ undoable !== void 0 ? { undoable } : {}
1128
+ );
1129
+ }
1130
+ function textInputRule(options) {
1131
+ const { find: find2, replace, undoable } = options;
1132
+ return new InputRule(
1133
+ find2,
1134
+ (state, _match, start, end) => state.tr.replaceWith(start, end, state.schema.text(replace)),
1135
+ undoable !== void 0 ? { undoable } : {}
1136
+ );
1137
+ }
1138
+ function nodeInputRule(options) {
1139
+ const { find: find2, type, getAttributes = null, undoable } = options;
1140
+ return new InputRule(
1141
+ find2,
1142
+ (state, match, start, end) => {
1143
+ const attrs = getAttributes instanceof Function ? getAttributes(match, state) : getAttributes;
1144
+ if (getAttributes instanceof Function && attrs === null) return null;
1145
+ return state.tr.replaceWith(start, end, type.create(attrs));
1146
+ },
1147
+ undoable !== void 0 ? { undoable } : {}
1148
+ );
1149
+ }
980
1150
 
981
1151
  // src/helpers/isValidUrl.ts
982
1152
  function isValidUrl(url, options = {}) {
@@ -1865,8 +2035,18 @@ var toggleWrap = (nodeName, attributes) => (props) => {
1865
2035
  const allWrapped = contentBlocks.length > 0 ? contentBlocks.every(({ pos }) => isInsideWrap(pos)) : isInsideWrap(from);
1866
2036
  if (allWrapped) {
1867
2037
  const first = contentBlocks[0];
1868
- if (first) {
1869
- tr.setSelection(TextSelection.create(tr.doc, first.pos + 1));
2038
+ const last = contentBlocks[contentBlocks.length - 1];
2039
+ if (first && last) {
2040
+ const $liftFrom = tr.doc.resolve(first.pos + 1);
2041
+ const $liftTo = tr.doc.resolve(last.pos + 1);
2042
+ const range = $liftFrom.blockRange($liftTo);
2043
+ if (!range) return false;
2044
+ const target = liftTarget(range);
2045
+ if (target === null) return false;
2046
+ if (!dispatch) return true;
2047
+ tr.lift(range, target).scrollIntoView();
2048
+ dispatch(tr);
2049
+ return true;
1870
2050
  }
1871
2051
  return lift()(props);
1872
2052
  }
@@ -1900,6 +2080,36 @@ var lift = () => ({ tr, dispatch }) => {
1900
2080
  dispatch(tr);
1901
2081
  return true;
1902
2082
  };
2083
+ function joinListBackwards(tr, listType) {
2084
+ const { $from } = tr.selection;
2085
+ for (let d = $from.depth; d >= 0; d--) {
2086
+ if ($from.node(d).type === listType) {
2087
+ const listPos = $from.before(d);
2088
+ if (listPos > 0 && canJoin(tr.doc, listPos)) {
2089
+ const nodeBefore = tr.doc.resolve(listPos - 1).parent;
2090
+ if (nodeBefore.type === listType) {
2091
+ tr.join(listPos);
2092
+ }
2093
+ }
2094
+ return;
2095
+ }
2096
+ }
2097
+ }
2098
+ function joinListForwards(tr, listType) {
2099
+ const { $from } = tr.selection;
2100
+ for (let d = $from.depth; d >= 0; d--) {
2101
+ if ($from.node(d).type === listType) {
2102
+ const after = $from.after(d);
2103
+ if (after < tr.doc.content.size && canJoin(tr.doc, after)) {
2104
+ const nodeAfter = tr.doc.nodeAt(after);
2105
+ if (nodeAfter?.type === listType) {
2106
+ tr.join(after);
2107
+ }
2108
+ }
2109
+ return;
2110
+ }
2111
+ }
2112
+ }
1903
2113
  var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, dispatch }) => {
1904
2114
  const listType = state.schema.nodes[listNodeName];
1905
2115
  const listItemType = state.schema.nodes[listItemNodeName];
@@ -2055,11 +2265,56 @@ var toggleList = (listNodeName, listItemNodeName, attributes) => ({ state, tr, d
2055
2265
  dispatch(tr);
2056
2266
  return true;
2057
2267
  }
2058
- const { $from: $wrapFrom, $to: $wrapTo } = tr.selection;
2268
+ const blocksInList = contentBlocks.filter((b) => b.inSomeList);
2269
+ if (blocksInList.length === 0) {
2270
+ const { $from: $wf, $to: $wt } = tr.selection;
2271
+ const wr = $wf.blockRange($wt);
2272
+ if (!wr) return false;
2273
+ if (!wrapRangeInList(dispatch ? tr : null, wr, listType, attributes)) return false;
2274
+ if (dispatch) {
2275
+ joinListBackwards(tr, listType);
2276
+ joinListForwards(tr, listType);
2277
+ dispatch(tr.scrollIntoView());
2278
+ }
2279
+ return true;
2280
+ }
2281
+ if (!dispatch) return true;
2282
+ const seen = /* @__PURE__ */ new Set();
2283
+ const listPositions = [];
2284
+ for (const block of blocksInList) {
2285
+ const $pos = tr.doc.resolve(block.pos);
2286
+ for (let d = $pos.depth; d >= 0; d--) {
2287
+ const groups = ($pos.node(d).type.spec.group ?? "").split(/\s+/);
2288
+ if (groups.includes("list")) {
2289
+ const lpos = $pos.before(d);
2290
+ if (!seen.has(lpos)) {
2291
+ seen.add(lpos);
2292
+ listPositions.push(lpos);
2293
+ }
2294
+ break;
2295
+ }
2296
+ }
2297
+ }
2298
+ listPositions.sort((a, b) => b - a);
2299
+ for (const pos of listPositions) {
2300
+ const listNode = tr.doc.nodeAt(pos);
2301
+ if (!listNode) continue;
2302
+ const children = [];
2303
+ listNode.forEach((item) => {
2304
+ item.forEach((child) => children.push(child));
2305
+ });
2306
+ tr.replaceWith(pos, pos + listNode.nodeSize, children);
2307
+ }
2308
+ const mappedFrom = tr.mapping.map(from, -1);
2309
+ const mappedTo = tr.mapping.map(to, 1);
2310
+ const $wrapFrom = tr.doc.resolve(mappedFrom);
2311
+ const $wrapTo = tr.doc.resolve(mappedTo);
2059
2312
  const wrapRange = $wrapFrom.blockRange($wrapTo);
2060
2313
  if (!wrapRange) return false;
2061
- if (!wrapRangeInList(dispatch ? tr : null, wrapRange, listType, attributes)) return false;
2062
- if (dispatch) dispatch(tr.scrollIntoView());
2314
+ wrapRangeInList(tr, wrapRange, listType, attributes);
2315
+ joinListBackwards(tr, listType);
2316
+ joinListForwards(tr, listType);
2317
+ dispatch(tr.scrollIntoView());
2063
2318
  return true;
2064
2319
  };
2065
2320
 
@@ -4408,7 +4663,32 @@ var Heading = Node.create({
4408
4663
  ];
4409
4664
  },
4410
4665
  addProseMirrorPlugins() {
4666
+ const { options, editor } = this;
4667
+ const codeToLevel = {};
4668
+ for (const level of options.levels) {
4669
+ codeToLevel[`Digit${String(level)}`] = level;
4670
+ }
4671
+ codeToLevel["Digit0"] = 0;
4411
4672
  return [
4673
+ new Plugin({
4674
+ key: new PluginKey("headingKeydownFix"),
4675
+ props: {
4676
+ handleDOMEvents: {
4677
+ keydown(_view, event) {
4678
+ if (!event.altKey || !(event.metaKey || event.ctrlKey)) return false;
4679
+ const level = codeToLevel[event.code];
4680
+ if (level === void 0) return false;
4681
+ event.preventDefault();
4682
+ if (level === 0) {
4683
+ editor?.commands["setParagraph"]?.();
4684
+ } else {
4685
+ editor?.commands["toggleHeading"]?.({ level });
4686
+ }
4687
+ return true;
4688
+ }
4689
+ }
4690
+ }
4691
+ }),
4412
4692
  keymap({
4413
4693
  Backspace: ((state, dispatch) => {
4414
4694
  const { selection } = state;
@@ -4435,10 +4715,10 @@ var Heading = Node.create({
4435
4715
  }
4436
4716
  const maxLevel = Math.max(...options.levels);
4437
4717
  return [
4438
- textblockTypeInputRule(
4439
- new RegExp(`^(#{1,${String(maxLevel)}})\\s$`),
4440
- nodeType,
4441
- (match) => {
4718
+ textblockTypeInputRule({
4719
+ find: new RegExp(`^(#{1,${String(maxLevel)}})\\s$`),
4720
+ type: nodeType,
4721
+ getAttributes: (match) => {
4442
4722
  const hashes = match[1];
4443
4723
  if (!hashes) {
4444
4724
  return null;
@@ -4449,10 +4729,12 @@ var Heading = Node.create({
4449
4729
  }
4450
4730
  return { level };
4451
4731
  }
4452
- )
4732
+ })
4453
4733
  ];
4454
4734
  }
4455
4735
  });
4736
+
4737
+ // src/nodes/Blockquote.ts
4456
4738
  var Blockquote = Node.create({
4457
4739
  name: "blockquote",
4458
4740
  group: "block",
@@ -4512,7 +4794,7 @@ var Blockquote = Node.create({
4512
4794
  return [];
4513
4795
  }
4514
4796
  return [
4515
- wrappingInputRule(/^\s*>\s$/, nodeType)
4797
+ wrappingInputRule({ find: /^\s*>\s$/, type: nodeType })
4516
4798
  ];
4517
4799
  }
4518
4800
  });
@@ -4642,14 +4924,14 @@ var CodeBlock = Node.create({
4642
4924
  return [];
4643
4925
  }
4644
4926
  return [
4645
- textblockTypeInputRule(
4646
- /^```([a-z]*)?[\s\n]$/,
4647
- nodeType,
4648
- (match) => {
4927
+ textblockTypeInputRule({
4928
+ find: /^```([a-z]*)?[\s\n]$/,
4929
+ type: nodeType,
4930
+ getAttributes: (match) => {
4649
4931
  const language = match[1] ?? null;
4650
4932
  return { language };
4651
4933
  }
4652
- )
4934
+ })
4653
4935
  ];
4654
4936
  }
4655
4937
  });
@@ -4833,14 +5115,16 @@ var BulletList = Node.create({
4833
5115
  }
4834
5116
  return [
4835
5117
  // - item
4836
- wrappingInputRule(/^\s*[-]\s$/, nodeType),
5118
+ wrappingInputRule({ find: /^\s*[-]\s$/, type: nodeType, guard: notInsideList }),
4837
5119
  // * item
4838
- wrappingInputRule(/^\s*[*]\s$/, nodeType),
5120
+ wrappingInputRule({ find: /^\s*[*]\s$/, type: nodeType, guard: notInsideList }),
4839
5121
  // + item
4840
- wrappingInputRule(/^\s*[+]\s$/, nodeType)
5122
+ wrappingInputRule({ find: /^\s*[+]\s$/, type: nodeType, guard: notInsideList })
4841
5123
  ];
4842
5124
  }
4843
5125
  });
5126
+
5127
+ // src/nodes/OrderedList.ts
4844
5128
  var OrderedList = Node.create({
4845
5129
  name: "orderedList",
4846
5130
  group: "block list",
@@ -4916,14 +5200,15 @@ var OrderedList = Node.create({
4916
5200
  }
4917
5201
  return [
4918
5202
  // 1. item (any number followed by . )
4919
- wrappingInputRule(
4920
- /^(\d+)\.\s$/,
4921
- nodeType,
4922
- (match) => {
5203
+ wrappingInputRule({
5204
+ find: /^(\d+)\.\s$/,
5205
+ type: nodeType,
5206
+ guard: notInsideList,
5207
+ getAttributes: (match) => {
4923
5208
  const num = match[1];
4924
5209
  return { start: num ? parseInt(num, 10) : 1 };
4925
5210
  }
4926
- )
5211
+ })
4927
5212
  ];
4928
5213
  }
4929
5214
  });
@@ -4998,13 +5283,12 @@ var HorizontalRule = Node.create({
4998
5283
  const $start = state.doc.resolve(start);
4999
5284
  const from = $start.before();
5000
5285
  const to = $start.after();
5001
- tr.replaceWith(from, to, nodeType.create());
5002
- if (from + 1 < tr.doc.content.size) {
5003
- const $after = tr.doc.resolve(from + 1);
5004
- const sel = TextSelection.findFrom($after, 1);
5005
- if (sel) {
5006
- tr.setSelection(sel);
5007
- }
5286
+ const paragraph = state.schema.nodes["paragraph"]?.create();
5287
+ const nodes = paragraph ? [nodeType.create(), paragraph] : [nodeType.create()];
5288
+ tr.replaceWith(from, to, nodes);
5289
+ const sel = TextSelection.findFrom(tr.doc.resolve(from + 1), 1);
5290
+ if (sel) {
5291
+ tr.setSelection(sel);
5008
5292
  }
5009
5293
  }
5010
5294
  return tr;
@@ -5295,9 +5579,9 @@ var TaskList = Node.create({
5295
5579
  }
5296
5580
  return [
5297
5581
  // [ ] at start of line creates unchecked task
5298
- wrappingInputRule(/^\s*\[\s?\]\s$/, nodeType),
5582
+ wrappingInputRule({ find: /^\s*\[\s?\]\s$/, type: nodeType, guard: notInsideList }),
5299
5583
  // [x] or [X] at start of line creates checked task
5300
- wrappingInputRule(/^\s*\[[xX]\]\s$/, nodeType)
5584
+ wrappingInputRule({ find: /^\s*\[[xX]\]\s$/, type: nodeType, guard: notInsideList })
5301
5585
  ];
5302
5586
  }
5303
5587
  });
@@ -6595,40 +6879,39 @@ var Typography = Extension.create({
6595
6879
  },
6596
6880
  addInputRules() {
6597
6881
  const rules = [];
6598
- const textReplace = (find2, replacement) => new InputRule(find2, (state, _match, start, end) => state.tr.replaceWith(start, end, state.schema.text(replacement)));
6599
6882
  if (this.options.emDash) {
6600
- rules.push(textReplace(/--$/, "\u2014"));
6883
+ rules.push(textInputRule({ find: /--$/, replace: "\u2014" }));
6601
6884
  }
6602
6885
  if (this.options.ellipsis) {
6603
- rules.push(textReplace(/\.\.\.$/, "\u2026"));
6886
+ rules.push(textInputRule({ find: /\.\.\.$/, replace: "\u2026" }));
6604
6887
  }
6605
6888
  if (this.options.arrows) {
6606
- rules.push(textReplace(/<-$/, "\u2190"));
6607
- rules.push(textReplace(/->$/, "\u2192"));
6608
- rules.push(textReplace(/=>$/, "\u21D2"));
6889
+ rules.push(textInputRule({ find: /<-$/, replace: "\u2190" }));
6890
+ rules.push(textInputRule({ find: /->$/, replace: "\u2192" }));
6891
+ rules.push(textInputRule({ find: /=>$/, replace: "\u21D2" }));
6609
6892
  }
6610
6893
  if (this.options.fractions) {
6611
- rules.push(textReplace(/1\/2$/, "\xBD"));
6612
- rules.push(textReplace(/1\/4$/, "\xBC"));
6613
- rules.push(textReplace(/3\/4$/, "\xBE"));
6614
- rules.push(textReplace(/1\/3$/, "\u2153"));
6615
- rules.push(textReplace(/2\/3$/, "\u2154"));
6894
+ rules.push(textInputRule({ find: /1\/2$/, replace: "\xBD" }));
6895
+ rules.push(textInputRule({ find: /1\/4$/, replace: "\xBC" }));
6896
+ rules.push(textInputRule({ find: /3\/4$/, replace: "\xBE" }));
6897
+ rules.push(textInputRule({ find: /1\/3$/, replace: "\u2153" }));
6898
+ rules.push(textInputRule({ find: /2\/3$/, replace: "\u2154" }));
6616
6899
  }
6617
6900
  if (this.options.symbols) {
6618
- rules.push(textReplace(/\(c\)$/i, "\xA9"));
6619
- rules.push(textReplace(/\(r\)$/i, "\xAE"));
6620
- rules.push(textReplace(/\(tm\)$/i, "\u2122"));
6621
- rules.push(textReplace(/\(sm\)$/i, "\u2120"));
6901
+ rules.push(textInputRule({ find: /\(c\)$/i, replace: "\xA9" }));
6902
+ rules.push(textInputRule({ find: /\(r\)$/i, replace: "\xAE" }));
6903
+ rules.push(textInputRule({ find: /\(tm\)$/i, replace: "\u2122" }));
6904
+ rules.push(textInputRule({ find: /\(sm\)$/i, replace: "\u2120" }));
6622
6905
  }
6623
6906
  if (this.options.math) {
6624
- rules.push(textReplace(/\+\/-$/, "\xB1"));
6625
- rules.push(textReplace(/!=$/, "\u2260"));
6626
- rules.push(textReplace(/<=$/, "\u2264"));
6627
- rules.push(textReplace(/>=$/, "\u2265"));
6907
+ rules.push(textInputRule({ find: /\+\/-$/, replace: "\xB1" }));
6908
+ rules.push(textInputRule({ find: /!=$/, replace: "\u2260" }));
6909
+ rules.push(textInputRule({ find: /<=$/, replace: "\u2264" }));
6910
+ rules.push(textInputRule({ find: />=$/, replace: "\u2265" }));
6628
6911
  }
6629
6912
  if (this.options.guillemets) {
6630
- rules.push(textReplace(/<<$/, "\xAB"));
6631
- rules.push(textReplace(/>>$/, "\xBB"));
6913
+ rules.push(textInputRule({ find: /<<$/, replace: "\xAB" }));
6914
+ rules.push(textInputRule({ find: />>$/, replace: "\xBB" }));
6632
6915
  }
6633
6916
  if (this.options.smartQuotes) {
6634
6917
  const { openDoubleQuote, closeDoubleQuote, openSingleQuote, closeSingleQuote } = this.options;
@@ -7865,11 +8148,13 @@ function linkPopoverPlugin({ editor, markType, protocols }) {
7865
8148
  applyBtn.type = "button";
7866
8149
  applyBtn.className = "dm-link-popover-btn dm-link-popover-apply";
7867
8150
  applyBtn.title = "Apply link";
8151
+ applyBtn.setAttribute("aria-label", "Apply link");
7868
8152
  applyBtn.innerHTML = defaultIcons["check"] ?? "";
7869
8153
  const removeBtn = document.createElement("button");
7870
8154
  removeBtn.type = "button";
7871
8155
  removeBtn.className = "dm-link-popover-btn dm-link-popover-remove";
7872
8156
  removeBtn.title = "Remove link";
8157
+ removeBtn.setAttribute("aria-label", "Remove link");
7873
8158
  removeBtn.innerHTML = defaultIcons["linkBreak"] ?? "";
7874
8159
  el.appendChild(input);
7875
8160
  el.appendChild(applyBtn);
@@ -8527,6 +8812,6 @@ var StarterKit = Extension.create({
8527
8812
  // src/index.ts
8528
8813
  var VERSION = "0.1.0";
8529
8814
 
8530
- export { BaseKeymap, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FloatingMenu, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LineHeight, Link, LinkPopover, ListItem, ListKeymap, Mark, Node, OrderedList, Paragraph, Placeholder, Selection3 as Selection, SelectionDecoration, StarterKit, Strike, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign, TextColor, TextStyle, ToolbarController, TrailingNode, Typography, Underline, UniqueID, VERSION, applyInlineStyles, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultIcons, deleteSelection, findChildren, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getMarkRange, inlineStyles, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isNodeEmpty, isValidUrl, lift, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn };
8815
+ export { BaseKeymap, Blockquote, Bold, BubbleMenu, BulletList, CanChecker, ChainBuilder, CharacterCount, ClearFormatting, Code, CodeBlock, CommandManager, DEFAULT_HIGHLIGHT_COLORS, DEFAULT_TEXT_COLORS, Document, Dropcursor, Editor, EventEmitter, Extension, ExtensionManager, FloatingMenu, Focus, FontFamily, FontSize, Gapcursor, HardBreak, Heading, Highlight, History, HorizontalRule, InvisibleChars, Italic, LineHeight, Link, LinkPopover, ListItem, ListKeymap, Mark, Node, OrderedList, Paragraph, Placeholder, Selection3 as Selection, SelectionDecoration, StarterKit, Strike, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign, TextColor, TextStyle, ToolbarController, TrailingNode, Typography, Underline, UniqueID, VERSION, applyInlineStyles, autolinkPlugin, autolinkPluginKey, blur, bubbleMenuPluginKey, buildCommandProps, builtInCommands, callOrReturn, characterCountPluginKey, clearContent, createAccumulatingDispatch, createBubbleMenuPlugin, createCanChecker, createChainBuilder, createDocument, createFloatingMenuPlugin, defaultBlockAt, defaultIcons, deleteSelection, findChildren, findParentNode, floatingMenuPluginKey, focus, focusPluginKey, generateHTML, generateJSON, generateText, getMarkRange, inlineStyles, insertContent, insertText, invisibleCharsPluginKey, isDocumentEmpty, isNodeEmpty, isValidUrl, lift, linkClickPlugin, linkClickPluginKey, linkExitPlugin, linkExitPluginKey, linkPastePlugin, linkPastePluginKey, markInputRule, markInputRulePatterns, nodeInputRule, placeholderPluginKey, positionFloating, positionFloatingOnce, resetAttributes, selectAll, selectNodeBackward, selectionDecorationPluginKey, setBlockType, setContent, setMark, textInputRule, textblockTypeInputRule, toggleBlockType, toggleList, toggleMark, toggleWrap, uniqueIDPluginKey, unsetAllMarks, unsetMark, updateAttributes, wrapIn, wrappingInputRule };
8531
8816
  //# sourceMappingURL=index.js.map
8532
8817
  //# sourceMappingURL=index.js.map