@ni/nimble-components 34.0.0 → 34.0.1

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.
@@ -5264,7 +5264,7 @@
5264
5264
  * Returns all displayed elements inside of a root node that match a provided selector
5265
5265
  */
5266
5266
  function getDisplayedNodes(rootNode, selector) {
5267
- if (!rootNode || false || !isHTMLElement(rootNode)) {
5267
+ if (!rootNode || !selector || !isHTMLElement(rootNode)) {
5268
5268
  return;
5269
5269
  }
5270
5270
  const nodes = Array.from(rootNode.querySelectorAll(selector));
@@ -11497,7 +11497,7 @@
11497
11497
  */
11498
11498
  getValidValue(value) {
11499
11499
  var _a, _b;
11500
- let validValue = parseFloat(parseFloat(value).toPrecision(12));
11500
+ let validValue = parseFloat(parseFloat(value).toPrecision(15));
11501
11501
  if (isNaN(validValue)) {
11502
11502
  validValue = "";
11503
11503
  }
@@ -27606,7 +27606,7 @@ so this becomes the fallback color for the slot */ ''}
27606
27606
  position in this fragment. The result object will be reused
27607
27607
  (overwritten) the next time the function is called. @internal
27608
27608
  */
27609
- findIndex(pos, round = -1) {
27609
+ findIndex(pos) {
27610
27610
  if (pos == 0)
27611
27611
  return retIndex(0, pos);
27612
27612
  if (pos == this.size)
@@ -27616,7 +27616,7 @@ so this becomes the fallback color for the slot */ ''}
27616
27616
  for (let i = 0, curPos = 0;; i++) {
27617
27617
  let cur = this.child(i), end = curPos + cur.nodeSize;
27618
27618
  if (end >= pos) {
27619
- if (end == pos || round > 0)
27619
+ if (end == pos)
27620
27620
  return retIndex(i + 1, end);
27621
27621
  return retIndex(i, curPos);
27622
27622
  }
@@ -28577,7 +28577,7 @@ so this becomes the fallback color for the slot */ ''}
28577
28577
  `blockSeparator` is given, it will be inserted to separate text
28578
28578
  from different block nodes. If `leafText` is given, it'll be
28579
28579
  inserted for every non-text leaf node encountered, otherwise
28580
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
28580
+ [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
28581
28581
  */
28582
28582
  textBetween(from, to, blockSeparator, leafText) {
28583
28583
  return this.content.textBetween(from, to, blockSeparator, leafText);
@@ -29787,8 +29787,8 @@ so this becomes the fallback color for the slot */ ''}
29787
29787
  let type = this.marks[prop], excl = type.spec.excludes;
29788
29788
  type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
29789
29789
  }
29790
- this.nodeFromJSON = this.nodeFromJSON.bind(this);
29791
- this.markFromJSON = this.markFromJSON.bind(this);
29790
+ this.nodeFromJSON = json => Node$2.fromJSON(this, json);
29791
+ this.markFromJSON = json => Mark$1.fromJSON(this, json);
29792
29792
  this.topNodeType = this.nodes[this.spec.topNode || "doc"];
29793
29793
  this.cached.wrappings = Object.create(null);
29794
29794
  }
@@ -29824,20 +29824,6 @@ so this becomes the fallback color for the slot */ ''}
29824
29824
  return type.create(attrs);
29825
29825
  }
29826
29826
  /**
29827
- Deserialize a node from its JSON representation. This method is
29828
- bound.
29829
- */
29830
- nodeFromJSON(json) {
29831
- return Node$2.fromJSON(this, json);
29832
- }
29833
- /**
29834
- Deserialize a mark from its JSON representation. This method is
29835
- bound.
29836
- */
29837
- markFromJSON(json) {
29838
- return Mark$1.fromJSON(this, json);
29839
- }
29840
- /**
29841
29827
  @internal
29842
29828
  */
29843
29829
  nodeType(name) {
@@ -30019,7 +30005,7 @@ so this becomes the fallback color for the slot */ ''}
30019
30005
  /**
30020
30006
  Construct a DOM parser using the parsing rules listed in a
30021
30007
  schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
30022
- [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
30008
+ [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
30023
30009
  */
30024
30010
  static fromSchema(schema) {
30025
30011
  return schema.cached.domParser ||
@@ -30043,7 +30029,7 @@ so this becomes the fallback color for the slot */ ''}
30043
30029
  if (preserveWhitespace != null)
30044
30030
  return (preserveWhitespace ? OPT_PRESERVE_WS : 0) |
30045
30031
  (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0);
30046
- return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & -5;
30032
+ return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
30047
30033
  }
30048
30034
  class NodeContext {
30049
30035
  constructor(type, attrs, marks, solid, match, options) {
@@ -30770,6 +30756,8 @@ so this becomes the fallback color for the slot */ ''}
30770
30756
  let space = name.indexOf(" ");
30771
30757
  if (space > 0)
30772
30758
  dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
30759
+ else if (name == "style" && dom.style)
30760
+ dom.style.cssText = attrs[name];
30773
30761
  else
30774
30762
  dom.setAttribute(name, attrs[name]);
30775
30763
  }
@@ -33479,7 +33467,7 @@ so this becomes the fallback color for the slot */ ''}
33479
33467
  throw new RangeError("Selection passed to setSelection must point at the current document");
33480
33468
  this.curSelection = selection;
33481
33469
  this.curSelectionFor = this.steps.length;
33482
- this.updated = (this.updated | UPDATED_SEL) & -3;
33470
+ this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS;
33483
33471
  this.storedMarks = null;
33484
33472
  return this;
33485
33473
  }
@@ -33530,7 +33518,7 @@ so this becomes the fallback color for the slot */ ''}
33530
33518
  */
33531
33519
  addStep(step, doc) {
33532
33520
  super.addStep(step, doc);
33533
- this.updated = this.updated & -3;
33521
+ this.updated = this.updated & ~UPDATED_MARKS;
33534
33522
  this.storedMarks = null;
33535
33523
  }
33536
33524
  /**
@@ -41876,7 +41864,7 @@ so this becomes the fallback color for the slot */ ''}
41876
41864
  dropEvent = event;
41877
41865
  if (!isDroppedFromProseMirror) {
41878
41866
  const dragFromOtherEditor = tiptapDragFromOtherEditor;
41879
- if (dragFromOtherEditor) {
41867
+ if (dragFromOtherEditor === null || dragFromOtherEditor === void 0 ? void 0 : dragFromOtherEditor.isEditable) {
41880
41868
  // setTimeout to avoid the wrong content after drop, timeout arg can't be empty or 0
41881
41869
  setTimeout(() => {
41882
41870
  const selection = dragFromOtherEditor.state.selection;
@@ -42427,7 +42415,7 @@ so this becomes the fallback color for the slot */ ''}
42427
42415
  tr.deleteRange(originRange.from, originRange.to);
42428
42416
  const newPos = tr.mapping.map(targetPos);
42429
42417
  tr.insert(newPos, contentSlice.content);
42430
- tr.setSelection(new TextSelection(tr.doc.resolve(newPos - 1)));
42418
+ tr.setSelection(new TextSelection(tr.doc.resolve(Math.max(newPos - 1, 0))));
42431
42419
  return true;
42432
42420
  };
42433
42421
 
@@ -42859,25 +42847,42 @@ so this becomes the fallback color for the slot */ ''}
42859
42847
  ...options,
42860
42848
  };
42861
42849
  let content;
42862
- try {
42863
- content = createNodeFromContent(value, editor.schema, {
42864
- parseOptions: {
42865
- preserveWhitespace: 'full',
42866
- ...options.parseOptions,
42867
- },
42868
- errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck,
42869
- });
42870
- }
42871
- catch (e) {
42850
+ const emitContentError = (error) => {
42872
42851
  editor.emit('contentError', {
42873
42852
  editor,
42874
- error: e,
42853
+ error,
42875
42854
  disableCollaboration: () => {
42876
42855
  if (editor.storage.collaboration) {
42877
42856
  editor.storage.collaboration.isDisabled = true;
42878
42857
  }
42879
42858
  },
42880
42859
  });
42860
+ };
42861
+ const parseOptions = {
42862
+ preserveWhitespace: 'full',
42863
+ ...options.parseOptions,
42864
+ };
42865
+ // If `emitContentError` is enabled, we want to check the content for errors
42866
+ // but ignore them (do not remove the invalid content from the document)
42867
+ if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) {
42868
+ try {
42869
+ createNodeFromContent(value, editor.schema, {
42870
+ parseOptions,
42871
+ errorOnInvalidContent: true,
42872
+ });
42873
+ }
42874
+ catch (e) {
42875
+ emitContentError(e);
42876
+ }
42877
+ }
42878
+ try {
42879
+ content = createNodeFromContent(value, editor.schema, {
42880
+ parseOptions,
42881
+ errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck,
42882
+ });
42883
+ }
42884
+ catch (e) {
42885
+ emitContentError(e);
42881
42886
  return false;
42882
42887
  }
42883
42888
  let { from, to } = typeof position === 'number' ? { from: position, to: position } : { from: position.from, to: position.to };
@@ -44704,6 +44709,10 @@ so this becomes the fallback color for the slot */ ''}
44704
44709
  const isBlock = node.isBlock && !node.isTextblock;
44705
44710
  const isNonTextAtom = node.isAtom && !node.isText;
44706
44711
  const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1);
44712
+ // Check if targetPos is within valid document range
44713
+ if (targetPos < 0 || targetPos > this.resolvedPos.doc.nodeSize - 2) {
44714
+ return;
44715
+ }
44707
44716
  const $pos = this.resolvedPos.doc.resolve(targetPos);
44708
44717
  if (!isBlock && $pos.depth <= this.depth) {
44709
44718
  return;
@@ -44903,6 +44912,7 @@ img.ProseMirror-separator {
44903
44912
  enablePasteRules: true,
44904
44913
  enableCoreExtensions: true,
44905
44914
  enableContentCheck: false,
44915
+ emitContentError: false,
44906
44916
  onBeforeCreate: () => null,
44907
44917
  onCreate: () => null,
44908
44918
  onUpdate: () => null,
@@ -58922,6 +58932,13 @@ img.ProseMirror-separator {
58922
58932
  return filtered;
58923
58933
  }
58924
58934
 
58935
+ // From DOMPurify
58936
+ // https://github.com/cure53/DOMPurify/blob/main/src/regexp.ts
58937
+ const UNICODE_WHITESPACE_PATTERN = '[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]';
58938
+ const UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN);
58939
+ const UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`);
58940
+ const UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, 'g');
58941
+
58925
58942
  /**
58926
58943
  * Check if the provided tokens form a valid link structure, which can either be a single link token
58927
58944
  * or a link token surrounded by parentheses or square brackets.
@@ -58978,14 +58995,16 @@ img.ProseMirror-separator {
58978
58995
  textBlock = nodesInChangedRanges[0];
58979
58996
  textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, textBlock.pos + textBlock.node.nodeSize, undefined, ' ');
58980
58997
  }
58981
- else if (nodesInChangedRanges.length
58982
- // We want to make sure to include the block seperator argument to treat hard breaks like spaces.
58983
- && newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ').endsWith(' ')) {
58998
+ else if (nodesInChangedRanges.length) {
58999
+ const endText = newState.doc.textBetween(newRange.from, newRange.to, ' ', ' ');
59000
+ if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) {
59001
+ return;
59002
+ }
58984
59003
  textBlock = nodesInChangedRanges[0];
58985
59004
  textBeforeWhitespace = newState.doc.textBetween(textBlock.pos, newRange.to, undefined, ' ');
58986
59005
  }
58987
59006
  if (textBlock && textBeforeWhitespace) {
58988
- const wordsBeforeWhitespace = textBeforeWhitespace.split(' ').filter(s => s !== '');
59007
+ const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean);
58989
59008
  if (wordsBeforeWhitespace.length <= 0) {
58990
59009
  return false;
58991
59010
  }
@@ -59097,10 +59116,6 @@ img.ProseMirror-separator {
59097
59116
  },
59098
59117
  });
59099
59118
  }
59100
- // From DOMPurify
59101
- // https://github.com/cure53/DOMPurify/blob/main/src/regexp.js
59102
- // eslint-disable-next-line no-control-regex
59103
- const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
59104
59119
  function isAllowedUri(uri, protocols) {
59105
59120
  const allowedProtocols = [
59106
59121
  'http',
@@ -59123,9 +59138,7 @@ img.ProseMirror-separator {
59123
59138
  });
59124
59139
  }
59125
59140
  return (!uri
59126
- || uri
59127
- .replace(ATTR_WHITESPACE, '')
59128
- .match(new RegExp(
59141
+ || uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, '').match(new RegExp(
59129
59142
  // eslint-disable-next-line no-useless-escape
59130
59143
  `^(?:(?:${allowedProtocols.join('|')}):|[^a-z]|[a-z0-9+.\-]+(?:[^a-z+.\-:]|$))`, 'i')));
59131
59144
  }
@@ -59420,7 +59433,7 @@ img.ProseMirror-separator {
59420
59433
  * This utility allows you to create suggestions.
59421
59434
  * @see https://tiptap.dev/api/utilities/suggestion
59422
59435
  */
59423
- function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59436
+ function Suggestion({ pluginKey = SuggestionPluginKey, editor, char = '@', allowSpaces = false, allowToIncludeChar = false, allowedPrefixes = [' '], startOfLine = false, decorationTag = 'span', decorationClass = 'suggestion', decorationContent = '', decorationEmptyClass = 'is-empty', command = () => null, items = () => [], render = () => ({}), allow = () => true, findSuggestionMatch: findSuggestionMatch$1 = findSuggestionMatch, }) {
59424
59437
  let props;
59425
59438
  const renderer = render === null || render === void 0 ? void 0 : render();
59426
59439
  const plugin = new Plugin({
@@ -59530,7 +59543,9 @@ img.ProseMirror-separator {
59530
59543
  // * a composition is active (see: https://github.com/ueberdosis/tiptap/issues/1449)
59531
59544
  if (isEditable && (empty || editor.view.composing)) {
59532
59545
  // Reset active state if we just left the previous suggestion range
59533
- if ((from < prev.range.from || from > prev.range.to) && !composing && !prev.composing) {
59546
+ if ((from < prev.range.from || from > prev.range.to)
59547
+ && !composing
59548
+ && !prev.composing) {
59534
59549
  next.active = false;
59535
59550
  }
59536
59551
  // Try to match against where our cursor currently is
@@ -59544,11 +59559,17 @@ img.ProseMirror-separator {
59544
59559
  });
59545
59560
  const decorationId = `id_${Math.floor(Math.random() * 0xffffffff)}`;
59546
59561
  // If we found a match, update the current state to show it
59547
- if (match && allow({
59548
- editor, state, range: match.range, isActive: prev.active,
59549
- })) {
59562
+ if (match
59563
+ && allow({
59564
+ editor,
59565
+ state,
59566
+ range: match.range,
59567
+ isActive: prev.active,
59568
+ })) {
59550
59569
  next.active = true;
59551
- next.decorationId = prev.decorationId ? prev.decorationId : decorationId;
59570
+ next.decorationId = prev.decorationId
59571
+ ? prev.decorationId
59572
+ : decorationId;
59552
59573
  next.range = match.range;
59553
59574
  next.query = match.query;
59554
59575
  next.text = match.text;
@@ -59582,15 +59603,21 @@ img.ProseMirror-separator {
59582
59603
  },
59583
59604
  // Setup decorator on the currently active suggestion.
59584
59605
  decorations(state) {
59585
- const { active, range, decorationId } = plugin.getState(state);
59606
+ const { active, range, decorationId, query, } = plugin.getState(state);
59586
59607
  if (!active) {
59587
59608
  return null;
59588
59609
  }
59610
+ const isEmpty = !(query === null || query === void 0 ? void 0 : query.length);
59611
+ const classNames = [decorationClass];
59612
+ if (isEmpty) {
59613
+ classNames.push(decorationEmptyClass);
59614
+ }
59589
59615
  return DecorationSet.create(state.doc, [
59590
59616
  Decoration.inline(range.from, range.to, {
59591
59617
  nodeName: decorationTag,
59592
- class: decorationClass,
59618
+ class: classNames.join(' '),
59593
59619
  'data-decoration-id': decorationId,
59620
+ 'data-decoration-content': decorationContent,
59594
59621
  }),
59595
59622
  ]);
59596
59623
  },
@@ -59600,10 +59627,91 @@ img.ProseMirror-separator {
59600
59627
  }
59601
59628
 
59602
59629
  /**
59603
- * The plugin key for the mention plugin.
59604
- * @default 'mention'
59630
+ * Returns the suggestion options for a trigger of the Mention extension. These
59631
+ * options are used to create a `Suggestion` ProseMirror plugin. Each plugin lets
59632
+ * you define a different trigger that opens the Mention menu. For example,
59633
+ * you can define a `@` trigger to mention users and a `#` trigger to mention
59634
+ * tags.
59635
+ *
59636
+ * @param param0 The configured options for the suggestion
59637
+ * @returns
59638
+ */
59639
+ function getSuggestionOptions({ editor: tiptapEditor, overrideSuggestionOptions, extensionName, char = '@', }) {
59640
+ const pluginKey = new PluginKey();
59641
+ return {
59642
+ editor: tiptapEditor,
59643
+ char,
59644
+ pluginKey,
59645
+ command: ({ editor, range, props }) => {
59646
+ var _a, _b, _c;
59647
+ // increase range.to by one when the next node is of type "text"
59648
+ // and starts with a space character
59649
+ const nodeAfter = editor.view.state.selection.$to.nodeAfter;
59650
+ const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
59651
+ if (overrideSpace) {
59652
+ range.to += 1;
59653
+ }
59654
+ editor
59655
+ .chain()
59656
+ .focus()
59657
+ .insertContentAt(range, [
59658
+ {
59659
+ type: extensionName,
59660
+ attrs: { ...props, mentionSuggestionChar: char },
59661
+ },
59662
+ {
59663
+ type: 'text',
59664
+ text: ' ',
59665
+ },
59666
+ ])
59667
+ .run();
59668
+ // get reference to `window` object from editor element, to support cross-frame JS usage
59669
+ (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
59670
+ },
59671
+ allow: ({ state, range }) => {
59672
+ const $from = state.doc.resolve(range.from);
59673
+ const type = state.schema.nodes[extensionName];
59674
+ const allow = !!$from.parent.type.contentMatch.matchType(type);
59675
+ return allow;
59676
+ },
59677
+ ...overrideSuggestionOptions,
59678
+ };
59679
+ }
59680
+
59681
+ /**
59682
+ * Returns the suggestions for the mention extension.
59683
+ *
59684
+ * @param options The extension options
59685
+ * @returns the suggestions
59686
+ */
59687
+ function getSuggestions(options) {
59688
+ return (options.options.suggestions.length ? options.options.suggestions : [options.options.suggestion]).map(suggestion => getSuggestionOptions({
59689
+ // @ts-ignore `editor` can be `undefined` when converting the document to HTML with the HTML utility
59690
+ editor: options.editor,
59691
+ overrideSuggestionOptions: suggestion,
59692
+ extensionName: options.name,
59693
+ char: suggestion.char,
59694
+ }));
59695
+ }
59696
+ /**
59697
+ * Returns the suggestion options of the mention that has a given character trigger. If not
59698
+ * found, it returns the first suggestion.
59699
+ *
59700
+ * @param options The extension options
59701
+ * @param char The character that triggers the mention
59702
+ * @returns The suggestion options
59605
59703
  */
59606
- const MentionPluginKey = new PluginKey('mention');
59704
+ function getSuggestionFromChar(options, char) {
59705
+ const suggestions = getSuggestions(options);
59706
+ const suggestion = suggestions.find(s => s.char === char);
59707
+ if (suggestion) {
59708
+ return suggestion;
59709
+ }
59710
+ if (suggestions.length) {
59711
+ return suggestions[0];
59712
+ }
59713
+ return null;
59714
+ }
59607
59715
  /**
59608
59716
  * This extension allows you to insert mentions into the editor.
59609
59717
  * @see https://www.tiptap.dev/api/extensions/mention
@@ -59614,55 +59722,21 @@ img.ProseMirror-separator {
59614
59722
  addOptions() {
59615
59723
  return {
59616
59724
  HTMLAttributes: {},
59617
- renderText({ options, node }) {
59618
- var _a;
59619
- return `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`;
59725
+ renderText({ node, suggestion }) {
59726
+ var _a, _b;
59727
+ return `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`;
59620
59728
  },
59621
59729
  deleteTriggerWithBackspace: false,
59622
- renderHTML({ options, node }) {
59623
- var _a;
59730
+ renderHTML({ options, node, suggestion }) {
59731
+ var _a, _b;
59624
59732
  return [
59625
59733
  'span',
59626
59734
  mergeAttributes(this.HTMLAttributes, options.HTMLAttributes),
59627
- `${options.suggestion.char}${(_a = node.attrs.label) !== null && _a !== void 0 ? _a : node.attrs.id}`,
59735
+ `${(_a = suggestion === null || suggestion === void 0 ? void 0 : suggestion.char) !== null && _a !== void 0 ? _a : '@'}${(_b = node.attrs.label) !== null && _b !== void 0 ? _b : node.attrs.id}`,
59628
59736
  ];
59629
59737
  },
59630
- suggestion: {
59631
- char: '@',
59632
- pluginKey: MentionPluginKey,
59633
- command: ({ editor, range, props }) => {
59634
- var _a, _b, _c;
59635
- // increase range.to by one when the next node is of type "text"
59636
- // and starts with a space character
59637
- const nodeAfter = editor.view.state.selection.$to.nodeAfter;
59638
- const overrideSpace = (_a = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.text) === null || _a === void 0 ? void 0 : _a.startsWith(' ');
59639
- if (overrideSpace) {
59640
- range.to += 1;
59641
- }
59642
- editor
59643
- .chain()
59644
- .focus()
59645
- .insertContentAt(range, [
59646
- {
59647
- type: this.name,
59648
- attrs: props,
59649
- },
59650
- {
59651
- type: 'text',
59652
- text: ' ',
59653
- },
59654
- ])
59655
- .run();
59656
- // get reference to `window` object from editor element, to support cross-frame JS usage
59657
- (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
59658
- },
59659
- allow: ({ state, range }) => {
59660
- const $from = state.doc.resolve(range.from);
59661
- const type = state.schema.nodes[this.name];
59662
- const allow = !!$from.parent.type.contentMatch.matchType(type);
59663
- return allow;
59664
- },
59665
- },
59738
+ suggestions: [],
59739
+ suggestion: {},
59666
59740
  };
59667
59741
  },
59668
59742
  group: 'inline',
@@ -59695,6 +59769,16 @@ img.ProseMirror-separator {
59695
59769
  };
59696
59770
  },
59697
59771
  },
59772
+ // When there are multiple types of mentions, this attribute helps distinguish them
59773
+ mentionSuggestionChar: {
59774
+ default: '@',
59775
+ parseHTML: element => element.getAttribute('data-mention-suggestion-char'),
59776
+ renderHTML: attributes => {
59777
+ return {
59778
+ 'data-mention-suggestion-char': attributes.mentionSuggestionChar,
59779
+ };
59780
+ },
59781
+ },
59698
59782
  };
59699
59783
  },
59700
59784
  parseHTML() {
@@ -59705,6 +59789,7 @@ img.ProseMirror-separator {
59705
59789
  ];
59706
59790
  },
59707
59791
  renderHTML({ node, HTMLAttributes }) {
59792
+ const suggestion = getSuggestionFromChar(this, node.attrs.mentionSuggestionChar);
59708
59793
  if (this.options.renderLabel !== undefined) {
59709
59794
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
59710
59795
  return [
@@ -59713,6 +59798,7 @@ img.ProseMirror-separator {
59713
59798
  this.options.renderLabel({
59714
59799
  options: this.options,
59715
59800
  node,
59801
+ suggestion,
59716
59802
  }),
59717
59803
  ];
59718
59804
  }
@@ -59721,6 +59807,7 @@ img.ProseMirror-separator {
59721
59807
  const html = this.options.renderHTML({
59722
59808
  options: mergedOptions,
59723
59809
  node,
59810
+ suggestion,
59724
59811
  });
59725
59812
  if (typeof html === 'string') {
59726
59813
  return [
@@ -59732,17 +59819,16 @@ img.ProseMirror-separator {
59732
59819
  return html;
59733
59820
  },
59734
59821
  renderText({ node }) {
59822
+ const args = {
59823
+ options: this.options,
59824
+ node,
59825
+ suggestion: getSuggestionFromChar(this, node.attrs.mentionSuggestionChar),
59826
+ };
59735
59827
  if (this.options.renderLabel !== undefined) {
59736
59828
  console.warn('renderLabel is deprecated use renderText and renderHTML instead');
59737
- return this.options.renderLabel({
59738
- options: this.options,
59739
- node,
59740
- });
59829
+ return this.options.renderLabel(args);
59741
59830
  }
59742
- return this.options.renderText({
59743
- options: this.options,
59744
- node,
59745
- });
59831
+ return this.options.renderText(args);
59746
59832
  },
59747
59833
  addKeyboardShortcuts() {
59748
59834
  return {
@@ -59760,17 +59846,27 @@ img.ProseMirror-separator {
59760
59846
  return false;
59761
59847
  }
59762
59848
  });
59849
+ // Store node and position for later use
59850
+ let mentionNode = new Node$2();
59851
+ let mentionPos = 0;
59852
+ state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
59853
+ if (node.type.name === this.name) {
59854
+ isMention = true;
59855
+ mentionNode = node;
59856
+ mentionPos = pos;
59857
+ return false;
59858
+ }
59859
+ });
59860
+ if (isMention) {
59861
+ tr.insertText(this.options.deleteTriggerWithBackspace ? '' : mentionNode.attrs.mentionSuggestionChar, mentionPos, mentionPos + mentionNode.nodeSize);
59862
+ }
59763
59863
  return isMention;
59764
59864
  }),
59765
59865
  };
59766
59866
  },
59767
59867
  addProseMirrorPlugins() {
59768
- return [
59769
- Suggestion({
59770
- editor: this.editor,
59771
- ...this.options.suggestion,
59772
- }),
59773
- ];
59868
+ // Create a plugin for each suggestion configuration
59869
+ return getSuggestions(this).map(Suggestion);
59774
59870
  },
59775
59871
  });
59776
59872
 
@@ -60133,7 +60229,8 @@ img.ProseMirror-separator {
60133
60229
  mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
60134
60230
  this.options.renderText({
60135
60231
  options: this.options,
60136
- node
60232
+ node,
60233
+ suggestion: null
60137
60234
  })
60138
60235
  ];
60139
60236
  }
@@ -68225,7 +68322,7 @@ focus outline in that case.
68225
68322
  return value;
68226
68323
  }
68227
68324
  }
68228
- const approxEqual = (a, b) => Math.abs(a - b) <= 1;
68325
+ const approxEqual = (a, b) => Math.abs(a - b) < 1.01;
68229
68326
  const debounce = (targetWindow, fn, ms) => {
68230
68327
  let timeoutId;
68231
68328
  return function(...args) {
@@ -68356,7 +68453,6 @@ focus outline in that case.
68356
68453
  this.scrollElement = null;
68357
68454
  this.targetWindow = null;
68358
68455
  this.isScrolling = false;
68359
- this.scrollToIndexTimeoutId = null;
68360
68456
  this.measurementsCache = [];
68361
68457
  this.itemSizeCache = /* @__PURE__ */ new Map();
68362
68458
  this.pendingMeasuredCacheIndexes = [];
@@ -68772,7 +68868,7 @@ focus outline in that case.
68772
68868
  } else if (align === "end") {
68773
68869
  toOffset -= size;
68774
68870
  }
68775
- const maxOffset = this.getTotalSize() - size;
68871
+ const maxOffset = this.getTotalSize() + this.options.scrollMargin - size;
68776
68872
  return Math.max(Math.min(maxOffset, toOffset), 0);
68777
68873
  };
68778
68874
  this.getOffsetForIndex = (index, align = "auto") => {
@@ -68799,14 +68895,7 @@ focus outline in that case.
68799
68895
  ];
68800
68896
  };
68801
68897
  this.isDynamicMode = () => this.elementsCache.size > 0;
68802
- this.cancelScrollToIndex = () => {
68803
- if (this.scrollToIndexTimeoutId !== null && this.targetWindow) {
68804
- this.targetWindow.clearTimeout(this.scrollToIndexTimeoutId);
68805
- this.scrollToIndexTimeoutId = null;
68806
- }
68807
- };
68808
68898
  this.scrollToOffset = (toOffset, { align = "start", behavior } = {}) => {
68809
- this.cancelScrollToIndex();
68810
68899
  if (behavior === "smooth" && this.isDynamicMode()) {
68811
68900
  console.warn(
68812
68901
  "The `smooth` scroll behavior is not fully supported with dynamic size."
@@ -68818,39 +68907,52 @@ focus outline in that case.
68818
68907
  });
68819
68908
  };
68820
68909
  this.scrollToIndex = (index, { align: initialAlign = "auto", behavior } = {}) => {
68821
- index = Math.max(0, Math.min(index, this.options.count - 1));
68822
- this.cancelScrollToIndex();
68823
68910
  if (behavior === "smooth" && this.isDynamicMode()) {
68824
68911
  console.warn(
68825
68912
  "The `smooth` scroll behavior is not fully supported with dynamic size."
68826
68913
  );
68827
68914
  }
68828
- const offsetAndAlign = this.getOffsetForIndex(index, initialAlign);
68829
- if (!offsetAndAlign) return;
68830
- const [offset, align] = offsetAndAlign;
68831
- this._scrollToOffset(offset, { adjustments: void 0, behavior });
68832
- if (behavior !== "smooth" && this.isDynamicMode() && this.targetWindow) {
68833
- this.scrollToIndexTimeoutId = this.targetWindow.setTimeout(() => {
68834
- this.scrollToIndexTimeoutId = null;
68835
- const elementInDOM = this.elementsCache.has(
68836
- this.options.getItemKey(index)
68837
- );
68838
- if (elementInDOM) {
68839
- const result = this.getOffsetForIndex(index, align);
68840
- if (!result) return;
68841
- const [latestOffset] = result;
68842
- const currentScrollOffset = this.getScrollOffset();
68843
- if (!approxEqual(latestOffset, currentScrollOffset)) {
68844
- this.scrollToIndex(index, { align, behavior });
68845
- }
68846
- } else {
68847
- this.scrollToIndex(index, { align, behavior });
68915
+ index = Math.max(0, Math.min(index, this.options.count - 1));
68916
+ let attempts = 0;
68917
+ const maxAttempts = 10;
68918
+ const tryScroll = (currentAlign) => {
68919
+ if (!this.targetWindow) return;
68920
+ const offsetInfo = this.getOffsetForIndex(index, currentAlign);
68921
+ if (!offsetInfo) {
68922
+ console.warn("Failed to get offset for index:", index);
68923
+ return;
68924
+ }
68925
+ const [offset, align] = offsetInfo;
68926
+ this._scrollToOffset(offset, { adjustments: void 0, behavior });
68927
+ this.targetWindow.requestAnimationFrame(() => {
68928
+ const currentOffset = this.getScrollOffset();
68929
+ const afterInfo = this.getOffsetForIndex(index, align);
68930
+ if (!afterInfo) {
68931
+ console.warn("Failed to get offset for index:", index);
68932
+ return;
68933
+ }
68934
+ if (!approxEqual(afterInfo[0], currentOffset)) {
68935
+ scheduleRetry(align);
68848
68936
  }
68849
68937
  });
68850
- }
68938
+ };
68939
+ const scheduleRetry = (align) => {
68940
+ if (!this.targetWindow) return;
68941
+ attempts++;
68942
+ if (attempts < maxAttempts) {
68943
+ if (this.options.debug) {
68944
+ console.info("Schedule retry", attempts, maxAttempts);
68945
+ }
68946
+ this.targetWindow.requestAnimationFrame(() => tryScroll(align));
68947
+ } else {
68948
+ console.warn(
68949
+ `Failed to scroll to index ${index} after ${maxAttempts} attempts.`
68950
+ );
68951
+ }
68952
+ };
68953
+ tryScroll(initialAlign);
68851
68954
  };
68852
68955
  this.scrollBy = (delta, { behavior } = {}) => {
68853
- this.cancelScrollToIndex();
68854
68956
  if (behavior === "smooth" && this.isDynamicMode()) {
68855
68957
  console.warn(
68856
68958
  "The `smooth` scroll behavior is not fully supported with dynamic size."
@@ -79779,7 +79881,7 @@ focus outline in that case.
79779
79881
  /** @ignore */ const isBoolean = (x) => typeof x === 'boolean';
79780
79882
  /** @ignore */ const isFunction = (x) => typeof x === 'function';
79781
79883
  /** @ignore */
79782
- // eslint-disable-next-line @typescript-eslint/ban-types
79884
+ // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
79783
79885
  const isObject$1 = (x) => x != null && Object(x) === x;
79784
79886
  /** @ignore */
79785
79887
  const isPromise = (x) => {
@@ -79950,6 +80052,7 @@ focus outline in that case.
79950
80052
  const pump$1 = (iterator) => { iterator.next(); return iterator; };
79951
80053
  /** @ignore */
79952
80054
  function* toArrayBufferViewIterator(ArrayCtor, source) {
80055
+ // eslint-disable-next-line unicorn/consistent-function-scoping
79953
80056
  const wrap = function* (x) { yield x; };
79954
80057
  const buffers = (typeof source === 'string') ? wrap(source)
79955
80058
  : (ArrayBuffer.isView(source)) ? wrap(source)
@@ -79972,6 +80075,7 @@ focus outline in that case.
79972
80075
  if (isPromise(source)) {
79973
80076
  return yield __await(yield __await(yield* __asyncDelegator(__asyncValues(toArrayBufferViewAsyncIterator(ArrayCtor, yield __await(source))))));
79974
80077
  }
80078
+ // eslint-disable-next-line unicorn/consistent-function-scoping
79975
80079
  const wrap = function (x) { return __asyncGenerator(this, arguments, function* () { yield yield __await(yield __await(x)); }); };
79976
80080
  const emit = function (source) {
79977
80081
  return __asyncGenerator(this, arguments, function* () {
@@ -80096,7 +80200,8 @@ focus outline in that case.
80096
80200
  } while (!done);
80097
80201
  }
80098
80202
  catch (e) {
80099
- (threw = true) && (typeof it.throw === 'function') && (it.throw(e));
80203
+ threw = true;
80204
+ (typeof it.throw === 'function') && (it.throw(e));
80100
80205
  }
80101
80206
  finally {
80102
80207
  (threw === false) && (typeof it.return === 'function') && (it.return(null));
@@ -80140,7 +80245,8 @@ focus outline in that case.
80140
80245
  } while (!done);
80141
80246
  }
80142
80247
  catch (e) {
80143
- (threw = true) && (typeof it.throw === 'function') && (yield __await(it.throw(e)));
80248
+ threw = true;
80249
+ (typeof it.throw === 'function') && (yield __await(it.throw(e)));
80144
80250
  }
80145
80251
  finally {
80146
80252
  (threw === false) && (typeof it.return === 'function') && (yield __await(it.return(new Uint8Array(0))));
@@ -80188,7 +80294,8 @@ focus outline in that case.
80188
80294
  } while (!done);
80189
80295
  }
80190
80296
  catch (e) {
80191
- (threw = true) && (yield __await(it['cancel'](e)));
80297
+ threw = true;
80298
+ yield __await(it['cancel'](e));
80192
80299
  }
80193
80300
  finally {
80194
80301
  (threw === false) ? (yield __await(it['cancel']()))
@@ -86708,7 +86815,6 @@ focus outline in that case.
86708
86815
  // KIND, either express or implied. See the License for the
86709
86816
  // specific language governing permissions and limitations
86710
86817
  // under the License.
86711
- /* eslint-disable @typescript-eslint/naming-convention */
86712
86818
  var Builder$1 = Builder$2;
86713
86819
  var ByteBuffer$1 = ByteBuffer$2;
86714
86820
  /** @ignore */
@@ -88903,7 +89009,6 @@ focus outline in that case.
88903
89009
  // KIND, either express or implied. See the License for the
88904
89010
  // specific language governing permissions and limitations
88905
89011
  // under the License.
88906
- /* eslint-disable brace-style */
88907
89012
  /** @ignore */
88908
89013
  function schemaFromJSON(_schema, dictionaries = new Map()) {
88909
89014
  return new Schema(schemaFieldsFromJSON(_schema, dictionaries), customMetadataFromJSON(_schema['metadata']), dictionaries);
@@ -89075,7 +89180,6 @@ focus outline in that case.
89075
89180
  // KIND, either express or implied. See the License for the
89076
89181
  // specific language governing permissions and limitations
89077
89182
  // under the License.
89078
- /* eslint-disable brace-style */
89079
89183
  var Builder = Builder$2;
89080
89184
  var ByteBuffer = ByteBuffer$2;
89081
89185
  /**