@codemirror/view 6.33.0 → 6.34.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 +18 -0
- package/dist/index.cjs +18 -32
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +18 -32
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 6.34.0 (2024-09-25)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where the dots past the wrapping point were displayed incorrectly when using `highlightWhitespace` with a wrapped sequence of spaces.
|
|
6
|
+
|
|
7
|
+
Improve performance of documents displaying lots of highlighted spaces by using a CSS background instead of pseudo-element.
|
|
8
|
+
|
|
9
|
+
### New features
|
|
10
|
+
|
|
11
|
+
`placeholder` now allows a function that constructs the placedholder DOM to be passed in, and uses `cloneNode` when a raw element is passed in, to prevent adding the same element to multiple editors.
|
|
12
|
+
|
|
13
|
+
## 6.33.1 (2024-08-30)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Work around odd behavior in Chrome's newly supported `caretPositionFromPoint` method, which could cause CodeMirror to crash with a null dereference.
|
|
18
|
+
|
|
1
19
|
## 6.33.0 (2024-08-24)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -20,12 +20,6 @@ function getSelection(root) {
|
|
|
20
20
|
function contains(dom, node) {
|
|
21
21
|
return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
22
22
|
}
|
|
23
|
-
function deepActiveElement(doc) {
|
|
24
|
-
let elt = doc.activeElement;
|
|
25
|
-
while (elt && elt.shadowRoot)
|
|
26
|
-
elt = elt.shadowRoot.activeElement;
|
|
27
|
-
return elt;
|
|
28
|
-
}
|
|
29
23
|
function hasSelection(dom, selection) {
|
|
30
24
|
if (!selection.anchorNode)
|
|
31
25
|
return false;
|
|
@@ -3581,6 +3575,11 @@ function posAtCoords(view, coords, precise, bias = -1) {
|
|
|
3581
3575
|
node = undefined;
|
|
3582
3576
|
}
|
|
3583
3577
|
}
|
|
3578
|
+
// Chrome will return offsets into <input> elements without child
|
|
3579
|
+
// nodes, which will lead to a null deref below, so clip the
|
|
3580
|
+
// offset to the node size.
|
|
3581
|
+
if (node)
|
|
3582
|
+
offset = Math.min(maxOffset(node), offset);
|
|
3584
3583
|
}
|
|
3585
3584
|
// No luck, do our own (potentially expensive) search
|
|
3586
3585
|
if (!node || !view.docView.dom.contains(node)) {
|
|
@@ -4130,7 +4129,6 @@ function selectionFromPoints(points, base) {
|
|
|
4130
4129
|
return anchor > -1 && head > -1 ? state.EditorSelection.single(anchor + base, head + base) : null;
|
|
4131
4130
|
}
|
|
4132
4131
|
|
|
4133
|
-
// This will also be where dragging info and such goes
|
|
4134
4132
|
class InputState {
|
|
4135
4133
|
setSelectionOrigin(origin) {
|
|
4136
4134
|
this.lastSelectionOrigin = origin;
|
|
@@ -6574,11 +6572,9 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
6574
6572
|
display: "inline-block",
|
|
6575
6573
|
verticalAlign: "top",
|
|
6576
6574
|
},
|
|
6577
|
-
".cm-highlightSpace
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
pointerEvents: "none",
|
|
6581
|
-
color: "#888"
|
|
6575
|
+
".cm-highlightSpace": {
|
|
6576
|
+
backgroundImage: "radial-gradient(circle at 50% 55%, #aaa 20%, transparent 5%)",
|
|
6577
|
+
backgroundPosition: "center",
|
|
6582
6578
|
},
|
|
6583
6579
|
".cm-highlightTab": {
|
|
6584
6580
|
backgroundImage: `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="20"><path stroke="%23888" stroke-width="1" fill="none" d="M1 10H196L190 5M190 15L196 10M197 4L197 16"/></svg>')`,
|
|
@@ -6776,7 +6772,7 @@ class DOMObserver {
|
|
|
6776
6772
|
if (!this.readSelectionRange() || this.delayedAndroidKey)
|
|
6777
6773
|
return;
|
|
6778
6774
|
let { view } = this, sel = this.selectionRange;
|
|
6779
|
-
if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(
|
|
6775
|
+
if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(this.dom, sel))
|
|
6780
6776
|
return;
|
|
6781
6777
|
let context = sel.anchorNode && view.docView.nearest(sel.anchorNode);
|
|
6782
6778
|
if (context && context.ignoreEvent(event)) {
|
|
@@ -6804,7 +6800,7 @@ class DOMObserver {
|
|
|
6804
6800
|
if (!selection)
|
|
6805
6801
|
return false;
|
|
6806
6802
|
let range = browser.safari && view.root.nodeType == 11 &&
|
|
6807
|
-
|
|
6803
|
+
view.root.activeElement == this.dom &&
|
|
6808
6804
|
safariSelectionRangeHack(this.view, selection) || selection;
|
|
6809
6805
|
if (!range || this.selectionRange.eq(range))
|
|
6810
6806
|
return false;
|
|
@@ -9492,11 +9488,13 @@ class Placeholder extends WidgetType {
|
|
|
9492
9488
|
super();
|
|
9493
9489
|
this.content = content;
|
|
9494
9490
|
}
|
|
9495
|
-
toDOM() {
|
|
9491
|
+
toDOM(view) {
|
|
9496
9492
|
let wrap = document.createElement("span");
|
|
9497
9493
|
wrap.className = "cm-placeholder";
|
|
9498
9494
|
wrap.style.pointerEvents = "none";
|
|
9499
|
-
wrap.appendChild(typeof this.content == "string" ? document.createTextNode(this.content) :
|
|
9495
|
+
wrap.appendChild(typeof this.content == "string" ? document.createTextNode(this.content) :
|
|
9496
|
+
typeof this.content == "function" ? this.content(view) :
|
|
9497
|
+
this.content.cloneNode(true));
|
|
9500
9498
|
if (typeof this.content == "string")
|
|
9501
9499
|
wrap.setAttribute("aria-label", "placeholder " + this.content);
|
|
9502
9500
|
else
|
|
@@ -11031,20 +11029,6 @@ function highlightActiveLineGutter() {
|
|
|
11031
11029
|
return activeLineGutterHighlighter;
|
|
11032
11030
|
}
|
|
11033
11031
|
|
|
11034
|
-
const WhitespaceDeco = new Map();
|
|
11035
|
-
function getWhitespaceDeco(space) {
|
|
11036
|
-
let deco = WhitespaceDeco.get(space);
|
|
11037
|
-
if (!deco)
|
|
11038
|
-
WhitespaceDeco.set(space, deco = Decoration.mark({
|
|
11039
|
-
attributes: space === "\t" ? {
|
|
11040
|
-
class: "cm-highlightTab",
|
|
11041
|
-
} : {
|
|
11042
|
-
class: "cm-highlightSpace",
|
|
11043
|
-
"data-display": space.replace(/ /g, "·")
|
|
11044
|
-
}
|
|
11045
|
-
}));
|
|
11046
|
-
return deco;
|
|
11047
|
-
}
|
|
11048
11032
|
function matcher(decorator) {
|
|
11049
11033
|
return ViewPlugin.define(view => ({
|
|
11050
11034
|
decorations: decorator.createDeco(view),
|
|
@@ -11055,9 +11039,11 @@ function matcher(decorator) {
|
|
|
11055
11039
|
decorations: v => v.decorations
|
|
11056
11040
|
});
|
|
11057
11041
|
}
|
|
11042
|
+
const tabDeco = Decoration.mark({ class: "cm-highlightTab" });
|
|
11043
|
+
const spaceDeco = Decoration.mark({ class: "cm-highlightSpace" });
|
|
11058
11044
|
const whitespaceHighlighter = matcher(new MatchDecorator({
|
|
11059
|
-
regexp: /\t|
|
|
11060
|
-
decoration: match =>
|
|
11045
|
+
regexp: /\t| /g,
|
|
11046
|
+
decoration: match => match[0] == "\t" ? tabDeco : spaceDeco,
|
|
11061
11047
|
boundary: /\S/,
|
|
11062
11048
|
}));
|
|
11063
11049
|
/**
|
package/dist/index.d.cts
CHANGED
|
@@ -1585,7 +1585,7 @@ declare function highlightActiveLine(): Extension;
|
|
|
1585
1585
|
Extension that enables a placeholder—a piece of example content
|
|
1586
1586
|
to show when the editor is empty.
|
|
1587
1587
|
*/
|
|
1588
|
-
declare function placeholder(content: string | HTMLElement): Extension;
|
|
1588
|
+
declare function placeholder(content: string | HTMLElement | ((view: EditorView) => HTMLElement)): Extension;
|
|
1589
1589
|
|
|
1590
1590
|
/**
|
|
1591
1591
|
Markers shown in a [layer](https://codemirror.net/6/docs/ref/#view.layer) must conform to this
|
package/dist/index.d.ts
CHANGED
|
@@ -1585,7 +1585,7 @@ declare function highlightActiveLine(): Extension;
|
|
|
1585
1585
|
Extension that enables a placeholder—a piece of example content
|
|
1586
1586
|
to show when the editor is empty.
|
|
1587
1587
|
*/
|
|
1588
|
-
declare function placeholder(content: string | HTMLElement): Extension;
|
|
1588
|
+
declare function placeholder(content: string | HTMLElement | ((view: EditorView) => HTMLElement)): Extension;
|
|
1589
1589
|
|
|
1590
1590
|
/**
|
|
1591
1591
|
Markers shown in a [layer](https://codemirror.net/6/docs/ref/#view.layer) must conform to this
|
package/dist/index.js
CHANGED
|
@@ -18,12 +18,6 @@ function getSelection(root) {
|
|
|
18
18
|
function contains(dom, node) {
|
|
19
19
|
return node ? dom == node || dom.contains(node.nodeType != 1 ? node.parentNode : node) : false;
|
|
20
20
|
}
|
|
21
|
-
function deepActiveElement(doc) {
|
|
22
|
-
let elt = doc.activeElement;
|
|
23
|
-
while (elt && elt.shadowRoot)
|
|
24
|
-
elt = elt.shadowRoot.activeElement;
|
|
25
|
-
return elt;
|
|
26
|
-
}
|
|
27
21
|
function hasSelection(dom, selection) {
|
|
28
22
|
if (!selection.anchorNode)
|
|
29
23
|
return false;
|
|
@@ -3577,6 +3571,11 @@ function posAtCoords(view, coords, precise, bias = -1) {
|
|
|
3577
3571
|
node = undefined;
|
|
3578
3572
|
}
|
|
3579
3573
|
}
|
|
3574
|
+
// Chrome will return offsets into <input> elements without child
|
|
3575
|
+
// nodes, which will lead to a null deref below, so clip the
|
|
3576
|
+
// offset to the node size.
|
|
3577
|
+
if (node)
|
|
3578
|
+
offset = Math.min(maxOffset(node), offset);
|
|
3580
3579
|
}
|
|
3581
3580
|
// No luck, do our own (potentially expensive) search
|
|
3582
3581
|
if (!node || !view.docView.dom.contains(node)) {
|
|
@@ -4126,7 +4125,6 @@ function selectionFromPoints(points, base) {
|
|
|
4126
4125
|
return anchor > -1 && head > -1 ? EditorSelection.single(anchor + base, head + base) : null;
|
|
4127
4126
|
}
|
|
4128
4127
|
|
|
4129
|
-
// This will also be where dragging info and such goes
|
|
4130
4128
|
class InputState {
|
|
4131
4129
|
setSelectionOrigin(origin) {
|
|
4132
4130
|
this.lastSelectionOrigin = origin;
|
|
@@ -6569,11 +6567,9 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
6569
6567
|
display: "inline-block",
|
|
6570
6568
|
verticalAlign: "top",
|
|
6571
6569
|
},
|
|
6572
|
-
".cm-highlightSpace
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
pointerEvents: "none",
|
|
6576
|
-
color: "#888"
|
|
6570
|
+
".cm-highlightSpace": {
|
|
6571
|
+
backgroundImage: "radial-gradient(circle at 50% 55%, #aaa 20%, transparent 5%)",
|
|
6572
|
+
backgroundPosition: "center",
|
|
6577
6573
|
},
|
|
6578
6574
|
".cm-highlightTab": {
|
|
6579
6575
|
backgroundImage: `url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="20"><path stroke="%23888" stroke-width="1" fill="none" d="M1 10H196L190 5M190 15L196 10M197 4L197 16"/></svg>')`,
|
|
@@ -6771,7 +6767,7 @@ class DOMObserver {
|
|
|
6771
6767
|
if (!this.readSelectionRange() || this.delayedAndroidKey)
|
|
6772
6768
|
return;
|
|
6773
6769
|
let { view } = this, sel = this.selectionRange;
|
|
6774
|
-
if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(
|
|
6770
|
+
if (view.state.facet(editable) ? view.root.activeElement != this.dom : !hasSelection(this.dom, sel))
|
|
6775
6771
|
return;
|
|
6776
6772
|
let context = sel.anchorNode && view.docView.nearest(sel.anchorNode);
|
|
6777
6773
|
if (context && context.ignoreEvent(event)) {
|
|
@@ -6799,7 +6795,7 @@ class DOMObserver {
|
|
|
6799
6795
|
if (!selection)
|
|
6800
6796
|
return false;
|
|
6801
6797
|
let range = browser.safari && view.root.nodeType == 11 &&
|
|
6802
|
-
|
|
6798
|
+
view.root.activeElement == this.dom &&
|
|
6803
6799
|
safariSelectionRangeHack(this.view, selection) || selection;
|
|
6804
6800
|
if (!range || this.selectionRange.eq(range))
|
|
6805
6801
|
return false;
|
|
@@ -9487,11 +9483,13 @@ class Placeholder extends WidgetType {
|
|
|
9487
9483
|
super();
|
|
9488
9484
|
this.content = content;
|
|
9489
9485
|
}
|
|
9490
|
-
toDOM() {
|
|
9486
|
+
toDOM(view) {
|
|
9491
9487
|
let wrap = document.createElement("span");
|
|
9492
9488
|
wrap.className = "cm-placeholder";
|
|
9493
9489
|
wrap.style.pointerEvents = "none";
|
|
9494
|
-
wrap.appendChild(typeof this.content == "string" ? document.createTextNode(this.content) :
|
|
9490
|
+
wrap.appendChild(typeof this.content == "string" ? document.createTextNode(this.content) :
|
|
9491
|
+
typeof this.content == "function" ? this.content(view) :
|
|
9492
|
+
this.content.cloneNode(true));
|
|
9495
9493
|
if (typeof this.content == "string")
|
|
9496
9494
|
wrap.setAttribute("aria-label", "placeholder " + this.content);
|
|
9497
9495
|
else
|
|
@@ -11026,20 +11024,6 @@ function highlightActiveLineGutter() {
|
|
|
11026
11024
|
return activeLineGutterHighlighter;
|
|
11027
11025
|
}
|
|
11028
11026
|
|
|
11029
|
-
const WhitespaceDeco = /*@__PURE__*/new Map();
|
|
11030
|
-
function getWhitespaceDeco(space) {
|
|
11031
|
-
let deco = WhitespaceDeco.get(space);
|
|
11032
|
-
if (!deco)
|
|
11033
|
-
WhitespaceDeco.set(space, deco = Decoration.mark({
|
|
11034
|
-
attributes: space === "\t" ? {
|
|
11035
|
-
class: "cm-highlightTab",
|
|
11036
|
-
} : {
|
|
11037
|
-
class: "cm-highlightSpace",
|
|
11038
|
-
"data-display": space.replace(/ /g, "·")
|
|
11039
|
-
}
|
|
11040
|
-
}));
|
|
11041
|
-
return deco;
|
|
11042
|
-
}
|
|
11043
11027
|
function matcher(decorator) {
|
|
11044
11028
|
return ViewPlugin.define(view => ({
|
|
11045
11029
|
decorations: decorator.createDeco(view),
|
|
@@ -11050,9 +11034,11 @@ function matcher(decorator) {
|
|
|
11050
11034
|
decorations: v => v.decorations
|
|
11051
11035
|
});
|
|
11052
11036
|
}
|
|
11037
|
+
const tabDeco = /*@__PURE__*/Decoration.mark({ class: "cm-highlightTab" });
|
|
11038
|
+
const spaceDeco = /*@__PURE__*/Decoration.mark({ class: "cm-highlightSpace" });
|
|
11053
11039
|
const whitespaceHighlighter = /*@__PURE__*/matcher(/*@__PURE__*/new MatchDecorator({
|
|
11054
|
-
regexp: /\t|
|
|
11055
|
-
decoration: match =>
|
|
11040
|
+
regexp: /\t| /g,
|
|
11041
|
+
decoration: match => match[0] == "\t" ? tabDeco : spaceDeco,
|
|
11056
11042
|
boundary: /\S/,
|
|
11057
11043
|
}));
|
|
11058
11044
|
/**
|