@codemirror/view 6.5.1 → 6.6.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 +8 -0
- package/dist/index.cjs +170 -96
- package/dist/index.d.ts +81 -1
- package/dist/index.js +169 -97
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 6.6.0 (2022-11-24)
|
|
2
|
+
|
|
3
|
+
### New features
|
|
4
|
+
|
|
5
|
+
The `layer` function can now be used to define extensions that draw DOM elements over or below the document text.
|
|
6
|
+
|
|
7
|
+
Tooltips that are bigger than the available vertical space for them will now have their height set so that they don't stick out of the window. The new `resize` property on `TooltipView` can be used to opt out of this behavior.
|
|
8
|
+
|
|
1
9
|
## 6.5.1 (2022-11-15)
|
|
2
10
|
|
|
3
11
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -5313,14 +5313,13 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5313
5313
|
"&dark .cm-content": { caretColor: "white" },
|
|
5314
5314
|
".cm-line": {
|
|
5315
5315
|
display: "block",
|
|
5316
|
-
padding: "0 2px 0
|
|
5316
|
+
padding: "0 2px 0 6px"
|
|
5317
5317
|
},
|
|
5318
|
-
".cm-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
position: "absolute",
|
|
5318
|
+
".cm-layer": {
|
|
5319
|
+
contain: "size style",
|
|
5320
|
+
"& > *": {
|
|
5321
|
+
position: "absolute"
|
|
5322
|
+
}
|
|
5324
5323
|
},
|
|
5325
5324
|
"&light .cm-selectionBackground": {
|
|
5326
5325
|
background: "#d9d9d9"
|
|
@@ -5335,8 +5334,6 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5335
5334
|
background: "#233"
|
|
5336
5335
|
},
|
|
5337
5336
|
".cm-cursorLayer": {
|
|
5338
|
-
zIndex: 100,
|
|
5339
|
-
contain: "size style",
|
|
5340
5337
|
pointerEvents: "none"
|
|
5341
5338
|
},
|
|
5342
5339
|
"&.cm-focused .cm-cursorLayer": {
|
|
@@ -5348,7 +5345,6 @@ const baseTheme$1 = buildTheme("." + baseThemeID, {
|
|
|
5348
5345
|
"@keyframes cm-blink": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
|
|
5349
5346
|
"@keyframes cm-blink2": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
|
|
5350
5347
|
".cm-cursor, .cm-dropCursor": {
|
|
5351
|
-
position: "absolute",
|
|
5352
5348
|
borderLeft: "1.2px solid black",
|
|
5353
5349
|
marginLeft: "-0.6px",
|
|
5354
5350
|
pointerEvents: "none",
|
|
@@ -7294,6 +7290,117 @@ function runHandlers(map, event, view, scope) {
|
|
|
7294
7290
|
return fallthrough;
|
|
7295
7291
|
}
|
|
7296
7292
|
|
|
7293
|
+
/**
|
|
7294
|
+
Implementation of [`LayerMarker`](https://codemirror.net/6/docs/ref/#view.LayerMarker) that creates
|
|
7295
|
+
a rectangle at a given set of coordinates.
|
|
7296
|
+
*/
|
|
7297
|
+
class RectangleMarker {
|
|
7298
|
+
/**
|
|
7299
|
+
Create a marker with the given class and dimensions.
|
|
7300
|
+
*/
|
|
7301
|
+
constructor(className, left, top, width, height) {
|
|
7302
|
+
this.className = className;
|
|
7303
|
+
this.left = left;
|
|
7304
|
+
this.top = top;
|
|
7305
|
+
this.width = width;
|
|
7306
|
+
this.height = height;
|
|
7307
|
+
}
|
|
7308
|
+
draw() {
|
|
7309
|
+
let elt = document.createElement("div");
|
|
7310
|
+
elt.className = this.className;
|
|
7311
|
+
this.adjust(elt);
|
|
7312
|
+
return elt;
|
|
7313
|
+
}
|
|
7314
|
+
update(elt, prev) {
|
|
7315
|
+
if (prev.className != this.className)
|
|
7316
|
+
return false;
|
|
7317
|
+
this.adjust(elt);
|
|
7318
|
+
return true;
|
|
7319
|
+
}
|
|
7320
|
+
adjust(elt) {
|
|
7321
|
+
elt.style.left = this.left + "px";
|
|
7322
|
+
elt.style.top = this.top + "px";
|
|
7323
|
+
if (this.width >= 0)
|
|
7324
|
+
elt.style.width = this.width + "px";
|
|
7325
|
+
elt.style.height = this.height + "px";
|
|
7326
|
+
}
|
|
7327
|
+
eq(p) {
|
|
7328
|
+
return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height &&
|
|
7329
|
+
this.className == p.className;
|
|
7330
|
+
}
|
|
7331
|
+
}
|
|
7332
|
+
function sameMarker(a, b) {
|
|
7333
|
+
return a.constructor == b.constructor && a.eq(b);
|
|
7334
|
+
}
|
|
7335
|
+
class LayerView {
|
|
7336
|
+
constructor(view, layer) {
|
|
7337
|
+
this.view = view;
|
|
7338
|
+
this.layer = layer;
|
|
7339
|
+
this.drawn = [];
|
|
7340
|
+
this.measureReq = { read: this.measure.bind(this), write: this.draw.bind(this) };
|
|
7341
|
+
this.dom = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7342
|
+
this.dom.classList.add("cm-layer");
|
|
7343
|
+
if (layer.above)
|
|
7344
|
+
this.dom.classList.add("cm-layer-above");
|
|
7345
|
+
if (layer.class)
|
|
7346
|
+
this.dom.classList.add(layer.class);
|
|
7347
|
+
this.dom.setAttribute("aria-hidden", "true");
|
|
7348
|
+
this.setOrder(view.state);
|
|
7349
|
+
view.requestMeasure(this.measureReq);
|
|
7350
|
+
if (layer.mount)
|
|
7351
|
+
layer.mount(this.dom, view);
|
|
7352
|
+
}
|
|
7353
|
+
update(update) {
|
|
7354
|
+
if (update.startState.facet(layerOrder) != update.state.facet(layerOrder))
|
|
7355
|
+
this.setOrder(update.state);
|
|
7356
|
+
if (this.layer.update(update, this.dom) || update.geometryChanged)
|
|
7357
|
+
update.view.requestMeasure(this.measureReq);
|
|
7358
|
+
}
|
|
7359
|
+
setOrder(state) {
|
|
7360
|
+
let pos = 0, order = state.facet(layerOrder);
|
|
7361
|
+
while (pos < order.length && order[pos] != this.layer)
|
|
7362
|
+
pos++;
|
|
7363
|
+
this.dom.style.zIndex = String((this.layer.above ? 150 : -1) - pos);
|
|
7364
|
+
}
|
|
7365
|
+
measure() {
|
|
7366
|
+
return this.layer.markers(this.view);
|
|
7367
|
+
}
|
|
7368
|
+
draw(markers) {
|
|
7369
|
+
if (markers.length != this.drawn.length || markers.some((p, i) => !sameMarker(p, this.drawn[i]))) {
|
|
7370
|
+
let old = this.dom.firstChild, oldI = 0;
|
|
7371
|
+
for (let marker of markers) {
|
|
7372
|
+
if (marker.update && old && marker.constructor && this.drawn[oldI].constructor &&
|
|
7373
|
+
marker.update(old, this.drawn[oldI])) {
|
|
7374
|
+
old = old.nextSibling;
|
|
7375
|
+
oldI++;
|
|
7376
|
+
}
|
|
7377
|
+
else {
|
|
7378
|
+
this.dom.insertBefore(marker.draw(), old);
|
|
7379
|
+
}
|
|
7380
|
+
}
|
|
7381
|
+
while (old) {
|
|
7382
|
+
let next = old.nextSibling;
|
|
7383
|
+
old.remove();
|
|
7384
|
+
old = next;
|
|
7385
|
+
}
|
|
7386
|
+
this.drawn = markers;
|
|
7387
|
+
}
|
|
7388
|
+
}
|
|
7389
|
+
destroy() {
|
|
7390
|
+
this.dom.remove();
|
|
7391
|
+
}
|
|
7392
|
+
}
|
|
7393
|
+
const layerOrder = state.Facet.define();
|
|
7394
|
+
/**
|
|
7395
|
+
Define a layer.
|
|
7396
|
+
*/
|
|
7397
|
+
function layer(config) {
|
|
7398
|
+
return [
|
|
7399
|
+
ViewPlugin.define(v => new LayerView(v, config)),
|
|
7400
|
+
layerOrder.of(config)
|
|
7401
|
+
];
|
|
7402
|
+
}
|
|
7403
|
+
|
|
7297
7404
|
const CanHidePrimary = !browser.ios; // FIXME test IE
|
|
7298
7405
|
const selectionConfig = state.Facet.define({
|
|
7299
7406
|
combine(configs) {
|
|
@@ -7327,102 +7434,55 @@ content).
|
|
|
7327
7434
|
function drawSelection(config = {}) {
|
|
7328
7435
|
return [
|
|
7329
7436
|
selectionConfig.of(config),
|
|
7330
|
-
|
|
7437
|
+
cursorLayer,
|
|
7438
|
+
selectionLayer,
|
|
7331
7439
|
hideNativeSelection,
|
|
7332
7440
|
nativeSelectionHidden.of(true)
|
|
7333
7441
|
];
|
|
7334
7442
|
}
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
this.left = left;
|
|
7338
|
-
this.top = top;
|
|
7339
|
-
this.width = width;
|
|
7340
|
-
this.height = height;
|
|
7341
|
-
this.className = className;
|
|
7342
|
-
}
|
|
7343
|
-
draw() {
|
|
7344
|
-
let elt = document.createElement("div");
|
|
7345
|
-
elt.className = this.className;
|
|
7346
|
-
this.adjust(elt);
|
|
7347
|
-
return elt;
|
|
7348
|
-
}
|
|
7349
|
-
adjust(elt) {
|
|
7350
|
-
elt.style.left = this.left + "px";
|
|
7351
|
-
elt.style.top = this.top + "px";
|
|
7352
|
-
if (this.width >= 0)
|
|
7353
|
-
elt.style.width = this.width + "px";
|
|
7354
|
-
elt.style.height = this.height + "px";
|
|
7355
|
-
}
|
|
7356
|
-
eq(p) {
|
|
7357
|
-
return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height &&
|
|
7358
|
-
this.className == p.className;
|
|
7359
|
-
}
|
|
7443
|
+
function configChanged(update) {
|
|
7444
|
+
return update.startState.facet(selectionConfig) != update.startState.facet(selectionConfig);
|
|
7360
7445
|
}
|
|
7361
|
-
const
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
this.cursors = [];
|
|
7366
|
-
this.measureReq = { read: this.readPos.bind(this), write: this.drawSel.bind(this) };
|
|
7367
|
-
this.selectionLayer = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7368
|
-
this.selectionLayer.className = "cm-selectionLayer";
|
|
7369
|
-
this.selectionLayer.setAttribute("aria-hidden", "true");
|
|
7370
|
-
this.cursorLayer = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7371
|
-
this.cursorLayer.className = "cm-cursorLayer";
|
|
7372
|
-
this.cursorLayer.setAttribute("aria-hidden", "true");
|
|
7373
|
-
view.requestMeasure(this.measureReq);
|
|
7374
|
-
this.setBlinkRate();
|
|
7375
|
-
}
|
|
7376
|
-
setBlinkRate() {
|
|
7377
|
-
this.cursorLayer.style.animationDuration = this.view.state.facet(selectionConfig).cursorBlinkRate + "ms";
|
|
7378
|
-
}
|
|
7379
|
-
update(update) {
|
|
7380
|
-
let confChanged = update.startState.facet(selectionConfig) != update.state.facet(selectionConfig);
|
|
7381
|
-
if (confChanged || update.selectionSet || update.geometryChanged || update.viewportChanged)
|
|
7382
|
-
this.view.requestMeasure(this.measureReq);
|
|
7383
|
-
if (update.transactions.some(tr => tr.scrollIntoView))
|
|
7384
|
-
this.cursorLayer.style.animationName = this.cursorLayer.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
|
|
7385
|
-
if (confChanged)
|
|
7386
|
-
this.setBlinkRate();
|
|
7387
|
-
}
|
|
7388
|
-
readPos() {
|
|
7389
|
-
let { state } = this.view, conf = state.facet(selectionConfig);
|
|
7390
|
-
let rangePieces = state.selection.ranges.map(r => r.empty ? [] : measureRange(this.view, r)).reduce((a, b) => a.concat(b));
|
|
7446
|
+
const cursorLayer = layer({
|
|
7447
|
+
above: true,
|
|
7448
|
+
markers(view) {
|
|
7449
|
+
let { state } = view, conf = state.facet(selectionConfig);
|
|
7391
7450
|
let cursors = [];
|
|
7392
7451
|
for (let r of state.selection.ranges) {
|
|
7393
7452
|
let prim = r == state.selection.main;
|
|
7394
7453
|
if (r.empty ? !prim || CanHidePrimary : conf.drawRangeCursor) {
|
|
7395
|
-
let piece = measureCursor(
|
|
7454
|
+
let piece = measureCursor(view, r, prim);
|
|
7396
7455
|
if (piece)
|
|
7397
7456
|
cursors.push(piece);
|
|
7398
7457
|
}
|
|
7399
7458
|
}
|
|
7400
|
-
return
|
|
7401
|
-
}
|
|
7402
|
-
|
|
7403
|
-
if (
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
}
|
|
7459
|
+
return cursors;
|
|
7460
|
+
},
|
|
7461
|
+
update(update, dom) {
|
|
7462
|
+
if (update.transactions.some(tr => tr.scrollIntoView))
|
|
7463
|
+
dom.style.animationName = dom.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
|
|
7464
|
+
let confChange = configChanged(update);
|
|
7465
|
+
if (confChange)
|
|
7466
|
+
setBlinkRate(update.state, dom);
|
|
7467
|
+
return update.docChanged || update.selectionSet || confChange;
|
|
7468
|
+
},
|
|
7469
|
+
mount(dom, view) {
|
|
7470
|
+
setBlinkRate(view.state, dom);
|
|
7471
|
+
},
|
|
7472
|
+
class: "cm-cursorLayer"
|
|
7473
|
+
});
|
|
7474
|
+
function setBlinkRate(state, dom) {
|
|
7475
|
+
dom.style.animationDuration = state.facet(selectionConfig).cursorBlinkRate + "ms";
|
|
7476
|
+
}
|
|
7477
|
+
const selectionLayer = layer({
|
|
7478
|
+
above: false,
|
|
7479
|
+
markers(view) {
|
|
7480
|
+
return view.state.selection.ranges.map(r => r.empty ? [] : measureRange(view, r)).reduce((a, b) => a.concat(b));
|
|
7481
|
+
},
|
|
7482
|
+
update(update, dom) {
|
|
7483
|
+
return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
|
|
7484
|
+
},
|
|
7485
|
+
class: "cm-selectionLayer"
|
|
7426
7486
|
});
|
|
7427
7487
|
const themeSpec = {
|
|
7428
7488
|
".cm-line": {
|
|
@@ -7485,7 +7545,7 @@ function measureRange(view, range) {
|
|
|
7485
7545
|
return pieces(top).concat(between).concat(pieces(bottom));
|
|
7486
7546
|
}
|
|
7487
7547
|
function piece(left, top, right, bottom) {
|
|
7488
|
-
return new
|
|
7548
|
+
return new RectangleMarker("cm-selectionBackground", left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
|
|
7489
7549
|
}
|
|
7490
7550
|
function pieces({ top, bottom, horizontal }) {
|
|
7491
7551
|
let pieces = [];
|
|
@@ -7542,7 +7602,7 @@ function measureCursor(view, cursor, primary) {
|
|
|
7542
7602
|
if (!pos)
|
|
7543
7603
|
return null;
|
|
7544
7604
|
let base = getBase(view);
|
|
7545
|
-
return new
|
|
7605
|
+
return new RectangleMarker(primary ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary", pos.left - base.left, pos.top - base.top, -1, pos.bottom - pos.top);
|
|
7546
7606
|
}
|
|
7547
7607
|
|
|
7548
7608
|
const setDropCursorPos = state.StateEffect.define({
|
|
@@ -8336,6 +8396,17 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8336
8396
|
: pos.bottom + (size.bottom - size.top) + offset.y > space.bottom) &&
|
|
8337
8397
|
above == (space.bottom - pos.bottom > pos.top - space.top))
|
|
8338
8398
|
above = !above;
|
|
8399
|
+
let spaceVert = (above ? pos.top - space.top : space.bottom - pos.bottom) - arrowHeight;
|
|
8400
|
+
if (spaceVert < height && tView.resize !== false) {
|
|
8401
|
+
if (spaceVert < this.view.defaultLineHeight) {
|
|
8402
|
+
dom.style.top = Outside;
|
|
8403
|
+
continue;
|
|
8404
|
+
}
|
|
8405
|
+
dom.style.height = (height = spaceVert) + "px";
|
|
8406
|
+
}
|
|
8407
|
+
else if (dom.style.height) {
|
|
8408
|
+
dom.style.height = "";
|
|
8409
|
+
}
|
|
8339
8410
|
let top = above ? pos.top - height - arrowHeight - offset.y : pos.bottom + arrowHeight + offset.y;
|
|
8340
8411
|
let right = left + width;
|
|
8341
8412
|
if (tView.overlap !== true)
|
|
@@ -8379,7 +8450,8 @@ const tooltipPlugin = ViewPlugin.fromClass(class {
|
|
|
8379
8450
|
});
|
|
8380
8451
|
const baseTheme = EditorView.baseTheme({
|
|
8381
8452
|
".cm-tooltip": {
|
|
8382
|
-
zIndex: 100
|
|
8453
|
+
zIndex: 100,
|
|
8454
|
+
boxSizing: "border-box"
|
|
8383
8455
|
},
|
|
8384
8456
|
"&light .cm-tooltip": {
|
|
8385
8457
|
border: "1px solid #bbb",
|
|
@@ -9309,6 +9381,7 @@ exports.Decoration = Decoration;
|
|
|
9309
9381
|
exports.EditorView = EditorView;
|
|
9310
9382
|
exports.GutterMarker = GutterMarker;
|
|
9311
9383
|
exports.MatchDecorator = MatchDecorator;
|
|
9384
|
+
exports.RectangleMarker = RectangleMarker;
|
|
9312
9385
|
exports.ViewPlugin = ViewPlugin;
|
|
9313
9386
|
exports.ViewUpdate = ViewUpdate;
|
|
9314
9387
|
exports.WidgetType = WidgetType;
|
|
@@ -9328,6 +9401,7 @@ exports.highlightActiveLineGutter = highlightActiveLineGutter;
|
|
|
9328
9401
|
exports.highlightSpecialChars = highlightSpecialChars;
|
|
9329
9402
|
exports.hoverTooltip = hoverTooltip;
|
|
9330
9403
|
exports.keymap = keymap;
|
|
9404
|
+
exports.layer = layer;
|
|
9331
9405
|
exports.lineNumberMarkers = lineNumberMarkers;
|
|
9332
9406
|
exports.lineNumbers = lineNumbers;
|
|
9333
9407
|
exports.logException = logException;
|
package/dist/index.d.ts
CHANGED
|
@@ -1366,6 +1366,80 @@ to show when the editor is empty.
|
|
|
1366
1366
|
*/
|
|
1367
1367
|
declare function placeholder(content: string | HTMLElement): Extension;
|
|
1368
1368
|
|
|
1369
|
+
/**
|
|
1370
|
+
Markers shown in a [layer](https://codemirror.net/6/docs/ref/#view.layer) must conform to this
|
|
1371
|
+
interface. They are created in a measuring phase, and have to
|
|
1372
|
+
contain all their positioning information, so that they can be
|
|
1373
|
+
drawn without further DOM layout reading.
|
|
1374
|
+
|
|
1375
|
+
Markers are automatically absolutely positioned. Their parent
|
|
1376
|
+
element has the same top-left corner as the document, so they
|
|
1377
|
+
should be positioned relative to the document.
|
|
1378
|
+
*/
|
|
1379
|
+
interface LayerMarker {
|
|
1380
|
+
/**
|
|
1381
|
+
Compare this marker to a marker of the same type. Used to avoid
|
|
1382
|
+
unnecessary redraws.
|
|
1383
|
+
*/
|
|
1384
|
+
eq(other: LayerMarker): boolean;
|
|
1385
|
+
/**
|
|
1386
|
+
Draw the marker to the DOM.
|
|
1387
|
+
*/
|
|
1388
|
+
draw(): HTMLElement;
|
|
1389
|
+
/**
|
|
1390
|
+
Update an existing marker of this type to this marker.
|
|
1391
|
+
*/
|
|
1392
|
+
update?(dom: HTMLElement, oldMarker: LayerMarker): boolean;
|
|
1393
|
+
}
|
|
1394
|
+
/**
|
|
1395
|
+
Implementation of [`LayerMarker`](https://codemirror.net/6/docs/ref/#view.LayerMarker) that creates
|
|
1396
|
+
a rectangle at a given set of coordinates.
|
|
1397
|
+
*/
|
|
1398
|
+
declare class RectangleMarker implements LayerMarker {
|
|
1399
|
+
private className;
|
|
1400
|
+
private left;
|
|
1401
|
+
private top;
|
|
1402
|
+
private width;
|
|
1403
|
+
private height;
|
|
1404
|
+
/**
|
|
1405
|
+
Create a marker with the given class and dimensions.
|
|
1406
|
+
*/
|
|
1407
|
+
constructor(className: string, left: number, top: number, width: number, height: number);
|
|
1408
|
+
draw(): HTMLDivElement;
|
|
1409
|
+
update(elt: HTMLElement, prev: RectangleMarker): boolean;
|
|
1410
|
+
private adjust;
|
|
1411
|
+
eq(p: RectangleMarker): boolean;
|
|
1412
|
+
}
|
|
1413
|
+
interface LayerConfig {
|
|
1414
|
+
/**
|
|
1415
|
+
Determines whether this layer is shown above or below the text.
|
|
1416
|
+
*/
|
|
1417
|
+
above: boolean;
|
|
1418
|
+
/**
|
|
1419
|
+
When given, this class is added to the DOM element that will
|
|
1420
|
+
wrap the markers.
|
|
1421
|
+
*/
|
|
1422
|
+
class?: string;
|
|
1423
|
+
/**
|
|
1424
|
+
Called on every view update. Returning true triggers a marker
|
|
1425
|
+
update (a call to `markers` and drawing of those markers).
|
|
1426
|
+
*/
|
|
1427
|
+
update(update: ViewUpdate, layer: HTMLElement): boolean;
|
|
1428
|
+
/**
|
|
1429
|
+
Build a set of markers for this layer, and measure their
|
|
1430
|
+
dimensions.
|
|
1431
|
+
*/
|
|
1432
|
+
markers(view: EditorView): readonly LayerMarker[];
|
|
1433
|
+
/**
|
|
1434
|
+
If given, this is called when the layer is created.
|
|
1435
|
+
*/
|
|
1436
|
+
mount?(layer: HTMLElement, view: EditorView): void;
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
Define a layer.
|
|
1440
|
+
*/
|
|
1441
|
+
declare function layer(config: LayerConfig): Extension;
|
|
1442
|
+
|
|
1369
1443
|
/**
|
|
1370
1444
|
Helper class used to make it easier to maintain decorations on
|
|
1371
1445
|
visible code that matches a given regular expression. To be used
|
|
@@ -1584,6 +1658,12 @@ interface TooltipView {
|
|
|
1584
1658
|
tooltip.
|
|
1585
1659
|
*/
|
|
1586
1660
|
positioned?(space: Rect): void;
|
|
1661
|
+
/**
|
|
1662
|
+
By default, the library will restrict the size of tooltips so
|
|
1663
|
+
that they don't stick out of the available space. Set this to
|
|
1664
|
+
false to disable that.
|
|
1665
|
+
*/
|
|
1666
|
+
resize?: boolean;
|
|
1587
1667
|
}
|
|
1588
1668
|
/**
|
|
1589
1669
|
Facet to which an extension can add a value to show a tooltip.
|
|
@@ -1820,4 +1900,4 @@ line](https://codemirror.net/6/docs/ref/#view.highlightActiveLine).
|
|
|
1820
1900
|
*/
|
|
1821
1901
|
declare function highlightActiveLineGutter(): Extension;
|
|
1822
1902
|
|
|
1823
|
-
export { BidiSpan, BlockInfo, BlockType, Command, DOMEventHandlers, DOMEventMap, Decoration, DecorationSet, Direction, EditorView, EditorViewConfig, GutterMarker, KeyBinding, MatchDecorator, MouseSelectionStyle, Panel, PanelConstructor, PluginSpec, PluginValue, Rect, Tooltip, TooltipView, ViewPlugin, ViewUpdate, WidgetType, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, hoverTooltip, keymap, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|
|
1903
|
+
export { BidiSpan, BlockInfo, BlockType, Command, DOMEventHandlers, DOMEventMap, Decoration, DecorationSet, Direction, EditorView, EditorViewConfig, GutterMarker, KeyBinding, LayerMarker, MatchDecorator, MouseSelectionStyle, Panel, PanelConstructor, PluginSpec, PluginValue, Rect, RectangleMarker, Tooltip, TooltipView, ViewPlugin, ViewUpdate, WidgetType, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|
package/dist/index.js
CHANGED
|
@@ -5306,14 +5306,13 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5306
5306
|
"&dark .cm-content": { caretColor: "white" },
|
|
5307
5307
|
".cm-line": {
|
|
5308
5308
|
display: "block",
|
|
5309
|
-
padding: "0 2px 0
|
|
5309
|
+
padding: "0 2px 0 6px"
|
|
5310
5310
|
},
|
|
5311
|
-
".cm-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
position: "absolute",
|
|
5311
|
+
".cm-layer": {
|
|
5312
|
+
contain: "size style",
|
|
5313
|
+
"& > *": {
|
|
5314
|
+
position: "absolute"
|
|
5315
|
+
}
|
|
5317
5316
|
},
|
|
5318
5317
|
"&light .cm-selectionBackground": {
|
|
5319
5318
|
background: "#d9d9d9"
|
|
@@ -5328,8 +5327,6 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5328
5327
|
background: "#233"
|
|
5329
5328
|
},
|
|
5330
5329
|
".cm-cursorLayer": {
|
|
5331
|
-
zIndex: 100,
|
|
5332
|
-
contain: "size style",
|
|
5333
5330
|
pointerEvents: "none"
|
|
5334
5331
|
},
|
|
5335
5332
|
"&.cm-focused .cm-cursorLayer": {
|
|
@@ -5341,7 +5338,6 @@ const baseTheme$1 = /*@__PURE__*/buildTheme("." + baseThemeID, {
|
|
|
5341
5338
|
"@keyframes cm-blink": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
|
|
5342
5339
|
"@keyframes cm-blink2": { "0%": {}, "50%": { opacity: 0 }, "100%": {} },
|
|
5343
5340
|
".cm-cursor, .cm-dropCursor": {
|
|
5344
|
-
position: "absolute",
|
|
5345
5341
|
borderLeft: "1.2px solid black",
|
|
5346
5342
|
marginLeft: "-0.6px",
|
|
5347
5343
|
pointerEvents: "none",
|
|
@@ -7287,6 +7283,117 @@ function runHandlers(map, event, view, scope) {
|
|
|
7287
7283
|
return fallthrough;
|
|
7288
7284
|
}
|
|
7289
7285
|
|
|
7286
|
+
/**
|
|
7287
|
+
Implementation of [`LayerMarker`](https://codemirror.net/6/docs/ref/#view.LayerMarker) that creates
|
|
7288
|
+
a rectangle at a given set of coordinates.
|
|
7289
|
+
*/
|
|
7290
|
+
class RectangleMarker {
|
|
7291
|
+
/**
|
|
7292
|
+
Create a marker with the given class and dimensions.
|
|
7293
|
+
*/
|
|
7294
|
+
constructor(className, left, top, width, height) {
|
|
7295
|
+
this.className = className;
|
|
7296
|
+
this.left = left;
|
|
7297
|
+
this.top = top;
|
|
7298
|
+
this.width = width;
|
|
7299
|
+
this.height = height;
|
|
7300
|
+
}
|
|
7301
|
+
draw() {
|
|
7302
|
+
let elt = document.createElement("div");
|
|
7303
|
+
elt.className = this.className;
|
|
7304
|
+
this.adjust(elt);
|
|
7305
|
+
return elt;
|
|
7306
|
+
}
|
|
7307
|
+
update(elt, prev) {
|
|
7308
|
+
if (prev.className != this.className)
|
|
7309
|
+
return false;
|
|
7310
|
+
this.adjust(elt);
|
|
7311
|
+
return true;
|
|
7312
|
+
}
|
|
7313
|
+
adjust(elt) {
|
|
7314
|
+
elt.style.left = this.left + "px";
|
|
7315
|
+
elt.style.top = this.top + "px";
|
|
7316
|
+
if (this.width >= 0)
|
|
7317
|
+
elt.style.width = this.width + "px";
|
|
7318
|
+
elt.style.height = this.height + "px";
|
|
7319
|
+
}
|
|
7320
|
+
eq(p) {
|
|
7321
|
+
return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height &&
|
|
7322
|
+
this.className == p.className;
|
|
7323
|
+
}
|
|
7324
|
+
}
|
|
7325
|
+
function sameMarker(a, b) {
|
|
7326
|
+
return a.constructor == b.constructor && a.eq(b);
|
|
7327
|
+
}
|
|
7328
|
+
class LayerView {
|
|
7329
|
+
constructor(view, layer) {
|
|
7330
|
+
this.view = view;
|
|
7331
|
+
this.layer = layer;
|
|
7332
|
+
this.drawn = [];
|
|
7333
|
+
this.measureReq = { read: this.measure.bind(this), write: this.draw.bind(this) };
|
|
7334
|
+
this.dom = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7335
|
+
this.dom.classList.add("cm-layer");
|
|
7336
|
+
if (layer.above)
|
|
7337
|
+
this.dom.classList.add("cm-layer-above");
|
|
7338
|
+
if (layer.class)
|
|
7339
|
+
this.dom.classList.add(layer.class);
|
|
7340
|
+
this.dom.setAttribute("aria-hidden", "true");
|
|
7341
|
+
this.setOrder(view.state);
|
|
7342
|
+
view.requestMeasure(this.measureReq);
|
|
7343
|
+
if (layer.mount)
|
|
7344
|
+
layer.mount(this.dom, view);
|
|
7345
|
+
}
|
|
7346
|
+
update(update) {
|
|
7347
|
+
if (update.startState.facet(layerOrder) != update.state.facet(layerOrder))
|
|
7348
|
+
this.setOrder(update.state);
|
|
7349
|
+
if (this.layer.update(update, this.dom) || update.geometryChanged)
|
|
7350
|
+
update.view.requestMeasure(this.measureReq);
|
|
7351
|
+
}
|
|
7352
|
+
setOrder(state) {
|
|
7353
|
+
let pos = 0, order = state.facet(layerOrder);
|
|
7354
|
+
while (pos < order.length && order[pos] != this.layer)
|
|
7355
|
+
pos++;
|
|
7356
|
+
this.dom.style.zIndex = String((this.layer.above ? 150 : -1) - pos);
|
|
7357
|
+
}
|
|
7358
|
+
measure() {
|
|
7359
|
+
return this.layer.markers(this.view);
|
|
7360
|
+
}
|
|
7361
|
+
draw(markers) {
|
|
7362
|
+
if (markers.length != this.drawn.length || markers.some((p, i) => !sameMarker(p, this.drawn[i]))) {
|
|
7363
|
+
let old = this.dom.firstChild, oldI = 0;
|
|
7364
|
+
for (let marker of markers) {
|
|
7365
|
+
if (marker.update && old && marker.constructor && this.drawn[oldI].constructor &&
|
|
7366
|
+
marker.update(old, this.drawn[oldI])) {
|
|
7367
|
+
old = old.nextSibling;
|
|
7368
|
+
oldI++;
|
|
7369
|
+
}
|
|
7370
|
+
else {
|
|
7371
|
+
this.dom.insertBefore(marker.draw(), old);
|
|
7372
|
+
}
|
|
7373
|
+
}
|
|
7374
|
+
while (old) {
|
|
7375
|
+
let next = old.nextSibling;
|
|
7376
|
+
old.remove();
|
|
7377
|
+
old = next;
|
|
7378
|
+
}
|
|
7379
|
+
this.drawn = markers;
|
|
7380
|
+
}
|
|
7381
|
+
}
|
|
7382
|
+
destroy() {
|
|
7383
|
+
this.dom.remove();
|
|
7384
|
+
}
|
|
7385
|
+
}
|
|
7386
|
+
const layerOrder = /*@__PURE__*/Facet.define();
|
|
7387
|
+
/**
|
|
7388
|
+
Define a layer.
|
|
7389
|
+
*/
|
|
7390
|
+
function layer(config) {
|
|
7391
|
+
return [
|
|
7392
|
+
ViewPlugin.define(v => new LayerView(v, config)),
|
|
7393
|
+
layerOrder.of(config)
|
|
7394
|
+
];
|
|
7395
|
+
}
|
|
7396
|
+
|
|
7290
7397
|
const CanHidePrimary = !browser.ios; // FIXME test IE
|
|
7291
7398
|
const selectionConfig = /*@__PURE__*/Facet.define({
|
|
7292
7399
|
combine(configs) {
|
|
@@ -7320,102 +7427,55 @@ content).
|
|
|
7320
7427
|
function drawSelection(config = {}) {
|
|
7321
7428
|
return [
|
|
7322
7429
|
selectionConfig.of(config),
|
|
7323
|
-
|
|
7430
|
+
cursorLayer,
|
|
7431
|
+
selectionLayer,
|
|
7324
7432
|
hideNativeSelection,
|
|
7325
7433
|
nativeSelectionHidden.of(true)
|
|
7326
7434
|
];
|
|
7327
7435
|
}
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
this.left = left;
|
|
7331
|
-
this.top = top;
|
|
7332
|
-
this.width = width;
|
|
7333
|
-
this.height = height;
|
|
7334
|
-
this.className = className;
|
|
7335
|
-
}
|
|
7336
|
-
draw() {
|
|
7337
|
-
let elt = document.createElement("div");
|
|
7338
|
-
elt.className = this.className;
|
|
7339
|
-
this.adjust(elt);
|
|
7340
|
-
return elt;
|
|
7341
|
-
}
|
|
7342
|
-
adjust(elt) {
|
|
7343
|
-
elt.style.left = this.left + "px";
|
|
7344
|
-
elt.style.top = this.top + "px";
|
|
7345
|
-
if (this.width >= 0)
|
|
7346
|
-
elt.style.width = this.width + "px";
|
|
7347
|
-
elt.style.height = this.height + "px";
|
|
7348
|
-
}
|
|
7349
|
-
eq(p) {
|
|
7350
|
-
return this.left == p.left && this.top == p.top && this.width == p.width && this.height == p.height &&
|
|
7351
|
-
this.className == p.className;
|
|
7352
|
-
}
|
|
7436
|
+
function configChanged(update) {
|
|
7437
|
+
return update.startState.facet(selectionConfig) != update.startState.facet(selectionConfig);
|
|
7353
7438
|
}
|
|
7354
|
-
const
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
this.cursors = [];
|
|
7359
|
-
this.measureReq = { read: this.readPos.bind(this), write: this.drawSel.bind(this) };
|
|
7360
|
-
this.selectionLayer = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7361
|
-
this.selectionLayer.className = "cm-selectionLayer";
|
|
7362
|
-
this.selectionLayer.setAttribute("aria-hidden", "true");
|
|
7363
|
-
this.cursorLayer = view.scrollDOM.appendChild(document.createElement("div"));
|
|
7364
|
-
this.cursorLayer.className = "cm-cursorLayer";
|
|
7365
|
-
this.cursorLayer.setAttribute("aria-hidden", "true");
|
|
7366
|
-
view.requestMeasure(this.measureReq);
|
|
7367
|
-
this.setBlinkRate();
|
|
7368
|
-
}
|
|
7369
|
-
setBlinkRate() {
|
|
7370
|
-
this.cursorLayer.style.animationDuration = this.view.state.facet(selectionConfig).cursorBlinkRate + "ms";
|
|
7371
|
-
}
|
|
7372
|
-
update(update) {
|
|
7373
|
-
let confChanged = update.startState.facet(selectionConfig) != update.state.facet(selectionConfig);
|
|
7374
|
-
if (confChanged || update.selectionSet || update.geometryChanged || update.viewportChanged)
|
|
7375
|
-
this.view.requestMeasure(this.measureReq);
|
|
7376
|
-
if (update.transactions.some(tr => tr.scrollIntoView))
|
|
7377
|
-
this.cursorLayer.style.animationName = this.cursorLayer.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
|
|
7378
|
-
if (confChanged)
|
|
7379
|
-
this.setBlinkRate();
|
|
7380
|
-
}
|
|
7381
|
-
readPos() {
|
|
7382
|
-
let { state } = this.view, conf = state.facet(selectionConfig);
|
|
7383
|
-
let rangePieces = state.selection.ranges.map(r => r.empty ? [] : measureRange(this.view, r)).reduce((a, b) => a.concat(b));
|
|
7439
|
+
const cursorLayer = /*@__PURE__*/layer({
|
|
7440
|
+
above: true,
|
|
7441
|
+
markers(view) {
|
|
7442
|
+
let { state } = view, conf = state.facet(selectionConfig);
|
|
7384
7443
|
let cursors = [];
|
|
7385
7444
|
for (let r of state.selection.ranges) {
|
|
7386
7445
|
let prim = r == state.selection.main;
|
|
7387
7446
|
if (r.empty ? !prim || CanHidePrimary : conf.drawRangeCursor) {
|
|
7388
|
-
let piece = measureCursor(
|
|
7447
|
+
let piece = measureCursor(view, r, prim);
|
|
7389
7448
|
if (piece)
|
|
7390
7449
|
cursors.push(piece);
|
|
7391
7450
|
}
|
|
7392
7451
|
}
|
|
7393
|
-
return
|
|
7394
|
-
}
|
|
7395
|
-
|
|
7396
|
-
if (
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
}
|
|
7452
|
+
return cursors;
|
|
7453
|
+
},
|
|
7454
|
+
update(update, dom) {
|
|
7455
|
+
if (update.transactions.some(tr => tr.scrollIntoView))
|
|
7456
|
+
dom.style.animationName = dom.style.animationName == "cm-blink" ? "cm-blink2" : "cm-blink";
|
|
7457
|
+
let confChange = configChanged(update);
|
|
7458
|
+
if (confChange)
|
|
7459
|
+
setBlinkRate(update.state, dom);
|
|
7460
|
+
return update.docChanged || update.selectionSet || confChange;
|
|
7461
|
+
},
|
|
7462
|
+
mount(dom, view) {
|
|
7463
|
+
setBlinkRate(view.state, dom);
|
|
7464
|
+
},
|
|
7465
|
+
class: "cm-cursorLayer"
|
|
7466
|
+
});
|
|
7467
|
+
function setBlinkRate(state, dom) {
|
|
7468
|
+
dom.style.animationDuration = state.facet(selectionConfig).cursorBlinkRate + "ms";
|
|
7469
|
+
}
|
|
7470
|
+
const selectionLayer = /*@__PURE__*/layer({
|
|
7471
|
+
above: false,
|
|
7472
|
+
markers(view) {
|
|
7473
|
+
return view.state.selection.ranges.map(r => r.empty ? [] : measureRange(view, r)).reduce((a, b) => a.concat(b));
|
|
7474
|
+
},
|
|
7475
|
+
update(update, dom) {
|
|
7476
|
+
return update.docChanged || update.selectionSet || update.viewportChanged || configChanged(update);
|
|
7477
|
+
},
|
|
7478
|
+
class: "cm-selectionLayer"
|
|
7419
7479
|
});
|
|
7420
7480
|
const themeSpec = {
|
|
7421
7481
|
".cm-line": {
|
|
@@ -7478,7 +7538,7 @@ function measureRange(view, range) {
|
|
|
7478
7538
|
return pieces(top).concat(between).concat(pieces(bottom));
|
|
7479
7539
|
}
|
|
7480
7540
|
function piece(left, top, right, bottom) {
|
|
7481
|
-
return new
|
|
7541
|
+
return new RectangleMarker("cm-selectionBackground", left - base.left, top - base.top - 0.01 /* C.Epsilon */, right - left, bottom - top + 0.01 /* C.Epsilon */);
|
|
7482
7542
|
}
|
|
7483
7543
|
function pieces({ top, bottom, horizontal }) {
|
|
7484
7544
|
let pieces = [];
|
|
@@ -7535,7 +7595,7 @@ function measureCursor(view, cursor, primary) {
|
|
|
7535
7595
|
if (!pos)
|
|
7536
7596
|
return null;
|
|
7537
7597
|
let base = getBase(view);
|
|
7538
|
-
return new
|
|
7598
|
+
return new RectangleMarker(primary ? "cm-cursor cm-cursor-primary" : "cm-cursor cm-cursor-secondary", pos.left - base.left, pos.top - base.top, -1, pos.bottom - pos.top);
|
|
7539
7599
|
}
|
|
7540
7600
|
|
|
7541
7601
|
const setDropCursorPos = /*@__PURE__*/StateEffect.define({
|
|
@@ -8329,6 +8389,17 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8329
8389
|
: pos.bottom + (size.bottom - size.top) + offset.y > space.bottom) &&
|
|
8330
8390
|
above == (space.bottom - pos.bottom > pos.top - space.top))
|
|
8331
8391
|
above = !above;
|
|
8392
|
+
let spaceVert = (above ? pos.top - space.top : space.bottom - pos.bottom) - arrowHeight;
|
|
8393
|
+
if (spaceVert < height && tView.resize !== false) {
|
|
8394
|
+
if (spaceVert < this.view.defaultLineHeight) {
|
|
8395
|
+
dom.style.top = Outside;
|
|
8396
|
+
continue;
|
|
8397
|
+
}
|
|
8398
|
+
dom.style.height = (height = spaceVert) + "px";
|
|
8399
|
+
}
|
|
8400
|
+
else if (dom.style.height) {
|
|
8401
|
+
dom.style.height = "";
|
|
8402
|
+
}
|
|
8332
8403
|
let top = above ? pos.top - height - arrowHeight - offset.y : pos.bottom + arrowHeight + offset.y;
|
|
8333
8404
|
let right = left + width;
|
|
8334
8405
|
if (tView.overlap !== true)
|
|
@@ -8372,7 +8443,8 @@ const tooltipPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
8372
8443
|
});
|
|
8373
8444
|
const baseTheme = /*@__PURE__*/EditorView.baseTheme({
|
|
8374
8445
|
".cm-tooltip": {
|
|
8375
|
-
zIndex: 100
|
|
8446
|
+
zIndex: 100,
|
|
8447
|
+
boxSizing: "border-box"
|
|
8376
8448
|
},
|
|
8377
8449
|
"&light .cm-tooltip": {
|
|
8378
8450
|
border: "1px solid #bbb",
|
|
@@ -9296,4 +9368,4 @@ function highlightActiveLineGutter() {
|
|
|
9296
9368
|
*/
|
|
9297
9369
|
const __test = { HeightMap, HeightOracle, MeasuredHeights, QueryType, ChangedRange, computeOrder, moveVisually };
|
|
9298
9370
|
|
|
9299
|
-
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, ViewPlugin, ViewUpdate, WidgetType, __test, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, hoverTooltip, keymap, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|
|
9371
|
+
export { BidiSpan, BlockInfo, BlockType, Decoration, Direction, EditorView, GutterMarker, MatchDecorator, RectangleMarker, ViewPlugin, ViewUpdate, WidgetType, __test, closeHoverTooltips, crosshairCursor, drawSelection, dropCursor, getPanel, getTooltip, gutter, gutterLineClass, gutters, hasHoverTooltips, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, hoverTooltip, keymap, layer, lineNumberMarkers, lineNumbers, logException, panels, placeholder, rectangularSelection, repositionTooltips, runScopeHandlers, scrollPastEnd, showPanel, showTooltip, tooltips };
|