@codemirror/view 6.38.3 → 6.38.5

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,19 @@
1
+ ## 6.38.5 (2025-10-07)
2
+
3
+ ### Bug fixes
4
+
5
+ Avoid firing text changes that cover unchanged text on Android.
6
+
7
+ Fix an issue where the editor could, in some circumstances, insert a stray newline when typing over a document that ended in a block widget.
8
+
9
+ Work around an issue in Safari 26 that causes inappropriate scrolling on focus in some circumstances.
10
+
11
+ ## 6.38.4 (2025-09-28)
12
+
13
+ ### Bug fixes
14
+
15
+ Work around a Chrome Android issue where the browser doesn't properly fire composition end events, leaving CodeMirror to believe the user was still composing.
16
+
1
17
  ## 6.38.3 (2025-09-22)
2
18
 
3
19
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -5,6 +5,36 @@ var styleMod = require('style-mod');
5
5
  var w3cKeyname = require('w3c-keyname');
6
6
  var elt = require('crelt');
7
7
 
8
+ let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
9
+ let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
10
+ const ie_edge = /Edge\/(\d+)/.exec(nav.userAgent);
11
+ const ie_upto10 = /MSIE \d/.test(nav.userAgent);
12
+ const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
13
+ const ie = !!(ie_upto10 || ie_11up || ie_edge);
14
+ const gecko = !ie && /gecko\/(\d+)/i.test(nav.userAgent);
15
+ const chrome = !ie && /Chrome\/(\d+)/.exec(nav.userAgent);
16
+ const webkit = "webkitFontSmoothing" in doc.documentElement.style;
17
+ const safari = !ie && /Apple Computer/.test(nav.vendor);
18
+ const ios = safari && (/Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
19
+ var browser = {
20
+ mac: ios || /Mac/.test(nav.platform),
21
+ windows: /Win/.test(nav.platform),
22
+ linux: /Linux|X11/.test(nav.platform),
23
+ ie,
24
+ ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
25
+ gecko,
26
+ gecko_version: gecko ? +(/Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
27
+ chrome: !!chrome,
28
+ chrome_version: chrome ? +chrome[1] : 0,
29
+ ios,
30
+ android: /Android\b/.test(nav.userAgent),
31
+ webkit,
32
+ webkit_version: webkit ? +(/\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
33
+ safari,
34
+ safari_version: safari ? +(/\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
35
+ tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
36
+ };
37
+
8
38
  function getSelection(root) {
9
39
  let target;
10
40
  // Browsers differ on whether shadow roots have a getSelection
@@ -255,6 +285,9 @@ class DOMSelectionState {
255
285
  }
256
286
  }
257
287
  let preventScrollSupported = null;
288
+ // Safari 26 breaks preventScroll support
289
+ if (browser.safari && browser.safari_version >= 26)
290
+ preventScrollSupported = false;
258
291
  // Feature-detects support for .focus({preventScroll: true}), and uses
259
292
  // a fallback kludge when not supported.
260
293
  function focusPreventScroll(dom) {
@@ -724,35 +757,6 @@ function mergeChildrenInto(parent, from, to, insert, openStart, openEnd) {
724
757
  replaceRange(parent, fromI, fromOff, toI, toOff, insert, 0, openStart, openEnd);
725
758
  }
726
759
 
727
- let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
728
- let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
729
- const ie_edge = /Edge\/(\d+)/.exec(nav.userAgent);
730
- const ie_upto10 = /MSIE \d/.test(nav.userAgent);
731
- const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
732
- const ie = !!(ie_upto10 || ie_11up || ie_edge);
733
- const gecko = !ie && /gecko\/(\d+)/i.test(nav.userAgent);
734
- const chrome = !ie && /Chrome\/(\d+)/.exec(nav.userAgent);
735
- const webkit = "webkitFontSmoothing" in doc.documentElement.style;
736
- const safari = !ie && /Apple Computer/.test(nav.vendor);
737
- const ios = safari && (/Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
738
- var browser = {
739
- mac: ios || /Mac/.test(nav.platform),
740
- windows: /Win/.test(nav.platform),
741
- linux: /Linux|X11/.test(nav.platform),
742
- ie,
743
- ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
744
- gecko,
745
- gecko_version: gecko ? +(/Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
746
- chrome: !!chrome,
747
- chrome_version: chrome ? +chrome[1] : 0,
748
- ios,
749
- android: /Android\b/.test(nav.userAgent),
750
- webkit,
751
- safari,
752
- webkit_version: webkit ? +(/\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
753
- tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
754
- };
755
-
756
760
  const MaxJoinLen = 256;
757
761
  class TextView extends ContentView {
758
762
  constructor(text) {
@@ -3858,9 +3862,10 @@ class DOMReader {
3858
3862
  if (next == end)
3859
3863
  break;
3860
3864
  let view = ContentView.get(cur), nextView = ContentView.get(next);
3861
- if (view && nextView ? view.breakAfter :
3865
+ if ((view && nextView ? view.breakAfter :
3862
3866
  (view ? view.breakAfter : isBlockElement(cur)) ||
3863
- (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen))
3867
+ (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen)) &&
3868
+ !isEmptyToEnd(next, end))
3864
3869
  this.lineBreak();
3865
3870
  cur = next;
3866
3871
  }
@@ -3939,6 +3944,25 @@ function isAtEnd(parent, node, offset) {
3939
3944
  node = node.parentNode;
3940
3945
  }
3941
3946
  }
3947
+ function isEmptyToEnd(node, end) {
3948
+ let widgets;
3949
+ for (;; node = node.nextSibling) {
3950
+ if (node == end || !node)
3951
+ break;
3952
+ let view = ContentView.get(node);
3953
+ if (!((view === null || view === void 0 ? void 0 : view.isWidget) || node.cmIgnore))
3954
+ return false;
3955
+ if (view)
3956
+ (widgets || (widgets = [])).push(view);
3957
+ }
3958
+ if (widgets)
3959
+ for (let w of widgets) {
3960
+ let override = w.overrideDOMText;
3961
+ if (override === null || override === void 0 ? void 0 : override.length)
3962
+ return false;
3963
+ }
3964
+ return true;
3965
+ }
3942
3966
  class DOMPoint {
3943
3967
  constructor(node, offset) {
3944
3968
  this.node = node;
@@ -4380,7 +4404,7 @@ class InputState {
4380
4404
  return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key instanceof KeyboardEvent ? key : undefined);
4381
4405
  }
4382
4406
  ignoreDuringComposition(event) {
4383
- if (!/^key/.test(event.type))
4407
+ if (!/^key/.test(event.type) || event.synthetic)
4384
4408
  return false;
4385
4409
  if (this.composing > 0)
4386
4410
  return true;
@@ -7285,20 +7309,23 @@ class EditContextManager {
7285
7309
  let from = this.toEditorPos(e.updateRangeStart), to = this.toEditorPos(e.updateRangeEnd);
7286
7310
  if (view.inputState.composing >= 0 && !this.composing)
7287
7311
  this.composing = { contextBase: e.updateRangeStart, editorBase: from, drifted: false };
7288
- let change = { from, to, insert: state.Text.of(e.text.split("\n")) };
7312
+ let deletes = to - from > e.text.length;
7289
7313
  // If the window doesn't include the anchor, assume changes
7290
7314
  // adjacent to a side go up to the anchor.
7291
- if (change.from == this.from && anchor < this.from)
7292
- change.from = anchor;
7293
- else if (change.to == this.to && anchor > this.to)
7294
- change.to = anchor;
7315
+ if (from == this.from && anchor < this.from)
7316
+ from = anchor;
7317
+ else if (to == this.to && anchor > this.to)
7318
+ to = anchor;
7319
+ let diff = findDiff(view.state.sliceDoc(from, to), e.text, (deletes ? main.from : main.to) - from, deletes ? "end" : null);
7295
7320
  // Edit contexts sometimes fire empty changes
7296
- if (change.from == change.to && !change.insert.length) {
7321
+ if (!diff) {
7297
7322
  let newSel = state.EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd));
7298
7323
  if (!newSel.main.eq(main))
7299
7324
  view.dispatch({ selection: newSel, userEvent: "select" });
7300
7325
  return;
7301
7326
  }
7327
+ let change = { from: diff.from + from, to: diff.toA + from,
7328
+ insert: state.Text.of(e.text.slice(diff.from, diff.toB).split("\n")) };
7302
7329
  if ((browser.mac || browser.android) && change.from == head - 1 &&
7303
7330
  /^\. ?$/.test(e.text) && view.contentDOM.getAttribute("autocorrect") == "off")
7304
7331
  change = { from, to, insert: state.Text.of([e.text.replace(".", " ")]) };
@@ -7313,6 +7340,10 @@ class EditContextManager {
7313
7340
  this.revertPending(view.state);
7314
7341
  this.setSelection(view.state);
7315
7342
  }
7343
+ // Work around missed compositionend events. See https://discuss.codemirror.net/t/a/9514
7344
+ if (change.from < change.to && !change.insert.length && view.inputState.composing >= 0 &&
7345
+ !/[\\p{Alphabetic}\\p{Number}_]/.test(context.text.slice(Math.max(0, e.updateRangeStart - 1), Math.min(context.text.length, e.updateRangeStart + 1))))
7346
+ this.handlers.compositionend(e);
7316
7347
  };
7317
7348
  this.handlers.characterboundsupdate = e => {
7318
7349
  let rects = [], prev = null;
@@ -7328,10 +7359,11 @@ class EditContextManager {
7328
7359
  let deco = [];
7329
7360
  for (let format of e.getTextFormats()) {
7330
7361
  let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
7331
- if (lineStyle != "None" && thickness != "None") {
7362
+ if (!/none/i.test(lineStyle) && !/none/i.test(thickness)) {
7332
7363
  let from = this.toEditorPos(format.rangeStart), to = this.toEditorPos(format.rangeEnd);
7333
7364
  if (from < to) {
7334
- let style = `text-decoration: underline ${lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${thickness == "Thin" ? 1 : 2}px`;
7365
+ // These values changed from capitalized custom strings to lower-case CSS keywords in 2025
7366
+ let style = `text-decoration: underline ${/^[a-z]/.test(lineStyle) ? lineStyle + " " : lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${/thin/i.test(thickness) ? 1 : 2}px`;
7335
7367
  deco.push(Decoration.mark({ attributes: { style } }).range(from, to));
7336
7368
  }
7337
7369
  }
package/dist/index.js CHANGED
@@ -3,6 +3,36 @@ import { StyleModule } from 'style-mod';
3
3
  import { keyName, base, shift } from 'w3c-keyname';
4
4
  import elt from 'crelt';
5
5
 
6
+ let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
7
+ let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
8
+ const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
9
+ const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
10
+ const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
11
+ const ie = !!(ie_upto10 || ie_11up || ie_edge);
12
+ const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
13
+ const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
14
+ const webkit = "webkitFontSmoothing" in doc.documentElement.style;
15
+ const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
16
+ const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
17
+ var browser = {
18
+ mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
19
+ windows: /*@__PURE__*//Win/.test(nav.platform),
20
+ linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
21
+ ie,
22
+ ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
23
+ gecko,
24
+ gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
25
+ chrome: !!chrome,
26
+ chrome_version: chrome ? +chrome[1] : 0,
27
+ ios,
28
+ android: /*@__PURE__*//Android\b/.test(nav.userAgent),
29
+ webkit,
30
+ webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
31
+ safari,
32
+ safari_version: safari ? +(/*@__PURE__*//\bVersion\/(\d+(\.\d+)?)/.exec(nav.userAgent) || [0, 0])[1] : 0,
33
+ tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
34
+ };
35
+
6
36
  function getSelection(root) {
7
37
  let target;
8
38
  // Browsers differ on whether shadow roots have a getSelection
@@ -253,6 +283,9 @@ class DOMSelectionState {
253
283
  }
254
284
  }
255
285
  let preventScrollSupported = null;
286
+ // Safari 26 breaks preventScroll support
287
+ if (browser.safari && browser.safari_version >= 26)
288
+ preventScrollSupported = false;
256
289
  // Feature-detects support for .focus({preventScroll: true}), and uses
257
290
  // a fallback kludge when not supported.
258
291
  function focusPreventScroll(dom) {
@@ -722,35 +755,6 @@ function mergeChildrenInto(parent, from, to, insert, openStart, openEnd) {
722
755
  replaceRange(parent, fromI, fromOff, toI, toOff, insert, 0, openStart, openEnd);
723
756
  }
724
757
 
725
- let nav = typeof navigator != "undefined" ? navigator : { userAgent: "", vendor: "", platform: "" };
726
- let doc = typeof document != "undefined" ? document : { documentElement: { style: {} } };
727
- const ie_edge = /*@__PURE__*//Edge\/(\d+)/.exec(nav.userAgent);
728
- const ie_upto10 = /*@__PURE__*//MSIE \d/.test(nav.userAgent);
729
- const ie_11up = /*@__PURE__*//Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(nav.userAgent);
730
- const ie = !!(ie_upto10 || ie_11up || ie_edge);
731
- const gecko = !ie && /*@__PURE__*//gecko\/(\d+)/i.test(nav.userAgent);
732
- const chrome = !ie && /*@__PURE__*//Chrome\/(\d+)/.exec(nav.userAgent);
733
- const webkit = "webkitFontSmoothing" in doc.documentElement.style;
734
- const safari = !ie && /*@__PURE__*//Apple Computer/.test(nav.vendor);
735
- const ios = safari && (/*@__PURE__*//Mobile\/\w+/.test(nav.userAgent) || nav.maxTouchPoints > 2);
736
- var browser = {
737
- mac: ios || /*@__PURE__*//Mac/.test(nav.platform),
738
- windows: /*@__PURE__*//Win/.test(nav.platform),
739
- linux: /*@__PURE__*//Linux|X11/.test(nav.platform),
740
- ie,
741
- ie_version: ie_upto10 ? doc.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0,
742
- gecko,
743
- gecko_version: gecko ? +(/*@__PURE__*//Firefox\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
744
- chrome: !!chrome,
745
- chrome_version: chrome ? +chrome[1] : 0,
746
- ios,
747
- android: /*@__PURE__*//Android\b/.test(nav.userAgent),
748
- webkit,
749
- safari,
750
- webkit_version: webkit ? +(/*@__PURE__*//\bAppleWebKit\/(\d+)/.exec(nav.userAgent) || [0, 0])[1] : 0,
751
- tabSize: doc.documentElement.style.tabSize != null ? "tab-size" : "-moz-tab-size"
752
- };
753
-
754
758
  const MaxJoinLen = 256;
755
759
  class TextView extends ContentView {
756
760
  constructor(text) {
@@ -3854,9 +3858,10 @@ class DOMReader {
3854
3858
  if (next == end)
3855
3859
  break;
3856
3860
  let view = ContentView.get(cur), nextView = ContentView.get(next);
3857
- if (view && nextView ? view.breakAfter :
3861
+ if ((view && nextView ? view.breakAfter :
3858
3862
  (view ? view.breakAfter : isBlockElement(cur)) ||
3859
- (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen))
3863
+ (isBlockElement(next) && (cur.nodeName != "BR" || cur.cmIgnore) && this.text.length > oldLen)) &&
3864
+ !isEmptyToEnd(next, end))
3860
3865
  this.lineBreak();
3861
3866
  cur = next;
3862
3867
  }
@@ -3935,6 +3940,25 @@ function isAtEnd(parent, node, offset) {
3935
3940
  node = node.parentNode;
3936
3941
  }
3937
3942
  }
3943
+ function isEmptyToEnd(node, end) {
3944
+ let widgets;
3945
+ for (;; node = node.nextSibling) {
3946
+ if (node == end || !node)
3947
+ break;
3948
+ let view = ContentView.get(node);
3949
+ if (!((view === null || view === void 0 ? void 0 : view.isWidget) || node.cmIgnore))
3950
+ return false;
3951
+ if (view)
3952
+ (widgets || (widgets = [])).push(view);
3953
+ }
3954
+ if (widgets)
3955
+ for (let w of widgets) {
3956
+ let override = w.overrideDOMText;
3957
+ if (override === null || override === void 0 ? void 0 : override.length)
3958
+ return false;
3959
+ }
3960
+ return true;
3961
+ }
3938
3962
  class DOMPoint {
3939
3963
  constructor(node, offset) {
3940
3964
  this.node = node;
@@ -4376,7 +4400,7 @@ class InputState {
4376
4400
  return dispatchKey(this.view.contentDOM, key.key, key.keyCode, key instanceof KeyboardEvent ? key : undefined);
4377
4401
  }
4378
4402
  ignoreDuringComposition(event) {
4379
- if (!/^key/.test(event.type))
4403
+ if (!/^key/.test(event.type) || event.synthetic)
4380
4404
  return false;
4381
4405
  if (this.composing > 0)
4382
4406
  return true;
@@ -7280,20 +7304,23 @@ class EditContextManager {
7280
7304
  let from = this.toEditorPos(e.updateRangeStart), to = this.toEditorPos(e.updateRangeEnd);
7281
7305
  if (view.inputState.composing >= 0 && !this.composing)
7282
7306
  this.composing = { contextBase: e.updateRangeStart, editorBase: from, drifted: false };
7283
- let change = { from, to, insert: Text.of(e.text.split("\n")) };
7307
+ let deletes = to - from > e.text.length;
7284
7308
  // If the window doesn't include the anchor, assume changes
7285
7309
  // adjacent to a side go up to the anchor.
7286
- if (change.from == this.from && anchor < this.from)
7287
- change.from = anchor;
7288
- else if (change.to == this.to && anchor > this.to)
7289
- change.to = anchor;
7310
+ if (from == this.from && anchor < this.from)
7311
+ from = anchor;
7312
+ else if (to == this.to && anchor > this.to)
7313
+ to = anchor;
7314
+ let diff = findDiff(view.state.sliceDoc(from, to), e.text, (deletes ? main.from : main.to) - from, deletes ? "end" : null);
7290
7315
  // Edit contexts sometimes fire empty changes
7291
- if (change.from == change.to && !change.insert.length) {
7316
+ if (!diff) {
7292
7317
  let newSel = EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd));
7293
7318
  if (!newSel.main.eq(main))
7294
7319
  view.dispatch({ selection: newSel, userEvent: "select" });
7295
7320
  return;
7296
7321
  }
7322
+ let change = { from: diff.from + from, to: diff.toA + from,
7323
+ insert: Text.of(e.text.slice(diff.from, diff.toB).split("\n")) };
7297
7324
  if ((browser.mac || browser.android) && change.from == head - 1 &&
7298
7325
  /^\. ?$/.test(e.text) && view.contentDOM.getAttribute("autocorrect") == "off")
7299
7326
  change = { from, to, insert: Text.of([e.text.replace(".", " ")]) };
@@ -7308,6 +7335,10 @@ class EditContextManager {
7308
7335
  this.revertPending(view.state);
7309
7336
  this.setSelection(view.state);
7310
7337
  }
7338
+ // Work around missed compositionend events. See https://discuss.codemirror.net/t/a/9514
7339
+ if (change.from < change.to && !change.insert.length && view.inputState.composing >= 0 &&
7340
+ !/[\\p{Alphabetic}\\p{Number}_]/.test(context.text.slice(Math.max(0, e.updateRangeStart - 1), Math.min(context.text.length, e.updateRangeStart + 1))))
7341
+ this.handlers.compositionend(e);
7311
7342
  };
7312
7343
  this.handlers.characterboundsupdate = e => {
7313
7344
  let rects = [], prev = null;
@@ -7323,10 +7354,11 @@ class EditContextManager {
7323
7354
  let deco = [];
7324
7355
  for (let format of e.getTextFormats()) {
7325
7356
  let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
7326
- if (lineStyle != "None" && thickness != "None") {
7357
+ if (!/none/i.test(lineStyle) && !/none/i.test(thickness)) {
7327
7358
  let from = this.toEditorPos(format.rangeStart), to = this.toEditorPos(format.rangeEnd);
7328
7359
  if (from < to) {
7329
- let style = `text-decoration: underline ${lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${thickness == "Thin" ? 1 : 2}px`;
7360
+ // These values changed from capitalized custom strings to lower-case CSS keywords in 2025
7361
+ let style = `text-decoration: underline ${/^[a-z]/.test(lineStyle) ? lineStyle + " " : lineStyle == "Dashed" ? "dashed " : lineStyle == "Squiggle" ? "wavy " : ""}${/thin/i.test(thickness) ? 1 : 2}px`;
7330
7362
  deco.push(Decoration.mark({ attributes: { style } }).range(from, to));
7331
7363
  }
7332
7364
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.38.3",
3
+ "version": "6.38.5",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",