@codemirror/view 0.19.24 → 0.19.25
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 +14 -0
- package/dist/index.cjs +78 -76
- package/dist/index.d.ts +17 -15
- package/dist/index.js +78 -76
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 0.19.25 (2021-12-02)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Widgets around replaced ranges are now visible when their side does not point towards the replaced range.
|
|
6
|
+
|
|
7
|
+
A replaced line with a line decoration no longer creates an extra empty line block in the editor.
|
|
8
|
+
|
|
9
|
+
The `scrollPastEnd` extension will now over-reserve space at the bottom of the editor on startup, to prevent restored scroll positions from being clipped.
|
|
10
|
+
|
|
11
|
+
### New features
|
|
12
|
+
|
|
13
|
+
`EditorView.editorAttributes` and `contentAttributes` may now hold functions that produce the attributes.
|
|
14
|
+
|
|
1
15
|
## 0.19.24 (2021-12-01)
|
|
2
16
|
|
|
3
17
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -1086,8 +1086,9 @@ class Decoration extends rangeset.RangeValue {
|
|
|
1086
1086
|
position.
|
|
1087
1087
|
*/
|
|
1088
1088
|
static widget(spec) {
|
|
1089
|
-
let side = spec.side || 0;
|
|
1090
|
-
|
|
1089
|
+
let side = spec.side || 0, block = !!spec.block;
|
|
1090
|
+
side += block ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */) : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
|
|
1091
|
+
return new PointDecoration(spec, side, side, block, spec.widget || null, false);
|
|
1091
1092
|
}
|
|
1092
1093
|
/**
|
|
1093
1094
|
Create a replace decoration which replaces the given range with
|
|
@@ -1096,8 +1097,8 @@ class Decoration extends rangeset.RangeValue {
|
|
|
1096
1097
|
static replace(spec) {
|
|
1097
1098
|
let block = !!spec.block;
|
|
1098
1099
|
let { start, end } = getInclusive(spec, block);
|
|
1099
|
-
let startSide =
|
|
1100
|
-
let endSide =
|
|
1100
|
+
let startSide = block ? (start ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 400000000 /* NonIncStart */;
|
|
1101
|
+
let endSide = block ? (end ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -500000000 /* NonIncEnd */;
|
|
1101
1102
|
return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
|
|
1102
1103
|
}
|
|
1103
1104
|
/**
|
|
@@ -1127,7 +1128,7 @@ Decoration.none = rangeset.RangeSet.empty;
|
|
|
1127
1128
|
class MarkDecoration extends Decoration {
|
|
1128
1129
|
constructor(spec) {
|
|
1129
1130
|
let { start, end } = getInclusive(spec);
|
|
1130
|
-
super(
|
|
1131
|
+
super(start ? -1 /* InlineIncStart */ : 400000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -500000000 /* NonIncEnd */, null, spec);
|
|
1131
1132
|
this.tagName = spec.tagName || "span";
|
|
1132
1133
|
this.class = spec.class || "";
|
|
1133
1134
|
this.attrs = spec.attributes || null;
|
|
@@ -1148,7 +1149,7 @@ class MarkDecoration extends Decoration {
|
|
|
1148
1149
|
MarkDecoration.prototype.point = false;
|
|
1149
1150
|
class LineDecoration extends Decoration {
|
|
1150
1151
|
constructor(spec) {
|
|
1151
|
-
super(-
|
|
1152
|
+
super(-200000000 /* Line */, -200000000 /* Line */, null, spec);
|
|
1152
1153
|
}
|
|
1153
1154
|
eq(other) {
|
|
1154
1155
|
return other instanceof LineDecoration && attrsEq(this.spec.attributes, other.spec.attributes);
|
|
@@ -1727,36 +1728,39 @@ class PluginInstance {
|
|
|
1727
1728
|
this.value = null;
|
|
1728
1729
|
}
|
|
1729
1730
|
takeField(type, target) {
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1731
|
+
if (this.spec)
|
|
1732
|
+
for (let { field, get } of this.spec.fields)
|
|
1733
|
+
if (field == type)
|
|
1734
|
+
target.push(get(this.value));
|
|
1733
1735
|
}
|
|
1734
1736
|
update(view) {
|
|
1735
1737
|
if (!this.value) {
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1738
|
+
if (this.spec) {
|
|
1739
|
+
try {
|
|
1740
|
+
this.value = this.spec.create(view);
|
|
1741
|
+
}
|
|
1742
|
+
catch (e) {
|
|
1743
|
+
logException(view.state, e, "CodeMirror plugin crashed");
|
|
1744
|
+
this.deactivate();
|
|
1745
|
+
}
|
|
1742
1746
|
}
|
|
1743
1747
|
}
|
|
1744
1748
|
else if (this.mustUpdate) {
|
|
1745
1749
|
let update = this.mustUpdate;
|
|
1746
1750
|
this.mustUpdate = null;
|
|
1747
|
-
if (
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1751
|
+
if (this.value.update) {
|
|
1752
|
+
try {
|
|
1753
|
+
this.value.update(update);
|
|
1754
|
+
}
|
|
1755
|
+
catch (e) {
|
|
1756
|
+
logException(update.state, e, "CodeMirror plugin crashed");
|
|
1757
|
+
if (this.value.destroy)
|
|
1758
|
+
try {
|
|
1759
|
+
this.value.destroy();
|
|
1760
|
+
}
|
|
1761
|
+
catch (_) { }
|
|
1762
|
+
this.deactivate();
|
|
1763
|
+
}
|
|
1760
1764
|
}
|
|
1761
1765
|
}
|
|
1762
1766
|
return this;
|
|
@@ -1772,20 +1776,12 @@ class PluginInstance {
|
|
|
1772
1776
|
}
|
|
1773
1777
|
}
|
|
1774
1778
|
}
|
|
1779
|
+
deactivate() {
|
|
1780
|
+
this.spec = this.value = null;
|
|
1781
|
+
}
|
|
1775
1782
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
let result = {};
|
|
1779
|
-
for (let i = values.length - 1; i >= 0; i--)
|
|
1780
|
-
combineAttrs(values[i], result);
|
|
1781
|
-
return result;
|
|
1782
|
-
}
|
|
1783
|
-
const editorAttributes = state.Facet.define({
|
|
1784
|
-
combine: combineFacetAttrs
|
|
1785
|
-
});
|
|
1786
|
-
const contentAttributes = state.Facet.define({
|
|
1787
|
-
combine: combineFacetAttrs
|
|
1788
|
-
});
|
|
1783
|
+
const editorAttributes = state.Facet.define();
|
|
1784
|
+
const contentAttributes = state.Facet.define();
|
|
1789
1785
|
// Provide decorations
|
|
1790
1786
|
const decorations = state.Facet.define();
|
|
1791
1787
|
const styleModule = state.Facet.define();
|
|
@@ -1933,12 +1929,12 @@ class DocView extends ContentView {
|
|
|
1933
1929
|
this.compositionDeco = Decoration.none;
|
|
1934
1930
|
this.decorations = [];
|
|
1935
1931
|
// Track a minimum width for the editor. When measuring sizes in
|
|
1936
|
-
//
|
|
1937
|
-
// element and its extent in the document. When a change
|
|
1938
|
-
// that range, these are reset. That way, once we've seen
|
|
1939
|
-
// line/element of a given length, we keep the editor wide enough
|
|
1940
|
-
// fit at least that element, until it is changed, at which point
|
|
1941
|
-
// forget it again.
|
|
1932
|
+
// measureVisibleLineHeights, this is updated to point at the width
|
|
1933
|
+
// of a given element and its extent in the document. When a change
|
|
1934
|
+
// happens in that range, these are reset. That way, once we've seen
|
|
1935
|
+
// a line/element of a given length, we keep the editor wide enough
|
|
1936
|
+
// to fit at least that element, until it is changed, at which point
|
|
1937
|
+
// we forget it again.
|
|
1942
1938
|
this.minWidth = 0;
|
|
1943
1939
|
this.minWidthFrom = 0;
|
|
1944
1940
|
this.minWidthTo = 0;
|
|
@@ -2008,7 +2004,7 @@ class DocView extends ContentView {
|
|
|
2008
2004
|
this.updateSelection();
|
|
2009
2005
|
}
|
|
2010
2006
|
}
|
|
2011
|
-
// Used
|
|
2007
|
+
// Used by update and the constructor do perform the actual DOM
|
|
2012
2008
|
// update
|
|
2013
2009
|
updateInner(changes, deco, oldLength) {
|
|
2014
2010
|
this.view.viewState.mustMeasureContent = true;
|
|
@@ -2931,7 +2927,7 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
|
|
|
2931
2927
|
y = docTop + yOffset;
|
|
2932
2928
|
let lineStart = block.from;
|
|
2933
2929
|
// Clip x to the viewport sides
|
|
2934
|
-
x = Math.max(content.left + 1, Math.min(content.right - 1, x));
|
|
2930
|
+
x = Math.max(content.left + 1, Math.min(Math.max(content.right, content.left + view.docView.minWidth) - 1, x));
|
|
2935
2931
|
// If this is outside of the rendered viewport, we can't determine a position
|
|
2936
2932
|
if (lineStart < view.viewport.from)
|
|
2937
2933
|
return view.viewport.from == 0 ? 0 : posAtCoordsImprecise(view, content, block, x, y);
|
|
@@ -5065,7 +5061,7 @@ const baseTheme = buildTheme("." + baseThemeID, {
|
|
|
5065
5061
|
color: "inherit",
|
|
5066
5062
|
fontSize: "70%",
|
|
5067
5063
|
padding: ".2em 1em",
|
|
5068
|
-
borderRadius: "
|
|
5064
|
+
borderRadius: "1px"
|
|
5069
5065
|
},
|
|
5070
5066
|
"&light .cm-button": {
|
|
5071
5067
|
backgroundImage: "linear-gradient(#eff1f5, #d9d9df)",
|
|
@@ -5387,6 +5383,7 @@ class DOMObserver {
|
|
|
5387
5383
|
for (let dom of this.scrollTargets)
|
|
5388
5384
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5389
5385
|
window.removeEventListener("scroll", this.onScroll);
|
|
5386
|
+
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5390
5387
|
clearTimeout(this.parentCheck);
|
|
5391
5388
|
clearTimeout(this.resizeTimeout);
|
|
5392
5389
|
}
|
|
@@ -5683,6 +5680,7 @@ class EditorView {
|
|
|
5683
5680
|
*/
|
|
5684
5681
|
config = {}) {
|
|
5685
5682
|
this.plugins = [];
|
|
5683
|
+
this.pluginMap = new Map;
|
|
5686
5684
|
this.editorAttrs = {};
|
|
5687
5685
|
this.contentAttrs = {};
|
|
5688
5686
|
this.bidiCache = [];
|
|
@@ -5852,6 +5850,7 @@ class EditorView {
|
|
|
5852
5850
|
plugin.destroy(this);
|
|
5853
5851
|
this.viewState = new ViewState(newState);
|
|
5854
5852
|
this.plugins = newState.facet(viewPlugin).map(spec => new PluginInstance(spec).update(this));
|
|
5853
|
+
this.pluginMap.clear();
|
|
5855
5854
|
this.docView = new DocView(this);
|
|
5856
5855
|
this.inputState.ensureHandlers(this);
|
|
5857
5856
|
this.mountStyles();
|
|
@@ -5882,6 +5881,7 @@ class EditorView {
|
|
|
5882
5881
|
if (plugin.mustUpdate != update)
|
|
5883
5882
|
plugin.destroy(this);
|
|
5884
5883
|
this.plugins = newPlugins;
|
|
5884
|
+
this.pluginMap.clear();
|
|
5885
5885
|
this.inputState.ensureHandlers(this);
|
|
5886
5886
|
}
|
|
5887
5887
|
else {
|
|
@@ -5889,7 +5889,7 @@ class EditorView {
|
|
|
5889
5889
|
p.mustUpdate = update;
|
|
5890
5890
|
}
|
|
5891
5891
|
for (let i = 0; i < this.plugins.length; i++)
|
|
5892
|
-
this.plugins[i]
|
|
5892
|
+
this.plugins[i].update(this);
|
|
5893
5893
|
}
|
|
5894
5894
|
/**
|
|
5895
5895
|
@internal
|
|
@@ -5978,7 +5978,7 @@ class EditorView {
|
|
|
5978
5978
|
this.state.facet(theme);
|
|
5979
5979
|
}
|
|
5980
5980
|
updateAttrs() {
|
|
5981
|
-
let editorAttrs =
|
|
5981
|
+
let editorAttrs = attrsFromFacet(this, editorAttributes, {
|
|
5982
5982
|
class: "cm-editor" + (this.hasFocus ? " cm-focused " : " ") + this.themeClasses
|
|
5983
5983
|
});
|
|
5984
5984
|
let contentAttrs = {
|
|
@@ -5994,7 +5994,7 @@ class EditorView {
|
|
|
5994
5994
|
};
|
|
5995
5995
|
if (this.state.readOnly)
|
|
5996
5996
|
contentAttrs["aria-readonly"] = "true";
|
|
5997
|
-
|
|
5997
|
+
attrsFromFacet(this, contentAttributes, contentAttrs);
|
|
5998
5998
|
this.observer.ignore(() => {
|
|
5999
5999
|
updateAttrs(this.contentDOM, this.contentAttrs, contentAttrs);
|
|
6000
6000
|
updateAttrs(this.dom, this.editorAttrs, editorAttrs);
|
|
@@ -6063,10 +6063,10 @@ class EditorView {
|
|
|
6063
6063
|
the return value of this method.
|
|
6064
6064
|
*/
|
|
6065
6065
|
plugin(plugin) {
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
return
|
|
6066
|
+
let known = this.pluginMap.get(plugin);
|
|
6067
|
+
if (known === undefined || known && known.spec != plugin)
|
|
6068
|
+
this.pluginMap.set(plugin, known = this.plugins.find(p => p.spec == plugin) || null);
|
|
6069
|
+
return known && known.update(this).value;
|
|
6070
6070
|
}
|
|
6071
6071
|
/**
|
|
6072
6072
|
The top position of the document, in screen coordinates. This
|
|
@@ -6553,6 +6553,14 @@ class CachedOrder {
|
|
|
6553
6553
|
return result;
|
|
6554
6554
|
}
|
|
6555
6555
|
}
|
|
6556
|
+
function attrsFromFacet(view, facet, base) {
|
|
6557
|
+
for (let sources = view.state.facet(facet), i = sources.length - 1; i >= 0; i--) {
|
|
6558
|
+
let source = sources[i], value = typeof source == "function" ? source(view) : source;
|
|
6559
|
+
if (value)
|
|
6560
|
+
combineAttrs(value, base);
|
|
6561
|
+
}
|
|
6562
|
+
return base;
|
|
6563
|
+
}
|
|
6556
6564
|
|
|
6557
6565
|
const currentPlatform = browser.mac ? "mac" : browser.windows ? "win" : browser.linux ? "linux" : "key";
|
|
6558
6566
|
function normalizeKeyName(name, platform) {
|
|
@@ -7205,35 +7213,29 @@ class TabWidget extends WidgetType {
|
|
|
7205
7213
|
}
|
|
7206
7214
|
|
|
7207
7215
|
const plugin = ViewPlugin.fromClass(class {
|
|
7208
|
-
constructor(
|
|
7209
|
-
this.height =
|
|
7210
|
-
this.
|
|
7211
|
-
read: view => Math.max(0, view.scrollDOM.clientHeight - view.defaultLineHeight),
|
|
7212
|
-
write: (value, view) => {
|
|
7213
|
-
if (Math.abs(value - this.height) > 1) {
|
|
7214
|
-
this.height = value;
|
|
7215
|
-
view.contentDOM.style.paddingBottom = value + "px";
|
|
7216
|
-
}
|
|
7217
|
-
}
|
|
7218
|
-
};
|
|
7219
|
-
view.requestMeasure(this.measure);
|
|
7216
|
+
constructor() {
|
|
7217
|
+
this.height = 1000;
|
|
7218
|
+
this.attrs = { style: "padding-bottom: 1000px" };
|
|
7220
7219
|
}
|
|
7221
7220
|
update(update) {
|
|
7222
|
-
|
|
7223
|
-
|
|
7221
|
+
let height = update.view.viewState.editorHeight - update.view.defaultLineHeight;
|
|
7222
|
+
if (height != this.height) {
|
|
7223
|
+
this.height = height;
|
|
7224
|
+
this.attrs = { style: `padding-bottom: ${height}px` };
|
|
7225
|
+
}
|
|
7224
7226
|
}
|
|
7225
7227
|
});
|
|
7226
7228
|
/**
|
|
7227
|
-
Returns
|
|
7228
|
-
equivalent to the height of the editor, minus one line
|
|
7229
|
-
that every line in the document can be scrolled to the
|
|
7230
|
-
editor.
|
|
7229
|
+
Returns an extension that makes sure the content has a bottom
|
|
7230
|
+
margin equivalent to the height of the editor, minus one line
|
|
7231
|
+
height, so that every line in the document can be scrolled to the
|
|
7232
|
+
top of the editor.
|
|
7231
7233
|
|
|
7232
7234
|
This is only meaningful when the editor is scrollable, and should
|
|
7233
7235
|
not be enabled in editors that take the size of their content.
|
|
7234
7236
|
*/
|
|
7235
7237
|
function scrollPastEnd() {
|
|
7236
|
-
return plugin;
|
|
7238
|
+
return [plugin, contentAttributes.of(view => { var _a; return ((_a = view.plugin(plugin)) === null || _a === void 0 ? void 0 : _a.attrs) || null; })];
|
|
7237
7239
|
}
|
|
7238
7240
|
|
|
7239
7241
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -431,6 +431,7 @@ interface MeasureRequest<T> {
|
|
|
431
431
|
*/
|
|
432
432
|
key?: any;
|
|
433
433
|
}
|
|
434
|
+
declare type AttrSource = Attrs | ((view: EditorView) => Attrs | null);
|
|
434
435
|
/**
|
|
435
436
|
View [plugins](https://codemirror.net/6/docs/ref/#view.ViewPlugin) are given instances of this
|
|
436
437
|
class, which describe what happened, whenever the view is updated.
|
|
@@ -694,6 +695,7 @@ declare class EditorView {
|
|
|
694
695
|
readonly contentDOM: HTMLElement;
|
|
695
696
|
private announceDOM;
|
|
696
697
|
private plugins;
|
|
698
|
+
private pluginMap;
|
|
697
699
|
private editorAttrs;
|
|
698
700
|
private contentAttrs;
|
|
699
701
|
private styleModules;
|
|
@@ -1008,7 +1010,7 @@ declare class EditorView {
|
|
|
1008
1010
|
mounted in its [document
|
|
1009
1011
|
root](https://codemirror.net/6/docs/ref/#view.EditorView.constructor^config.root).
|
|
1010
1012
|
*/
|
|
1011
|
-
static styleModule:
|
|
1013
|
+
static styleModule: Facet<StyleModule, readonly StyleModule[]>;
|
|
1012
1014
|
/**
|
|
1013
1015
|
Facet that can be used to add DOM event handlers. The value
|
|
1014
1016
|
should be an object mapping event names to handler functions. The
|
|
@@ -1029,7 +1031,7 @@ declare class EditorView {
|
|
|
1029
1031
|
content. When one returns true, no further input handlers are
|
|
1030
1032
|
called and the default behavior is prevented.
|
|
1031
1033
|
*/
|
|
1032
|
-
static inputHandler:
|
|
1034
|
+
static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string) => boolean, readonly ((view: EditorView, from: number, to: number, text: string) => boolean)[]>;
|
|
1033
1035
|
/**
|
|
1034
1036
|
Allows you to provide a function that should be called when the
|
|
1035
1037
|
library catches an exception from an extension (mostly from view
|
|
@@ -1037,12 +1039,12 @@ declare class EditorView {
|
|
|
1037
1039
|
from user-code-provided callbacks). This is mostly useful for
|
|
1038
1040
|
debugging and logging. See [`logException`](https://codemirror.net/6/docs/ref/#view.logException).
|
|
1039
1041
|
*/
|
|
1040
|
-
static exceptionSink:
|
|
1042
|
+
static exceptionSink: Facet<(exception: any) => void, readonly ((exception: any) => void)[]>;
|
|
1041
1043
|
/**
|
|
1042
1044
|
A facet that can be used to register a function to be called
|
|
1043
1045
|
every time the view updates.
|
|
1044
1046
|
*/
|
|
1045
|
-
static updateListener:
|
|
1047
|
+
static updateListener: Facet<(update: ViewUpdate) => void, readonly ((update: ViewUpdate) => void)[]>;
|
|
1046
1048
|
/**
|
|
1047
1049
|
Facet that controls whether the editor content DOM is editable.
|
|
1048
1050
|
When its highest-precedence value is `false`, the element will
|
|
@@ -1051,33 +1053,33 @@ declare class EditorView {
|
|
|
1051
1053
|
even when those are bound to keys or buttons. See the
|
|
1052
1054
|
[`readOnly`](https://codemirror.net/6/docs/ref/#state.EditorState.readOnly) facet for that.)
|
|
1053
1055
|
*/
|
|
1054
|
-
static editable:
|
|
1056
|
+
static editable: Facet<boolean, boolean>;
|
|
1055
1057
|
/**
|
|
1056
1058
|
Allows you to influence the way mouse selection happens. The
|
|
1057
1059
|
functions in this facet will be called for a `mousedown` event
|
|
1058
1060
|
on the editor, and can return an object that overrides the way a
|
|
1059
1061
|
selection is computed from that mouse click or drag.
|
|
1060
1062
|
*/
|
|
1061
|
-
static mouseSelectionStyle:
|
|
1063
|
+
static mouseSelectionStyle: Facet<MakeSelectionStyle, readonly MakeSelectionStyle[]>;
|
|
1062
1064
|
/**
|
|
1063
1065
|
Facet used to configure whether a given selection drag event
|
|
1064
1066
|
should move or copy the selection. The given predicate will be
|
|
1065
1067
|
called with the `mousedown` event, and can return `true` when
|
|
1066
1068
|
the drag should move the content.
|
|
1067
1069
|
*/
|
|
1068
|
-
static dragMovesSelection:
|
|
1070
|
+
static dragMovesSelection: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>;
|
|
1069
1071
|
/**
|
|
1070
1072
|
Facet used to configure whether a given selecting click adds
|
|
1071
1073
|
a new range to the existing selection or replaces it entirely.
|
|
1072
1074
|
*/
|
|
1073
|
-
static clickAddsSelectionRange:
|
|
1075
|
+
static clickAddsSelectionRange: Facet<(event: MouseEvent) => boolean, readonly ((event: MouseEvent) => boolean)[]>;
|
|
1074
1076
|
/**
|
|
1075
1077
|
A facet that determines which [decorations](https://codemirror.net/6/docs/ref/#view.Decoration)
|
|
1076
1078
|
are shown in the view. See also [view
|
|
1077
1079
|
plugins](https://codemirror.net/6/docs/ref/#view.EditorView^decorations), which have a separate
|
|
1078
1080
|
mechanism for providing decorations.
|
|
1079
1081
|
*/
|
|
1080
|
-
static decorations:
|
|
1082
|
+
static decorations: Facet<DecorationSet, readonly DecorationSet[]>;
|
|
1081
1083
|
/**
|
|
1082
1084
|
Create a theme extension. The first argument can be a
|
|
1083
1085
|
[`style-mod`](https://github.com/marijnh/style-mod#documentation)
|
|
@@ -1115,12 +1117,12 @@ declare class EditorView {
|
|
|
1115
1117
|
Facet that provides additional DOM attributes for the editor's
|
|
1116
1118
|
editable DOM element.
|
|
1117
1119
|
*/
|
|
1118
|
-
static contentAttributes:
|
|
1120
|
+
static contentAttributes: Facet<AttrSource, readonly AttrSource[]>;
|
|
1119
1121
|
/**
|
|
1120
1122
|
Facet that provides DOM attributes for the editor's outer
|
|
1121
1123
|
element.
|
|
1122
1124
|
*/
|
|
1123
|
-
static editorAttributes:
|
|
1125
|
+
static editorAttributes: Facet<AttrSource, readonly AttrSource[]>;
|
|
1124
1126
|
/**
|
|
1125
1127
|
An extension that enables line wrapping in the editor (by
|
|
1126
1128
|
setting CSS `white-space` to `pre-wrap` in the content).
|
|
@@ -1318,10 +1320,10 @@ Configuration options.
|
|
|
1318
1320
|
config?: SpecialCharConfig): Extension;
|
|
1319
1321
|
|
|
1320
1322
|
/**
|
|
1321
|
-
Returns
|
|
1322
|
-
equivalent to the height of the editor, minus one line
|
|
1323
|
-
that every line in the document can be scrolled to the
|
|
1324
|
-
editor.
|
|
1323
|
+
Returns an extension that makes sure the content has a bottom
|
|
1324
|
+
margin equivalent to the height of the editor, minus one line
|
|
1325
|
+
height, so that every line in the document can be scrolled to the
|
|
1326
|
+
top of the editor.
|
|
1325
1327
|
|
|
1326
1328
|
This is only meaningful when the editor is scrollable, and should
|
|
1327
1329
|
not be enabled in editors that take the size of their content.
|
package/dist/index.js
CHANGED
|
@@ -1082,8 +1082,9 @@ class Decoration extends RangeValue {
|
|
|
1082
1082
|
position.
|
|
1083
1083
|
*/
|
|
1084
1084
|
static widget(spec) {
|
|
1085
|
-
let side = spec.side || 0;
|
|
1086
|
-
|
|
1085
|
+
let side = spec.side || 0, block = !!spec.block;
|
|
1086
|
+
side += block ? (side > 0 ? 300000000 /* BlockAfter */ : -400000000 /* BlockBefore */) : (side > 0 ? 100000000 /* InlineAfter */ : -100000000 /* InlineBefore */);
|
|
1087
|
+
return new PointDecoration(spec, side, side, block, spec.widget || null, false);
|
|
1087
1088
|
}
|
|
1088
1089
|
/**
|
|
1089
1090
|
Create a replace decoration which replaces the given range with
|
|
@@ -1092,8 +1093,8 @@ class Decoration extends RangeValue {
|
|
|
1092
1093
|
static replace(spec) {
|
|
1093
1094
|
let block = !!spec.block;
|
|
1094
1095
|
let { start, end } = getInclusive(spec, block);
|
|
1095
|
-
let startSide =
|
|
1096
|
-
let endSide =
|
|
1096
|
+
let startSide = block ? (start ? -300000000 /* BlockIncStart */ : -1 /* InlineIncStart */) : 400000000 /* NonIncStart */;
|
|
1097
|
+
let endSide = block ? (end ? 200000000 /* BlockIncEnd */ : 1 /* InlineIncEnd */) : -500000000 /* NonIncEnd */;
|
|
1097
1098
|
return new PointDecoration(spec, startSide, endSide, block, spec.widget || null, true);
|
|
1098
1099
|
}
|
|
1099
1100
|
/**
|
|
@@ -1123,7 +1124,7 @@ Decoration.none = RangeSet.empty;
|
|
|
1123
1124
|
class MarkDecoration extends Decoration {
|
|
1124
1125
|
constructor(spec) {
|
|
1125
1126
|
let { start, end } = getInclusive(spec);
|
|
1126
|
-
super(
|
|
1127
|
+
super(start ? -1 /* InlineIncStart */ : 400000000 /* NonIncStart */, end ? 1 /* InlineIncEnd */ : -500000000 /* NonIncEnd */, null, spec);
|
|
1127
1128
|
this.tagName = spec.tagName || "span";
|
|
1128
1129
|
this.class = spec.class || "";
|
|
1129
1130
|
this.attrs = spec.attributes || null;
|
|
@@ -1144,7 +1145,7 @@ class MarkDecoration extends Decoration {
|
|
|
1144
1145
|
MarkDecoration.prototype.point = false;
|
|
1145
1146
|
class LineDecoration extends Decoration {
|
|
1146
1147
|
constructor(spec) {
|
|
1147
|
-
super(-
|
|
1148
|
+
super(-200000000 /* Line */, -200000000 /* Line */, null, spec);
|
|
1148
1149
|
}
|
|
1149
1150
|
eq(other) {
|
|
1150
1151
|
return other instanceof LineDecoration && attrsEq(this.spec.attributes, other.spec.attributes);
|
|
@@ -1723,36 +1724,39 @@ class PluginInstance {
|
|
|
1723
1724
|
this.value = null;
|
|
1724
1725
|
}
|
|
1725
1726
|
takeField(type, target) {
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1727
|
+
if (this.spec)
|
|
1728
|
+
for (let { field, get } of this.spec.fields)
|
|
1729
|
+
if (field == type)
|
|
1730
|
+
target.push(get(this.value));
|
|
1729
1731
|
}
|
|
1730
1732
|
update(view) {
|
|
1731
1733
|
if (!this.value) {
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1734
|
+
if (this.spec) {
|
|
1735
|
+
try {
|
|
1736
|
+
this.value = this.spec.create(view);
|
|
1737
|
+
}
|
|
1738
|
+
catch (e) {
|
|
1739
|
+
logException(view.state, e, "CodeMirror plugin crashed");
|
|
1740
|
+
this.deactivate();
|
|
1741
|
+
}
|
|
1738
1742
|
}
|
|
1739
1743
|
}
|
|
1740
1744
|
else if (this.mustUpdate) {
|
|
1741
1745
|
let update = this.mustUpdate;
|
|
1742
1746
|
this.mustUpdate = null;
|
|
1743
|
-
if (
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1747
|
+
if (this.value.update) {
|
|
1748
|
+
try {
|
|
1749
|
+
this.value.update(update);
|
|
1750
|
+
}
|
|
1751
|
+
catch (e) {
|
|
1752
|
+
logException(update.state, e, "CodeMirror plugin crashed");
|
|
1753
|
+
if (this.value.destroy)
|
|
1754
|
+
try {
|
|
1755
|
+
this.value.destroy();
|
|
1756
|
+
}
|
|
1757
|
+
catch (_) { }
|
|
1758
|
+
this.deactivate();
|
|
1759
|
+
}
|
|
1756
1760
|
}
|
|
1757
1761
|
}
|
|
1758
1762
|
return this;
|
|
@@ -1768,20 +1772,12 @@ class PluginInstance {
|
|
|
1768
1772
|
}
|
|
1769
1773
|
}
|
|
1770
1774
|
}
|
|
1775
|
+
deactivate() {
|
|
1776
|
+
this.spec = this.value = null;
|
|
1777
|
+
}
|
|
1771
1778
|
}
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
let result = {};
|
|
1775
|
-
for (let i = values.length - 1; i >= 0; i--)
|
|
1776
|
-
combineAttrs(values[i], result);
|
|
1777
|
-
return result;
|
|
1778
|
-
}
|
|
1779
|
-
const editorAttributes = /*@__PURE__*/Facet.define({
|
|
1780
|
-
combine: combineFacetAttrs
|
|
1781
|
-
});
|
|
1782
|
-
const contentAttributes = /*@__PURE__*/Facet.define({
|
|
1783
|
-
combine: combineFacetAttrs
|
|
1784
|
-
});
|
|
1779
|
+
const editorAttributes = /*@__PURE__*/Facet.define();
|
|
1780
|
+
const contentAttributes = /*@__PURE__*/Facet.define();
|
|
1785
1781
|
// Provide decorations
|
|
1786
1782
|
const decorations = /*@__PURE__*/Facet.define();
|
|
1787
1783
|
const styleModule = /*@__PURE__*/Facet.define();
|
|
@@ -1929,12 +1925,12 @@ class DocView extends ContentView {
|
|
|
1929
1925
|
this.compositionDeco = Decoration.none;
|
|
1930
1926
|
this.decorations = [];
|
|
1931
1927
|
// Track a minimum width for the editor. When measuring sizes in
|
|
1932
|
-
//
|
|
1933
|
-
// element and its extent in the document. When a change
|
|
1934
|
-
// that range, these are reset. That way, once we've seen
|
|
1935
|
-
// line/element of a given length, we keep the editor wide enough
|
|
1936
|
-
// fit at least that element, until it is changed, at which point
|
|
1937
|
-
// forget it again.
|
|
1928
|
+
// measureVisibleLineHeights, this is updated to point at the width
|
|
1929
|
+
// of a given element and its extent in the document. When a change
|
|
1930
|
+
// happens in that range, these are reset. That way, once we've seen
|
|
1931
|
+
// a line/element of a given length, we keep the editor wide enough
|
|
1932
|
+
// to fit at least that element, until it is changed, at which point
|
|
1933
|
+
// we forget it again.
|
|
1938
1934
|
this.minWidth = 0;
|
|
1939
1935
|
this.minWidthFrom = 0;
|
|
1940
1936
|
this.minWidthTo = 0;
|
|
@@ -2004,7 +2000,7 @@ class DocView extends ContentView {
|
|
|
2004
2000
|
this.updateSelection();
|
|
2005
2001
|
}
|
|
2006
2002
|
}
|
|
2007
|
-
// Used
|
|
2003
|
+
// Used by update and the constructor do perform the actual DOM
|
|
2008
2004
|
// update
|
|
2009
2005
|
updateInner(changes, deco, oldLength) {
|
|
2010
2006
|
this.view.viewState.mustMeasureContent = true;
|
|
@@ -2926,7 +2922,7 @@ function posAtCoords(view, { x, y }, precise, bias = -1) {
|
|
|
2926
2922
|
y = docTop + yOffset;
|
|
2927
2923
|
let lineStart = block.from;
|
|
2928
2924
|
// Clip x to the viewport sides
|
|
2929
|
-
x = Math.max(content.left + 1, Math.min(content.right - 1, x));
|
|
2925
|
+
x = Math.max(content.left + 1, Math.min(Math.max(content.right, content.left + view.docView.minWidth) - 1, x));
|
|
2930
2926
|
// If this is outside of the rendered viewport, we can't determine a position
|
|
2931
2927
|
if (lineStart < view.viewport.from)
|
|
2932
2928
|
return view.viewport.from == 0 ? 0 : posAtCoordsImprecise(view, content, block, x, y);
|
|
@@ -5059,7 +5055,7 @@ const baseTheme = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5059
5055
|
color: "inherit",
|
|
5060
5056
|
fontSize: "70%",
|
|
5061
5057
|
padding: ".2em 1em",
|
|
5062
|
-
borderRadius: "
|
|
5058
|
+
borderRadius: "1px"
|
|
5063
5059
|
},
|
|
5064
5060
|
"&light .cm-button": {
|
|
5065
5061
|
backgroundImage: "linear-gradient(#eff1f5, #d9d9df)",
|
|
@@ -5381,6 +5377,7 @@ class DOMObserver {
|
|
|
5381
5377
|
for (let dom of this.scrollTargets)
|
|
5382
5378
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5383
5379
|
window.removeEventListener("scroll", this.onScroll);
|
|
5380
|
+
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5384
5381
|
clearTimeout(this.parentCheck);
|
|
5385
5382
|
clearTimeout(this.resizeTimeout);
|
|
5386
5383
|
}
|
|
@@ -5677,6 +5674,7 @@ class EditorView {
|
|
|
5677
5674
|
*/
|
|
5678
5675
|
config = {}) {
|
|
5679
5676
|
this.plugins = [];
|
|
5677
|
+
this.pluginMap = new Map;
|
|
5680
5678
|
this.editorAttrs = {};
|
|
5681
5679
|
this.contentAttrs = {};
|
|
5682
5680
|
this.bidiCache = [];
|
|
@@ -5846,6 +5844,7 @@ class EditorView {
|
|
|
5846
5844
|
plugin.destroy(this);
|
|
5847
5845
|
this.viewState = new ViewState(newState);
|
|
5848
5846
|
this.plugins = newState.facet(viewPlugin).map(spec => new PluginInstance(spec).update(this));
|
|
5847
|
+
this.pluginMap.clear();
|
|
5849
5848
|
this.docView = new DocView(this);
|
|
5850
5849
|
this.inputState.ensureHandlers(this);
|
|
5851
5850
|
this.mountStyles();
|
|
@@ -5876,6 +5875,7 @@ class EditorView {
|
|
|
5876
5875
|
if (plugin.mustUpdate != update)
|
|
5877
5876
|
plugin.destroy(this);
|
|
5878
5877
|
this.plugins = newPlugins;
|
|
5878
|
+
this.pluginMap.clear();
|
|
5879
5879
|
this.inputState.ensureHandlers(this);
|
|
5880
5880
|
}
|
|
5881
5881
|
else {
|
|
@@ -5883,7 +5883,7 @@ class EditorView {
|
|
|
5883
5883
|
p.mustUpdate = update;
|
|
5884
5884
|
}
|
|
5885
5885
|
for (let i = 0; i < this.plugins.length; i++)
|
|
5886
|
-
this.plugins[i]
|
|
5886
|
+
this.plugins[i].update(this);
|
|
5887
5887
|
}
|
|
5888
5888
|
/**
|
|
5889
5889
|
@internal
|
|
@@ -5972,7 +5972,7 @@ class EditorView {
|
|
|
5972
5972
|
this.state.facet(theme);
|
|
5973
5973
|
}
|
|
5974
5974
|
updateAttrs() {
|
|
5975
|
-
let editorAttrs =
|
|
5975
|
+
let editorAttrs = attrsFromFacet(this, editorAttributes, {
|
|
5976
5976
|
class: "cm-editor" + (this.hasFocus ? " cm-focused " : " ") + this.themeClasses
|
|
5977
5977
|
});
|
|
5978
5978
|
let contentAttrs = {
|
|
@@ -5988,7 +5988,7 @@ class EditorView {
|
|
|
5988
5988
|
};
|
|
5989
5989
|
if (this.state.readOnly)
|
|
5990
5990
|
contentAttrs["aria-readonly"] = "true";
|
|
5991
|
-
|
|
5991
|
+
attrsFromFacet(this, contentAttributes, contentAttrs);
|
|
5992
5992
|
this.observer.ignore(() => {
|
|
5993
5993
|
updateAttrs(this.contentDOM, this.contentAttrs, contentAttrs);
|
|
5994
5994
|
updateAttrs(this.dom, this.editorAttrs, editorAttrs);
|
|
@@ -6057,10 +6057,10 @@ class EditorView {
|
|
|
6057
6057
|
the return value of this method.
|
|
6058
6058
|
*/
|
|
6059
6059
|
plugin(plugin) {
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
return
|
|
6060
|
+
let known = this.pluginMap.get(plugin);
|
|
6061
|
+
if (known === undefined || known && known.spec != plugin)
|
|
6062
|
+
this.pluginMap.set(plugin, known = this.plugins.find(p => p.spec == plugin) || null);
|
|
6063
|
+
return known && known.update(this).value;
|
|
6064
6064
|
}
|
|
6065
6065
|
/**
|
|
6066
6066
|
The top position of the document, in screen coordinates. This
|
|
@@ -6547,6 +6547,14 @@ class CachedOrder {
|
|
|
6547
6547
|
return result;
|
|
6548
6548
|
}
|
|
6549
6549
|
}
|
|
6550
|
+
function attrsFromFacet(view, facet, base) {
|
|
6551
|
+
for (let sources = view.state.facet(facet), i = sources.length - 1; i >= 0; i--) {
|
|
6552
|
+
let source = sources[i], value = typeof source == "function" ? source(view) : source;
|
|
6553
|
+
if (value)
|
|
6554
|
+
combineAttrs(value, base);
|
|
6555
|
+
}
|
|
6556
|
+
return base;
|
|
6557
|
+
}
|
|
6550
6558
|
|
|
6551
6559
|
const currentPlatform = browser.mac ? "mac" : browser.windows ? "win" : browser.linux ? "linux" : "key";
|
|
6552
6560
|
function normalizeKeyName(name, platform) {
|
|
@@ -7199,35 +7207,29 @@ class TabWidget extends WidgetType {
|
|
|
7199
7207
|
}
|
|
7200
7208
|
|
|
7201
7209
|
const plugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
7202
|
-
constructor(
|
|
7203
|
-
this.height =
|
|
7204
|
-
this.
|
|
7205
|
-
read: view => Math.max(0, view.scrollDOM.clientHeight - view.defaultLineHeight),
|
|
7206
|
-
write: (value, view) => {
|
|
7207
|
-
if (Math.abs(value - this.height) > 1) {
|
|
7208
|
-
this.height = value;
|
|
7209
|
-
view.contentDOM.style.paddingBottom = value + "px";
|
|
7210
|
-
}
|
|
7211
|
-
}
|
|
7212
|
-
};
|
|
7213
|
-
view.requestMeasure(this.measure);
|
|
7210
|
+
constructor() {
|
|
7211
|
+
this.height = 1000;
|
|
7212
|
+
this.attrs = { style: "padding-bottom: 1000px" };
|
|
7214
7213
|
}
|
|
7215
7214
|
update(update) {
|
|
7216
|
-
|
|
7217
|
-
|
|
7215
|
+
let height = update.view.viewState.editorHeight - update.view.defaultLineHeight;
|
|
7216
|
+
if (height != this.height) {
|
|
7217
|
+
this.height = height;
|
|
7218
|
+
this.attrs = { style: `padding-bottom: ${height}px` };
|
|
7219
|
+
}
|
|
7218
7220
|
}
|
|
7219
7221
|
});
|
|
7220
7222
|
/**
|
|
7221
|
-
Returns
|
|
7222
|
-
equivalent to the height of the editor, minus one line
|
|
7223
|
-
that every line in the document can be scrolled to the
|
|
7224
|
-
editor.
|
|
7223
|
+
Returns an extension that makes sure the content has a bottom
|
|
7224
|
+
margin equivalent to the height of the editor, minus one line
|
|
7225
|
+
height, so that every line in the document can be scrolled to the
|
|
7226
|
+
top of the editor.
|
|
7225
7227
|
|
|
7226
7228
|
This is only meaningful when the editor is scrollable, and should
|
|
7227
7229
|
not be enabled in editors that take the size of their content.
|
|
7228
7230
|
*/
|
|
7229
7231
|
function scrollPastEnd() {
|
|
7230
|
-
return plugin;
|
|
7232
|
+
return [plugin, contentAttributes.of(view => { var _a; return ((_a = view.plugin(plugin)) === null || _a === void 0 ? void 0 : _a.attrs) || null; })];
|
|
7231
7233
|
}
|
|
7232
7234
|
|
|
7233
7235
|
/**
|