@ni/nimble-components 32.2.7 → 32.2.8

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.
@@ -35251,6 +35251,7 @@ so this becomes the fallback color for the slot */ ''}
35251
35251
  return true;
35252
35252
  }
35253
35253
  else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
35254
+ this.destroyBetween(this.index, i);
35254
35255
  this.top.children[this.index] = updated;
35255
35256
  if (updated.contentDOM) {
35256
35257
  updated.dirty = CONTENT_DIRTY;
@@ -35270,7 +35271,8 @@ so this becomes the fallback color for the slot */ ''}
35270
35271
  // identical content, move over its children.
35271
35272
  recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
35272
35273
  if (next.dirty || node.isAtom || !next.children.length ||
35273
- !next.node.content.eq(node.content))
35274
+ !next.node.content.eq(node.content) ||
35275
+ !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco))
35274
35276
  return null;
35275
35277
  let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
35276
35278
  if (wrapper.contentDOM) {
@@ -35541,9 +35543,9 @@ so this becomes the fallback color for the slot */ ''}
35541
35543
  let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1);
35542
35544
  if (head < 0)
35543
35545
  return null;
35544
- let $head = doc.resolve(head), $anchor, selection;
35546
+ let $head = doc.resolve(head), anchor, selection;
35545
35547
  if (selectionCollapsed(domSel)) {
35546
- $anchor = $head;
35548
+ anchor = head;
35547
35549
  while (nearestDesc && !nearestDesc.node)
35548
35550
  nearestDesc = nearestDesc.parent;
35549
35551
  let nearestDescNode = nearestDesc.node;
@@ -35554,11 +35556,25 @@ so this becomes the fallback color for the slot */ ''}
35554
35556
  }
35555
35557
  }
35556
35558
  else {
35557
- let anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
35559
+ if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
35560
+ let min = head, max = head;
35561
+ for (let i = 0; i < domSel.rangeCount; i++) {
35562
+ let range = domSel.getRangeAt(i);
35563
+ min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1));
35564
+ max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1));
35565
+ }
35566
+ if (min < 0)
35567
+ return null;
35568
+ [anchor, head] = max == view.state.selection.anchor ? [max, min] : [min, max];
35569
+ $head = doc.resolve(head);
35570
+ }
35571
+ else {
35572
+ anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
35573
+ }
35558
35574
  if (anchor < 0)
35559
35575
  return null;
35560
- $anchor = doc.resolve(anchor);
35561
35576
  }
35577
+ let $anchor = doc.resolve(anchor);
35562
35578
  if (!selection) {
35563
35579
  let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1;
35564
35580
  selection = selectionBetween(view, $anchor, $head, bias);
@@ -40376,7 +40392,18 @@ so this becomes the fallback color for the slot */ ''}
40376
40392
  mergedAttributes[key] = [...existingClasses, ...insertClasses].join(' ');
40377
40393
  }
40378
40394
  else if (key === 'style') {
40379
- mergedAttributes[key] = [mergedAttributes[key], value].join('; ');
40395
+ const newStyles = value ? value.split(';').map((style) => style.trim()).filter(Boolean) : [];
40396
+ const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(';').map((style) => style.trim()).filter(Boolean) : [];
40397
+ const styleMap = new Map();
40398
+ existingStyles.forEach(style => {
40399
+ const [property, val] = style.split(':').map(part => part.trim());
40400
+ styleMap.set(property, val);
40401
+ });
40402
+ newStyles.forEach(style => {
40403
+ const [property, val] = style.split(':').map(part => part.trim());
40404
+ styleMap.set(property, val);
40405
+ });
40406
+ mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join('; ');
40380
40407
  }
40381
40408
  else {
40382
40409
  mergedAttributes[key] = value;
@@ -40388,6 +40415,7 @@ so this becomes the fallback color for the slot */ ''}
40388
40415
 
40389
40416
  function getRenderedAttributes(nodeOrMark, extensionAttributes) {
40390
40417
  return extensionAttributes
40418
+ .filter(attribute => attribute.type === nodeOrMark.type.name)
40391
40419
  .filter(item => item.attribute.rendered)
40392
40420
  .map(item => {
40393
40421
  if (!item.attribute.renderHTML) {
@@ -41207,15 +41235,19 @@ so this becomes the fallback color for the slot */ ''}
41207
41235
  if (!addNodeView) {
41208
41236
  return [];
41209
41237
  }
41210
- const nodeview = (node, view, getPos, decorations) => {
41238
+ const nodeview = (node, view, getPos, decorations, innerDecorations) => {
41211
41239
  const HTMLAttributes = getRenderedAttributes(node, extensionAttributes);
41212
41240
  return addNodeView()({
41213
- editor,
41241
+ // pass-through
41214
41242
  node,
41215
- getPos,
41243
+ view,
41244
+ getPos: getPos,
41216
41245
  decorations,
41217
- HTMLAttributes,
41246
+ innerDecorations,
41247
+ // tiptap-specific
41248
+ editor,
41218
41249
  extension,
41250
+ HTMLAttributes,
41219
41251
  });
41220
41252
  };
41221
41253
  return [extension.name, nodeview];
@@ -43180,10 +43212,17 @@ so this becomes the fallback color for the slot */ ''}
43180
43212
  const type = getNodeType(typeOrName, state.schema);
43181
43213
  const toggleType = getNodeType(toggleTypeOrName, state.schema);
43182
43214
  const isActive = isNodeActive(state, type, attributes);
43215
+ let attributesToCopy;
43216
+ if (state.selection.$anchor.sameParent(state.selection.$head)) {
43217
+ // only copy attributes if the selection is pointing to a node of the same type
43218
+ attributesToCopy = state.selection.$anchor.parent.attrs;
43219
+ }
43183
43220
  if (isActive) {
43184
- return commands.setNode(toggleType);
43221
+ return commands.setNode(toggleType, attributesToCopy);
43185
43222
  }
43186
- return commands.setNode(type, attributes);
43223
+ // If the node is not active, we want to set the new node type with the given attributes
43224
+ // Copying over the attributes from the current node if the selection is pointing to a node of the same type
43225
+ return commands.setNode(type, { ...attributesToCopy, ...attributes });
43187
43226
  };
43188
43227
 
43189
43228
  const toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => {
@@ -43517,7 +43556,8 @@ so this becomes the fallback color for the slot */ ''}
43517
43556
  appendTransaction: (transactions, oldState, newState) => {
43518
43557
  const docChanges = transactions.some(transaction => transaction.docChanged)
43519
43558
  && !oldState.doc.eq(newState.doc);
43520
- if (!docChanges) {
43559
+ const ignoreTr = transactions.some(transaction => transaction.getMeta('preventClearDocument'));
43560
+ if (!docChanges || ignoreTr) {
43521
43561
  return;
43522
43562
  }
43523
43563
  const { empty, from, to } = oldState.selection;
@@ -43527,7 +43567,7 @@ so this becomes the fallback color for the slot */ ''}
43527
43567
  if (empty || !allWasSelected) {
43528
43568
  return;
43529
43569
  }
43530
- const isEmpty = newState.doc.textBetween(0, newState.doc.content.size, ' ', ' ').length === 0;
43570
+ const isEmpty = isNodeEmpty(newState.doc);
43531
43571
  if (!isEmpty) {
43532
43572
  return;
43533
43573
  }
@@ -43741,6 +43781,28 @@ so this becomes the fallback color for the slot */ ''}
43741
43781
  }
43742
43782
  }
43743
43783
 
43784
+ const DropPlugin = (onDrop) => {
43785
+ return new Plugin({
43786
+ key: new PluginKey('tiptapDrop'),
43787
+ props: {
43788
+ handleDrop: (_, e, slice, moved) => {
43789
+ onDrop(e, slice, moved);
43790
+ },
43791
+ },
43792
+ });
43793
+ };
43794
+
43795
+ const PastePlugin = (onPaste) => {
43796
+ return new Plugin({
43797
+ key: new PluginKey('tiptapPaste'),
43798
+ props: {
43799
+ handlePaste: (_view, e, slice) => {
43800
+ onPaste(e, slice);
43801
+ },
43802
+ },
43803
+ });
43804
+ };
43805
+
43744
43806
  const style = `.ProseMirror {
43745
43807
  position: relative;
43746
43808
  }
@@ -43865,6 +43927,8 @@ img.ProseMirror-separator {
43865
43927
  onBlur: () => null,
43866
43928
  onDestroy: () => null,
43867
43929
  onContentError: ({ error }) => { throw error; },
43930
+ onPaste: () => null,
43931
+ onDrop: () => null,
43868
43932
  };
43869
43933
  this.isCapturingTransaction = false;
43870
43934
  this.capturedTransaction = null;
@@ -43884,6 +43948,12 @@ img.ProseMirror-separator {
43884
43948
  this.on('focus', this.options.onFocus);
43885
43949
  this.on('blur', this.options.onBlur);
43886
43950
  this.on('destroy', this.options.onDestroy);
43951
+ if (this.options.onPaste) {
43952
+ this.registerPlugin(PastePlugin(this.options.onPaste));
43953
+ }
43954
+ if (this.options.onDrop) {
43955
+ this.registerPlugin(DropPlugin(this.options.onDrop));
43956
+ }
43887
43957
  window.setTimeout(() => {
43888
43958
  if (this.isDestroyed) {
43889
43959
  return;
@@ -43972,6 +44042,7 @@ img.ProseMirror-separator {
43972
44042
  *
43973
44043
  * @param plugin A ProseMirror plugin
43974
44044
  * @param handlePlugins Control how to merge the plugin into the existing plugins.
44045
+ * @returns The new editor state
43975
44046
  */
43976
44047
  registerPlugin(plugin, handlePlugins) {
43977
44048
  const plugins = isFunction$3(handlePlugins)
@@ -43979,15 +44050,17 @@ img.ProseMirror-separator {
43979
44050
  : [...this.state.plugins, plugin];
43980
44051
  const state = this.state.reconfigure({ plugins });
43981
44052
  this.view.updateState(state);
44053
+ return state;
43982
44054
  }
43983
44055
  /**
43984
44056
  * Unregister a ProseMirror plugin.
43985
44057
  *
43986
44058
  * @param nameOrPluginKey The plugins name
44059
+ * @returns The new editor state or undefined if the editor is destroyed
43987
44060
  */
43988
44061
  unregisterPlugin(nameOrPluginKey) {
43989
44062
  if (this.isDestroyed) {
43990
- return;
44063
+ return undefined;
43991
44064
  }
43992
44065
  // @ts-ignore
43993
44066
  const name = typeof nameOrPluginKey === 'string' ? `${nameOrPluginKey}$` : nameOrPluginKey.key;
@@ -43996,6 +44069,7 @@ img.ProseMirror-separator {
43996
44069
  plugins: this.state.plugins.filter(plugin => !plugin.key.startsWith(name)),
43997
44070
  });
43998
44071
  this.view.updateState(state);
44072
+ return state;
43999
44073
  }
44000
44074
  /**
44001
44075
  * Creates an extension manager.
@@ -44011,7 +44085,12 @@ img.ProseMirror-separator {
44011
44085
  FocusEvents,
44012
44086
  Keymap,
44013
44087
  Tabindex,
44014
- ] : [];
44088
+ ].filter(ext => {
44089
+ if (typeof this.options.enableCoreExtensions === 'object') {
44090
+ return this.options.enableCoreExtensions[ext.name] !== false;
44091
+ }
44092
+ return true;
44093
+ }) : [];
44015
44094
  const allExtensions = [...coreExtensions, ...this.options.extensions].filter(extension => {
44016
44095
  return ['extension', 'node', 'mark'].includes(extension === null || extension === void 0 ? void 0 : extension.type);
44017
44096
  });
@@ -44223,6 +44302,12 @@ img.ProseMirror-separator {
44223
44302
  destroy() {
44224
44303
  this.emit('destroy');
44225
44304
  if (this.view) {
44305
+ // Cleanup our reference to prevent circular references which caused memory leaks
44306
+ // @ts-ignore
44307
+ const dom = this.view.dom;
44308
+ if (dom && dom.editor) {
44309
+ delete dom.editor;
44310
+ }
44226
44311
  this.view.destroy();
44227
44312
  }
44228
44313
  this.removeAllListeners();
@@ -58625,7 +58710,7 @@ img.ProseMirror-separator {
58625
58710
  char: '@',
58626
58711
  pluginKey: MentionPluginKey,
58627
58712
  command: ({ editor, range, props }) => {
58628
- var _a, _b;
58713
+ var _a, _b, _c;
58629
58714
  // increase range.to by one when the next node is of type "text"
58630
58715
  // and starts with a space character
58631
58716
  const nodeAfter = editor.view.state.selection.$to.nodeAfter;
@@ -58647,7 +58732,8 @@ img.ProseMirror-separator {
58647
58732
  },
58648
58733
  ])
58649
58734
  .run();
58650
- (_b = window.getSelection()) === null || _b === void 0 ? void 0 : _b.collapseToEnd();
58735
+ // get reference to `window` object from editor element, to support cross-frame JS usage
58736
+ (_c = (_b = editor.view.dom.ownerDocument.defaultView) === null || _b === void 0 ? void 0 : _b.getSelection()) === null || _c === void 0 ? void 0 : _c.collapseToEnd();
58651
58737
  },
58652
58738
  allow: ({ state, range }) => {
58653
58739
  const $from = state.doc.resolve(range.from);
@@ -67430,7 +67516,8 @@ focus outline in that case.
67430
67516
  return {
67431
67517
  disconnect: () => {
67432
67518
  var _a;
67433
- return (_a = get()) == null ? void 0 : _a.disconnect();
67519
+ (_a = get()) == null ? void 0 : _a.disconnect();
67520
+ _ro = null;
67434
67521
  },
67435
67522
  observe: (target) => {
67436
67523
  var _a;
@@ -67502,10 +67589,9 @@ focus outline in that case.
67502
67589
  this.cleanup = () => {
67503
67590
  this.unsubs.filter(Boolean).forEach((d) => d());
67504
67591
  this.unsubs = [];
67592
+ this.observer.disconnect();
67505
67593
  this.scrollElement = null;
67506
67594
  this.targetWindow = null;
67507
- this.observer.disconnect();
67508
- this.elementsCache.clear();
67509
67595
  };
67510
67596
  this._didMount = () => {
67511
67597
  return () => {
@@ -67527,6 +67613,9 @@ focus outline in that case.
67527
67613
  } else {
67528
67614
  this.targetWindow = ((_a = this.scrollElement) == null ? void 0 : _a.window) ?? null;
67529
67615
  }
67616
+ this.elementsCache.forEach((cached) => {
67617
+ this.observer.observe(cached);
67618
+ });
67530
67619
  this._scrollToOffset(this.getScrollOffset(), {
67531
67620
  adjustments: void 0,
67532
67621
  behavior: void 0
@@ -67900,7 +67989,10 @@ focus outline in that case.
67900
67989
  ...measurements.slice(-this.options.lanes).map((m) => m.end)
67901
67990
  );
67902
67991
  }
67903
- return end - this.options.scrollMargin + this.options.paddingEnd;
67992
+ return Math.max(
67993
+ end - this.options.scrollMargin + this.options.paddingEnd,
67994
+ 0
67995
+ );
67904
67996
  };
67905
67997
  this._scrollToOffset = (offset, {
67906
67998
  adjustments,