@codemirror/view 0.19.47 → 0.19.48
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 +12 -0
- package/dist/index.cjs +37 -33
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -33
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## 0.19.48 (2022-03-30)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where DOM syncing could crash when a DOM node was moved from a parent to a child node (via widgets reusing existing nodes).
|
|
6
|
+
|
|
7
|
+
To avoid interfering with things like a vim mode too much, the editor will now only activate the tab-to-move-focus escape hatch after an escape press that wasn't handled by an event handler.
|
|
8
|
+
|
|
9
|
+
Make sure the view measures itself before the page is printed.
|
|
10
|
+
|
|
11
|
+
Tweak types of view plugin defining functions to avoid TypeScript errors when the plugin value doesn't have any of the interface's properties.
|
|
12
|
+
|
|
1
13
|
## 0.19.47 (2022-03-08)
|
|
2
14
|
|
|
3
15
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -318,32 +318,34 @@ class ContentView {
|
|
|
318
318
|
sync(track) {
|
|
319
319
|
if (this.dirty & 2 /* Node */) {
|
|
320
320
|
let parent = this.dom;
|
|
321
|
-
let
|
|
321
|
+
let prev = null, next;
|
|
322
322
|
for (let child of this.children) {
|
|
323
323
|
if (child.dirty) {
|
|
324
|
-
if (!child.dom &&
|
|
325
|
-
let contentView = ContentView.get(
|
|
324
|
+
if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) {
|
|
325
|
+
let contentView = ContentView.get(next);
|
|
326
326
|
if (!contentView || !contentView.parent && contentView.constructor == child.constructor)
|
|
327
|
-
child.reuseDOM(
|
|
327
|
+
child.reuseDOM(next);
|
|
328
328
|
}
|
|
329
329
|
child.sync(track);
|
|
330
330
|
child.dirty = 0 /* Not */;
|
|
331
331
|
}
|
|
332
|
-
|
|
332
|
+
next = prev ? prev.nextSibling : parent.firstChild;
|
|
333
|
+
if (track && !track.written && track.node == parent && next != child.dom)
|
|
333
334
|
track.written = true;
|
|
334
335
|
if (child.dom.parentNode == parent) {
|
|
335
|
-
while (
|
|
336
|
-
|
|
337
|
-
pos = child.dom.nextSibling;
|
|
336
|
+
while (next && next != child.dom)
|
|
337
|
+
next = rm(next);
|
|
338
338
|
}
|
|
339
339
|
else {
|
|
340
|
-
parent.insertBefore(child.dom,
|
|
340
|
+
parent.insertBefore(child.dom, next);
|
|
341
341
|
}
|
|
342
|
+
prev = child.dom;
|
|
342
343
|
}
|
|
343
|
-
|
|
344
|
+
next = prev ? prev.nextSibling : parent.firstChild;
|
|
345
|
+
if (next && track && track.node == parent)
|
|
344
346
|
track.written = true;
|
|
345
|
-
while (
|
|
346
|
-
|
|
347
|
+
while (next)
|
|
348
|
+
next = rm(next);
|
|
347
349
|
}
|
|
348
350
|
else if (this.dirty & 1 /* Child */) {
|
|
349
351
|
for (let child of this.children)
|
|
@@ -3373,10 +3375,10 @@ class InputState {
|
|
|
3373
3375
|
for (let type in handlers) {
|
|
3374
3376
|
let handler = handlers[type];
|
|
3375
3377
|
view.contentDOM.addEventListener(type, (event) => {
|
|
3376
|
-
if (type == "keydown" && this.keydown(view, event))
|
|
3377
|
-
return;
|
|
3378
3378
|
if (!eventBelongsToEditor(view, event) || this.ignoreDuringComposition(event))
|
|
3379
3379
|
return;
|
|
3380
|
+
if (type == "keydown" && this.keydown(view, event))
|
|
3381
|
+
return;
|
|
3380
3382
|
if (this.mustFlushObserver(event))
|
|
3381
3383
|
view.observer.forceFlush();
|
|
3382
3384
|
if (this.runCustomHandlers(type, view, event))
|
|
@@ -3444,7 +3446,7 @@ class InputState {
|
|
|
3444
3446
|
// Must always run, even if a custom handler handled the event
|
|
3445
3447
|
this.lastKeyCode = event.keyCode;
|
|
3446
3448
|
this.lastKeyTime = Date.now();
|
|
3447
|
-
if (
|
|
3449
|
+
if (event.keyCode == 9 && Date.now() < this.lastEscPress + 2000)
|
|
3448
3450
|
return true;
|
|
3449
3451
|
// Chrome for Android usually doesn't fire proper key events, but
|
|
3450
3452
|
// occasionally does, usually surrounded by a bunch of complicated
|
|
@@ -3494,14 +3496,6 @@ class InputState {
|
|
|
3494
3496
|
}
|
|
3495
3497
|
return false;
|
|
3496
3498
|
}
|
|
3497
|
-
screenKeyEvent(view, event) {
|
|
3498
|
-
let protectedTab = event.keyCode == 9 && Date.now() < this.lastEscPress + 2000;
|
|
3499
|
-
if (event.keyCode == 27)
|
|
3500
|
-
this.lastEscPress = Date.now();
|
|
3501
|
-
else if (modifierCodes.indexOf(event.keyCode) < 0)
|
|
3502
|
-
this.lastEscPress = 0;
|
|
3503
|
-
return protectedTab;
|
|
3504
|
-
}
|
|
3505
3499
|
mustFlushObserver(event) {
|
|
3506
3500
|
return (event.type == "keydown" && event.keyCode != 229) ||
|
|
3507
3501
|
event.type == "compositionend" && !browser.ios;
|
|
@@ -3675,6 +3669,10 @@ function doPaste(view, input) {
|
|
|
3675
3669
|
}
|
|
3676
3670
|
handlers.keydown = (view, event) => {
|
|
3677
3671
|
view.inputState.setSelectionOrigin("select");
|
|
3672
|
+
if (event.keyCode == 27)
|
|
3673
|
+
view.inputState.lastEscPress = Date.now();
|
|
3674
|
+
else if (modifierCodes.indexOf(event.keyCode) < 0)
|
|
3675
|
+
view.inputState.lastEscPress = 0;
|
|
3678
3676
|
};
|
|
3679
3677
|
let lastTouch = 0;
|
|
3680
3678
|
handlers.touchstart = (view, e) => {
|
|
@@ -3932,14 +3930,6 @@ handlers.focus = handlers.blur = view => {
|
|
|
3932
3930
|
view.update([]);
|
|
3933
3931
|
}, 10);
|
|
3934
3932
|
};
|
|
3935
|
-
handlers.beforeprint = view => {
|
|
3936
|
-
view.viewState.printing = true;
|
|
3937
|
-
view.requestMeasure();
|
|
3938
|
-
setTimeout(() => {
|
|
3939
|
-
view.viewState.printing = false;
|
|
3940
|
-
view.requestMeasure();
|
|
3941
|
-
}, 2000);
|
|
3942
|
-
};
|
|
3943
3933
|
function forceClearComposition(view, rapid) {
|
|
3944
3934
|
if (view.docView.compositionDeco.size) {
|
|
3945
3935
|
view.inputState.rapidCompositionStart = rapid;
|
|
@@ -4695,6 +4685,11 @@ function visiblePixelRange(dom, paddingTop) {
|
|
|
4695
4685
|
return { left: left - rect.left, right: Math.max(left, right) - rect.left,
|
|
4696
4686
|
top: top - (rect.top + paddingTop), bottom: Math.max(top, bottom) - (rect.top + paddingTop) };
|
|
4697
4687
|
}
|
|
4688
|
+
function fullPixelRange(dom, paddingTop) {
|
|
4689
|
+
let rect = dom.getBoundingClientRect();
|
|
4690
|
+
return { left: 0, right: rect.right - rect.left,
|
|
4691
|
+
top: paddingTop, bottom: rect.bottom - (rect.top + paddingTop) };
|
|
4692
|
+
}
|
|
4698
4693
|
// Line gaps are placeholder widgets used to hide pieces of overlong
|
|
4699
4694
|
// lines within the viewport, as a kludge to keep the editor
|
|
4700
4695
|
// responsive when a ridiculously long line is loaded into it.
|
|
@@ -4851,8 +4846,7 @@ class ViewState {
|
|
|
4851
4846
|
}
|
|
4852
4847
|
}
|
|
4853
4848
|
// Pixel viewport
|
|
4854
|
-
let pixelViewport = this.printing ?
|
|
4855
|
-
: visiblePixelRange(dom, this.paddingTop);
|
|
4849
|
+
let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
|
|
4856
4850
|
let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
|
|
4857
4851
|
this.pixelViewport = pixelViewport;
|
|
4858
4852
|
let inView = this.pixelViewport.bottom > this.pixelViewport.top && this.pixelViewport.right > this.pixelViewport.left;
|
|
@@ -5429,6 +5423,7 @@ class DOMObserver {
|
|
|
5429
5423
|
});
|
|
5430
5424
|
this.resize.observe(view.scrollDOM);
|
|
5431
5425
|
}
|
|
5426
|
+
window.addEventListener("beforeprint", this.onPrint = this.onPrint.bind(this));
|
|
5432
5427
|
this.start();
|
|
5433
5428
|
window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
|
|
5434
5429
|
if (typeof IntersectionObserver == "function") {
|
|
@@ -5463,6 +5458,14 @@ class DOMObserver {
|
|
|
5463
5458
|
this.view.requestMeasure();
|
|
5464
5459
|
}, 50);
|
|
5465
5460
|
}
|
|
5461
|
+
onPrint() {
|
|
5462
|
+
this.view.viewState.printing = true;
|
|
5463
|
+
this.view.measure();
|
|
5464
|
+
setTimeout(() => {
|
|
5465
|
+
this.view.viewState.printing = false;
|
|
5466
|
+
this.view.requestMeasure();
|
|
5467
|
+
}, 500);
|
|
5468
|
+
}
|
|
5466
5469
|
updateGaps(gaps) {
|
|
5467
5470
|
if (this.gapIntersection && (gaps.length != this.gaps.length || this.gaps.some((g, i) => g != gaps[i]))) {
|
|
5468
5471
|
this.gapIntersection.disconnect();
|
|
@@ -5680,6 +5683,7 @@ class DOMObserver {
|
|
|
5680
5683
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5681
5684
|
window.removeEventListener("scroll", this.onScroll);
|
|
5682
5685
|
window.removeEventListener("resize", this.onResize);
|
|
5686
|
+
window.removeEventListener("beforeprint", this.onPrint);
|
|
5683
5687
|
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5684
5688
|
clearTimeout(this.parentCheck);
|
|
5685
5689
|
clearTimeout(this.resizeTimeout);
|
package/dist/index.d.ts
CHANGED
|
@@ -413,12 +413,12 @@ declare class ViewPlugin<V extends PluginValue> {
|
|
|
413
413
|
Define a plugin from a constructor function that creates the
|
|
414
414
|
plugin's value, given an editor view.
|
|
415
415
|
*/
|
|
416
|
-
static define<V extends PluginValue>(create: (view: EditorView) => V, spec?: PluginSpec<V>): ViewPlugin<V>;
|
|
416
|
+
static define<V extends PluginValue & object>(create: (view: EditorView) => V, spec?: PluginSpec<V>): ViewPlugin<V>;
|
|
417
417
|
/**
|
|
418
418
|
Create a plugin for a class whose constructor takes a single
|
|
419
419
|
editor view as argument.
|
|
420
420
|
*/
|
|
421
|
-
static fromClass<V extends PluginValue>(cls: {
|
|
421
|
+
static fromClass<V extends PluginValue & object>(cls: {
|
|
422
422
|
new (view: EditorView): V;
|
|
423
423
|
}, spec?: PluginSpec<V>): ViewPlugin<V>;
|
|
424
424
|
}
|
package/dist/index.js
CHANGED
|
@@ -315,32 +315,34 @@ class ContentView {
|
|
|
315
315
|
sync(track) {
|
|
316
316
|
if (this.dirty & 2 /* Node */) {
|
|
317
317
|
let parent = this.dom;
|
|
318
|
-
let
|
|
318
|
+
let prev = null, next;
|
|
319
319
|
for (let child of this.children) {
|
|
320
320
|
if (child.dirty) {
|
|
321
|
-
if (!child.dom &&
|
|
322
|
-
let contentView = ContentView.get(
|
|
321
|
+
if (!child.dom && (next = prev ? prev.nextSibling : parent.firstChild)) {
|
|
322
|
+
let contentView = ContentView.get(next);
|
|
323
323
|
if (!contentView || !contentView.parent && contentView.constructor == child.constructor)
|
|
324
|
-
child.reuseDOM(
|
|
324
|
+
child.reuseDOM(next);
|
|
325
325
|
}
|
|
326
326
|
child.sync(track);
|
|
327
327
|
child.dirty = 0 /* Not */;
|
|
328
328
|
}
|
|
329
|
-
|
|
329
|
+
next = prev ? prev.nextSibling : parent.firstChild;
|
|
330
|
+
if (track && !track.written && track.node == parent && next != child.dom)
|
|
330
331
|
track.written = true;
|
|
331
332
|
if (child.dom.parentNode == parent) {
|
|
332
|
-
while (
|
|
333
|
-
|
|
334
|
-
pos = child.dom.nextSibling;
|
|
333
|
+
while (next && next != child.dom)
|
|
334
|
+
next = rm(next);
|
|
335
335
|
}
|
|
336
336
|
else {
|
|
337
|
-
parent.insertBefore(child.dom,
|
|
337
|
+
parent.insertBefore(child.dom, next);
|
|
338
338
|
}
|
|
339
|
+
prev = child.dom;
|
|
339
340
|
}
|
|
340
|
-
|
|
341
|
+
next = prev ? prev.nextSibling : parent.firstChild;
|
|
342
|
+
if (next && track && track.node == parent)
|
|
341
343
|
track.written = true;
|
|
342
|
-
while (
|
|
343
|
-
|
|
344
|
+
while (next)
|
|
345
|
+
next = rm(next);
|
|
344
346
|
}
|
|
345
347
|
else if (this.dirty & 1 /* Child */) {
|
|
346
348
|
for (let child of this.children)
|
|
@@ -3368,10 +3370,10 @@ class InputState {
|
|
|
3368
3370
|
for (let type in handlers) {
|
|
3369
3371
|
let handler = handlers[type];
|
|
3370
3372
|
view.contentDOM.addEventListener(type, (event) => {
|
|
3371
|
-
if (type == "keydown" && this.keydown(view, event))
|
|
3372
|
-
return;
|
|
3373
3373
|
if (!eventBelongsToEditor(view, event) || this.ignoreDuringComposition(event))
|
|
3374
3374
|
return;
|
|
3375
|
+
if (type == "keydown" && this.keydown(view, event))
|
|
3376
|
+
return;
|
|
3375
3377
|
if (this.mustFlushObserver(event))
|
|
3376
3378
|
view.observer.forceFlush();
|
|
3377
3379
|
if (this.runCustomHandlers(type, view, event))
|
|
@@ -3439,7 +3441,7 @@ class InputState {
|
|
|
3439
3441
|
// Must always run, even if a custom handler handled the event
|
|
3440
3442
|
this.lastKeyCode = event.keyCode;
|
|
3441
3443
|
this.lastKeyTime = Date.now();
|
|
3442
|
-
if (
|
|
3444
|
+
if (event.keyCode == 9 && Date.now() < this.lastEscPress + 2000)
|
|
3443
3445
|
return true;
|
|
3444
3446
|
// Chrome for Android usually doesn't fire proper key events, but
|
|
3445
3447
|
// occasionally does, usually surrounded by a bunch of complicated
|
|
@@ -3489,14 +3491,6 @@ class InputState {
|
|
|
3489
3491
|
}
|
|
3490
3492
|
return false;
|
|
3491
3493
|
}
|
|
3492
|
-
screenKeyEvent(view, event) {
|
|
3493
|
-
let protectedTab = event.keyCode == 9 && Date.now() < this.lastEscPress + 2000;
|
|
3494
|
-
if (event.keyCode == 27)
|
|
3495
|
-
this.lastEscPress = Date.now();
|
|
3496
|
-
else if (modifierCodes.indexOf(event.keyCode) < 0)
|
|
3497
|
-
this.lastEscPress = 0;
|
|
3498
|
-
return protectedTab;
|
|
3499
|
-
}
|
|
3500
3494
|
mustFlushObserver(event) {
|
|
3501
3495
|
return (event.type == "keydown" && event.keyCode != 229) ||
|
|
3502
3496
|
event.type == "compositionend" && !browser.ios;
|
|
@@ -3670,6 +3664,10 @@ function doPaste(view, input) {
|
|
|
3670
3664
|
}
|
|
3671
3665
|
handlers.keydown = (view, event) => {
|
|
3672
3666
|
view.inputState.setSelectionOrigin("select");
|
|
3667
|
+
if (event.keyCode == 27)
|
|
3668
|
+
view.inputState.lastEscPress = Date.now();
|
|
3669
|
+
else if (modifierCodes.indexOf(event.keyCode) < 0)
|
|
3670
|
+
view.inputState.lastEscPress = 0;
|
|
3673
3671
|
};
|
|
3674
3672
|
let lastTouch = 0;
|
|
3675
3673
|
handlers.touchstart = (view, e) => {
|
|
@@ -3927,14 +3925,6 @@ handlers.focus = handlers.blur = view => {
|
|
|
3927
3925
|
view.update([]);
|
|
3928
3926
|
}, 10);
|
|
3929
3927
|
};
|
|
3930
|
-
handlers.beforeprint = view => {
|
|
3931
|
-
view.viewState.printing = true;
|
|
3932
|
-
view.requestMeasure();
|
|
3933
|
-
setTimeout(() => {
|
|
3934
|
-
view.viewState.printing = false;
|
|
3935
|
-
view.requestMeasure();
|
|
3936
|
-
}, 2000);
|
|
3937
|
-
};
|
|
3938
3928
|
function forceClearComposition(view, rapid) {
|
|
3939
3929
|
if (view.docView.compositionDeco.size) {
|
|
3940
3930
|
view.inputState.rapidCompositionStart = rapid;
|
|
@@ -4689,6 +4679,11 @@ function visiblePixelRange(dom, paddingTop) {
|
|
|
4689
4679
|
return { left: left - rect.left, right: Math.max(left, right) - rect.left,
|
|
4690
4680
|
top: top - (rect.top + paddingTop), bottom: Math.max(top, bottom) - (rect.top + paddingTop) };
|
|
4691
4681
|
}
|
|
4682
|
+
function fullPixelRange(dom, paddingTop) {
|
|
4683
|
+
let rect = dom.getBoundingClientRect();
|
|
4684
|
+
return { left: 0, right: rect.right - rect.left,
|
|
4685
|
+
top: paddingTop, bottom: rect.bottom - (rect.top + paddingTop) };
|
|
4686
|
+
}
|
|
4692
4687
|
// Line gaps are placeholder widgets used to hide pieces of overlong
|
|
4693
4688
|
// lines within the viewport, as a kludge to keep the editor
|
|
4694
4689
|
// responsive when a ridiculously long line is loaded into it.
|
|
@@ -4845,8 +4840,7 @@ class ViewState {
|
|
|
4845
4840
|
}
|
|
4846
4841
|
}
|
|
4847
4842
|
// Pixel viewport
|
|
4848
|
-
let pixelViewport = this.printing ?
|
|
4849
|
-
: visiblePixelRange(dom, this.paddingTop);
|
|
4843
|
+
let pixelViewport = (this.printing ? fullPixelRange : visiblePixelRange)(dom, this.paddingTop);
|
|
4850
4844
|
let dTop = pixelViewport.top - this.pixelViewport.top, dBottom = pixelViewport.bottom - this.pixelViewport.bottom;
|
|
4851
4845
|
this.pixelViewport = pixelViewport;
|
|
4852
4846
|
let inView = this.pixelViewport.bottom > this.pixelViewport.top && this.pixelViewport.right > this.pixelViewport.left;
|
|
@@ -5423,6 +5417,7 @@ class DOMObserver {
|
|
|
5423
5417
|
});
|
|
5424
5418
|
this.resize.observe(view.scrollDOM);
|
|
5425
5419
|
}
|
|
5420
|
+
window.addEventListener("beforeprint", this.onPrint = this.onPrint.bind(this));
|
|
5426
5421
|
this.start();
|
|
5427
5422
|
window.addEventListener("scroll", this.onScroll = this.onScroll.bind(this));
|
|
5428
5423
|
if (typeof IntersectionObserver == "function") {
|
|
@@ -5457,6 +5452,14 @@ class DOMObserver {
|
|
|
5457
5452
|
this.view.requestMeasure();
|
|
5458
5453
|
}, 50);
|
|
5459
5454
|
}
|
|
5455
|
+
onPrint() {
|
|
5456
|
+
this.view.viewState.printing = true;
|
|
5457
|
+
this.view.measure();
|
|
5458
|
+
setTimeout(() => {
|
|
5459
|
+
this.view.viewState.printing = false;
|
|
5460
|
+
this.view.requestMeasure();
|
|
5461
|
+
}, 500);
|
|
5462
|
+
}
|
|
5460
5463
|
updateGaps(gaps) {
|
|
5461
5464
|
if (this.gapIntersection && (gaps.length != this.gaps.length || this.gaps.some((g, i) => g != gaps[i]))) {
|
|
5462
5465
|
this.gapIntersection.disconnect();
|
|
@@ -5674,6 +5677,7 @@ class DOMObserver {
|
|
|
5674
5677
|
dom.removeEventListener("scroll", this.onScroll);
|
|
5675
5678
|
window.removeEventListener("scroll", this.onScroll);
|
|
5676
5679
|
window.removeEventListener("resize", this.onResize);
|
|
5680
|
+
window.removeEventListener("beforeprint", this.onPrint);
|
|
5677
5681
|
this.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange);
|
|
5678
5682
|
clearTimeout(this.parentCheck);
|
|
5679
5683
|
clearTimeout(this.resizeTimeout);
|