@domternal/core 0.2.0 → 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;
@@ -5046,6 +5330,20 @@ var HardBreak = Node.create({
5046
5330
  }
5047
5331
  };
5048
5332
  },
5333
+ addToolbarItems() {
5334
+ return [
5335
+ {
5336
+ type: "button",
5337
+ name: "hardBreak",
5338
+ command: "setHardBreak",
5339
+ icon: "linkBreak",
5340
+ label: "Hard Break",
5341
+ shortcut: "Shift-Enter",
5342
+ group: "insert",
5343
+ priority: 50
5344
+ }
5345
+ ];
5346
+ },
5049
5347
  addKeyboardShortcuts() {
5050
5348
  const { editor } = this;
5051
5349
  return {
@@ -5281,9 +5579,9 @@ var TaskList = Node.create({
5281
5579
  }
5282
5580
  return [
5283
5581
  // [ ] at start of line creates unchecked task
5284
- wrappingInputRule(/^\s*\[\s?\]\s$/, nodeType),
5582
+ wrappingInputRule({ find: /^\s*\[\s?\]\s$/, type: nodeType, guard: notInsideList }),
5285
5583
  // [x] or [X] at start of line creates checked task
5286
- wrappingInputRule(/^\s*\[[xX]\]\s$/, nodeType)
5584
+ wrappingInputRule({ find: /^\s*\[[xX]\]\s$/, type: nodeType, guard: notInsideList })
5287
5585
  ];
5288
5586
  }
5289
5587
  });
@@ -6581,40 +6879,39 @@ var Typography = Extension.create({
6581
6879
  },
6582
6880
  addInputRules() {
6583
6881
  const rules = [];
6584
- const textReplace = (find2, replacement) => new InputRule(find2, (state, _match, start, end) => state.tr.replaceWith(start, end, state.schema.text(replacement)));
6585
6882
  if (this.options.emDash) {
6586
- rules.push(textReplace(/--$/, "\u2014"));
6883
+ rules.push(textInputRule({ find: /--$/, replace: "\u2014" }));
6587
6884
  }
6588
6885
  if (this.options.ellipsis) {
6589
- rules.push(textReplace(/\.\.\.$/, "\u2026"));
6886
+ rules.push(textInputRule({ find: /\.\.\.$/, replace: "\u2026" }));
6590
6887
  }
6591
6888
  if (this.options.arrows) {
6592
- rules.push(textReplace(/<-$/, "\u2190"));
6593
- rules.push(textReplace(/->$/, "\u2192"));
6594
- 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" }));
6595
6892
  }
6596
6893
  if (this.options.fractions) {
6597
- rules.push(textReplace(/1\/2$/, "\xBD"));
6598
- rules.push(textReplace(/1\/4$/, "\xBC"));
6599
- rules.push(textReplace(/3\/4$/, "\xBE"));
6600
- rules.push(textReplace(/1\/3$/, "\u2153"));
6601
- 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" }));
6602
6899
  }
6603
6900
  if (this.options.symbols) {
6604
- rules.push(textReplace(/\(c\)$/i, "\xA9"));
6605
- rules.push(textReplace(/\(r\)$/i, "\xAE"));
6606
- rules.push(textReplace(/\(tm\)$/i, "\u2122"));
6607
- 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" }));
6608
6905
  }
6609
6906
  if (this.options.math) {
6610
- rules.push(textReplace(/\+\/-$/, "\xB1"));
6611
- rules.push(textReplace(/!=$/, "\u2260"));
6612
- rules.push(textReplace(/<=$/, "\u2264"));
6613
- 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" }));
6614
6911
  }
6615
6912
  if (this.options.guillemets) {
6616
- rules.push(textReplace(/<<$/, "\xAB"));
6617
- rules.push(textReplace(/>>$/, "\xBB"));
6913
+ rules.push(textInputRule({ find: /<<$/, replace: "\xAB" }));
6914
+ rules.push(textInputRule({ find: />>$/, replace: "\xBB" }));
6618
6915
  }
6619
6916
  if (this.options.smartQuotes) {
6620
6917
  const { openDoubleQuote, closeDoubleQuote, openSingleQuote, closeSingleQuote } = this.options;
@@ -7851,11 +8148,13 @@ function linkPopoverPlugin({ editor, markType, protocols }) {
7851
8148
  applyBtn.type = "button";
7852
8149
  applyBtn.className = "dm-link-popover-btn dm-link-popover-apply";
7853
8150
  applyBtn.title = "Apply link";
8151
+ applyBtn.setAttribute("aria-label", "Apply link");
7854
8152
  applyBtn.innerHTML = defaultIcons["check"] ?? "";
7855
8153
  const removeBtn = document.createElement("button");
7856
8154
  removeBtn.type = "button";
7857
8155
  removeBtn.className = "dm-link-popover-btn dm-link-popover-remove";
7858
8156
  removeBtn.title = "Remove link";
8157
+ removeBtn.setAttribute("aria-label", "Remove link");
7859
8158
  removeBtn.innerHTML = defaultIcons["linkBreak"] ?? "";
7860
8159
  el.appendChild(input);
7861
8160
  el.appendChild(applyBtn);
@@ -8513,6 +8812,6 @@ var StarterKit = Extension.create({
8513
8812
  // src/index.ts
8514
8813
  var VERSION = "0.1.0";
8515
8814
 
8516
- 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 };
8517
8816
  //# sourceMappingURL=index.js.map
8518
8817
  //# sourceMappingURL=index.js.map