@codemirror/autocomplete 6.3.4 → 6.4.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/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 6.4.0 (2022-12-14)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where the extension would sometimes try to draw a disabled dialog at an outdated position, leading to plugin crashes.
6
+
7
+ ### New features
8
+
9
+ A `tooltipClass` option to autocompletion can now be used to add additional CSS classes to the completion tooltip.
10
+
1
11
  ## 6.3.4 (2022-11-24)
2
12
 
3
13
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -327,6 +327,7 @@ const completionConfig = state.Facet.define({
327
327
  closeOnBlur: true,
328
328
  maxRenderedOptions: 100,
329
329
  defaultKeymap: true,
330
+ tooltipClass: () => "",
330
331
  optionClass: () => "",
331
332
  aboveCursor: false,
332
333
  icons: true,
@@ -337,6 +338,7 @@ const completionConfig = state.Facet.define({
337
338
  defaultKeymap: (a, b) => a && b,
338
339
  closeOnBlur: (a, b) => a && b,
339
340
  icons: (a, b) => a && b,
341
+ tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
340
342
  optionClass: (a, b) => c => joinClass(a(c), b(c)),
341
343
  addToOptions: (a, b) => a.concat(b)
342
344
  });
@@ -415,14 +417,17 @@ class CompletionTooltip {
415
417
  key: this
416
418
  };
417
419
  this.space = null;
420
+ this.currentClass = "";
418
421
  let cState = view.state.field(stateField);
419
422
  let { options, selected } = cState.open;
420
423
  let config = view.state.facet(completionConfig);
421
424
  this.optionContent = optionContent(config);
422
425
  this.optionClass = config.optionClass;
426
+ this.tooltipClass = config.tooltipClass;
423
427
  this.range = rangeAroundSelected(options.length, selected, config.maxRenderedOptions);
424
428
  this.dom = document.createElement("div");
425
429
  this.dom.className = "cm-tooltip-autocomplete";
430
+ this.updateTooltipClass(view.state);
426
431
  this.dom.addEventListener("mousedown", (e) => {
427
432
  for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
428
433
  if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
@@ -443,12 +448,25 @@ class CompletionTooltip {
443
448
  var _a, _b, _c;
444
449
  let cState = update.state.field(this.stateField);
445
450
  let prevState = update.startState.field(this.stateField);
451
+ this.updateTooltipClass(update.state);
446
452
  if (cState != prevState) {
447
453
  this.updateSel();
448
454
  if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
449
455
  this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
450
456
  }
451
457
  }
458
+ updateTooltipClass(state) {
459
+ let cls = this.tooltipClass(state);
460
+ if (cls != this.currentClass) {
461
+ for (let c of this.currentClass.split(" "))
462
+ if (c)
463
+ this.dom.classList.remove(c);
464
+ for (let c of cls.split(" "))
465
+ if (c)
466
+ this.dom.classList.add(c);
467
+ this.currentClass = cls;
468
+ }
469
+ }
452
470
  positioned(space) {
453
471
  this.space = space;
454
472
  if (this.info)
@@ -709,13 +727,13 @@ class CompletionState {
709
727
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
710
728
  active = this.active;
711
729
  let open = this.open;
730
+ if (open && tr.docChanged)
731
+ open = open.map(tr.changes);
712
732
  if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
713
733
  !sameResults(active, this.active))
714
- open = CompletionDialog.build(active, state, this.id, this.open, conf);
734
+ open = CompletionDialog.build(active, state, this.id, open, conf);
715
735
  else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
716
736
  open = null;
717
- else if (open && tr.docChanged)
718
- open = open.map(tr.changes);
719
737
  if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
720
738
  active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
721
739
  for (let effect of tr.effects)
package/dist/index.d.ts CHANGED
@@ -50,6 +50,11 @@ interface CompletionConfig {
50
50
  */
51
51
  aboveCursor?: boolean;
52
52
  /**
53
+ When given, this may return an additional CSS class to add to
54
+ the completion dialog element.
55
+ */
56
+ tooltipClass?: (state: EditorState) => string;
57
+ /**
53
58
  This can be used to add additional CSS classes to completion
54
59
  options.
55
60
  */
package/dist/index.js CHANGED
@@ -323,6 +323,7 @@ const completionConfig = /*@__PURE__*/Facet.define({
323
323
  closeOnBlur: true,
324
324
  maxRenderedOptions: 100,
325
325
  defaultKeymap: true,
326
+ tooltipClass: () => "",
326
327
  optionClass: () => "",
327
328
  aboveCursor: false,
328
329
  icons: true,
@@ -333,6 +334,7 @@ const completionConfig = /*@__PURE__*/Facet.define({
333
334
  defaultKeymap: (a, b) => a && b,
334
335
  closeOnBlur: (a, b) => a && b,
335
336
  icons: (a, b) => a && b,
337
+ tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
336
338
  optionClass: (a, b) => c => joinClass(a(c), b(c)),
337
339
  addToOptions: (a, b) => a.concat(b)
338
340
  });
@@ -411,14 +413,17 @@ class CompletionTooltip {
411
413
  key: this
412
414
  };
413
415
  this.space = null;
416
+ this.currentClass = "";
414
417
  let cState = view.state.field(stateField);
415
418
  let { options, selected } = cState.open;
416
419
  let config = view.state.facet(completionConfig);
417
420
  this.optionContent = optionContent(config);
418
421
  this.optionClass = config.optionClass;
422
+ this.tooltipClass = config.tooltipClass;
419
423
  this.range = rangeAroundSelected(options.length, selected, config.maxRenderedOptions);
420
424
  this.dom = document.createElement("div");
421
425
  this.dom.className = "cm-tooltip-autocomplete";
426
+ this.updateTooltipClass(view.state);
422
427
  this.dom.addEventListener("mousedown", (e) => {
423
428
  for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
424
429
  if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
@@ -439,12 +444,25 @@ class CompletionTooltip {
439
444
  var _a, _b, _c;
440
445
  let cState = update.state.field(this.stateField);
441
446
  let prevState = update.startState.field(this.stateField);
447
+ this.updateTooltipClass(update.state);
442
448
  if (cState != prevState) {
443
449
  this.updateSel();
444
450
  if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
445
451
  this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
446
452
  }
447
453
  }
454
+ updateTooltipClass(state) {
455
+ let cls = this.tooltipClass(state);
456
+ if (cls != this.currentClass) {
457
+ for (let c of this.currentClass.split(" "))
458
+ if (c)
459
+ this.dom.classList.remove(c);
460
+ for (let c of cls.split(" "))
461
+ if (c)
462
+ this.dom.classList.add(c);
463
+ this.currentClass = cls;
464
+ }
465
+ }
448
466
  positioned(space) {
449
467
  this.space = space;
450
468
  if (this.info)
@@ -705,13 +723,13 @@ class CompletionState {
705
723
  if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
706
724
  active = this.active;
707
725
  let open = this.open;
726
+ if (open && tr.docChanged)
727
+ open = open.map(tr.changes);
708
728
  if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
709
729
  !sameResults(active, this.active))
710
- open = CompletionDialog.build(active, state, this.id, this.open, conf);
730
+ open = CompletionDialog.build(active, state, this.id, open, conf);
711
731
  else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
712
732
  open = null;
713
- else if (open && tr.docChanged)
714
- open = open.map(tr.changes);
715
733
  if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
716
734
  active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
717
735
  for (let effect of tr.effects)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/autocomplete",
3
- "version": "6.3.4",
3
+ "version": "6.4.0",
4
4
  "description": "Autocompletion for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",