prosemirror-view 1.38.0 → 1.38.1
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 +10 -0
- package/dist/index.cjs +9 -3
- package/dist/index.d.cts +1 -100
- package/dist/index.d.ts +1 -100
- package/dist/index.js +8 -3
- package/package.json +1 -1
- package/src/domcoords.ts +5 -3
- package/src/domobserver.ts +1 -0
- package/src/viewdesc.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 1.38.1 (2025-03-04)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a regression in 1.38.0 that breaks scrolling back to the selection after Chrome tries to reset it on focus.
|
|
6
|
+
|
|
7
|
+
Remove some internally used types from the public type declaration files. Include file extension in web test local imports
|
|
8
|
+
|
|
9
|
+
Fix an issue where scrolling the cursor into view could inappropriately scroll parent nodes of absolutely positioned elements.
|
|
10
|
+
|
|
1
11
|
## 1.38.0 (2025-02-12)
|
|
2
12
|
|
|
3
13
|
### New features
|
package/dist/index.cjs
CHANGED
|
@@ -200,9 +200,12 @@ function scrollRectIntoView(view, rect, startDOM) {
|
|
|
200
200
|
var scrollThreshold = view.someProp("scrollThreshold") || 0,
|
|
201
201
|
scrollMargin = view.someProp("scrollMargin") || 5;
|
|
202
202
|
var doc = view.dom.ownerDocument;
|
|
203
|
-
for (var parent = startDOM || view.dom;;
|
|
203
|
+
for (var parent = startDOM || view.dom;;) {
|
|
204
204
|
if (!parent) break;
|
|
205
|
-
if (parent.nodeType != 1)
|
|
205
|
+
if (parent.nodeType != 1) {
|
|
206
|
+
parent = parentNode(parent);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
206
209
|
var elt = parent;
|
|
207
210
|
var atTop = elt == doc.body;
|
|
208
211
|
var bounding = atTop ? windowRect(doc) : clientRect(elt);
|
|
@@ -228,7 +231,9 @@ function scrollRectIntoView(view, rect, startDOM) {
|
|
|
228
231
|
};
|
|
229
232
|
}
|
|
230
233
|
}
|
|
231
|
-
|
|
234
|
+
var pos = atTop ? "fixed" : getComputedStyle(parent).position;
|
|
235
|
+
if (/^(fixed|sticky)$/.test(pos)) break;
|
|
236
|
+
parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
|
|
232
237
|
}
|
|
233
238
|
}
|
|
234
239
|
function storeScrollPos(view) {
|
|
@@ -4369,6 +4374,7 @@ var DOMObserver = function () {
|
|
|
4369
4374
|
view.input.lastFocus = 0;
|
|
4370
4375
|
selectionToDOM(view);
|
|
4371
4376
|
this.currentSelection.set(sel);
|
|
4377
|
+
view.scrollToSelection();
|
|
4372
4378
|
} else if (from > -1 || newSel) {
|
|
4373
4379
|
if (from > -1) {
|
|
4374
4380
|
view.docView.markDirty(from, to);
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EditorState, Transaction, Selection, Plugin } from 'prosemirror-state';
|
|
2
|
-
import { Mark, Node,
|
|
2
|
+
import { Mark, Node, Slice, ResolvedPos, DOMParser, DOMSerializer } from 'prosemirror-model';
|
|
3
3
|
import { Mapping } from 'prosemirror-transform';
|
|
4
4
|
|
|
5
5
|
type DOMNode = InstanceType<typeof window.Node>;
|
|
@@ -234,7 +234,6 @@ declare class DecorationGroup implements DecorationSource {
|
|
|
234
234
|
|
|
235
235
|
declare global {
|
|
236
236
|
interface Node {
|
|
237
|
-
pmViewDesc?: ViewDesc;
|
|
238
237
|
}
|
|
239
238
|
}
|
|
240
239
|
/**
|
|
@@ -361,104 +360,6 @@ interface MarkView {
|
|
|
361
360
|
*/
|
|
362
361
|
destroy?: () => void;
|
|
363
362
|
}
|
|
364
|
-
declare class ViewDesc {
|
|
365
|
-
parent: ViewDesc | undefined;
|
|
366
|
-
children: ViewDesc[];
|
|
367
|
-
dom: DOMNode;
|
|
368
|
-
contentDOM: HTMLElement | null;
|
|
369
|
-
dirty: number;
|
|
370
|
-
node: Node | null;
|
|
371
|
-
constructor(parent: ViewDesc | undefined, children: ViewDesc[], dom: DOMNode, contentDOM: HTMLElement | null);
|
|
372
|
-
matchesWidget(widget: Decoration): boolean;
|
|
373
|
-
matchesMark(mark: Mark): boolean;
|
|
374
|
-
matchesNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource): boolean;
|
|
375
|
-
matchesHack(nodeName: string): boolean;
|
|
376
|
-
parseRule(): Omit<TagParseRule, "tag"> | null;
|
|
377
|
-
stopEvent(event: Event): boolean;
|
|
378
|
-
get size(): number;
|
|
379
|
-
get border(): number;
|
|
380
|
-
destroy(): void;
|
|
381
|
-
posBeforeChild(child: ViewDesc): number;
|
|
382
|
-
get posBefore(): number;
|
|
383
|
-
get posAtStart(): number;
|
|
384
|
-
get posAfter(): number;
|
|
385
|
-
get posAtEnd(): number;
|
|
386
|
-
localPosFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
387
|
-
nearestDesc(dom: DOMNode): ViewDesc | undefined;
|
|
388
|
-
nearestDesc(dom: DOMNode, onlyNodes: true): NodeViewDesc | undefined;
|
|
389
|
-
getDesc(dom: DOMNode): ViewDesc | undefined;
|
|
390
|
-
posFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
391
|
-
descAt(pos: number): ViewDesc | undefined;
|
|
392
|
-
domFromPos(pos: number, side: number): {
|
|
393
|
-
node: DOMNode;
|
|
394
|
-
offset: number;
|
|
395
|
-
atom?: number;
|
|
396
|
-
};
|
|
397
|
-
parseRange(from: number, to: number, base?: number): {
|
|
398
|
-
node: DOMNode;
|
|
399
|
-
from: number;
|
|
400
|
-
to: number;
|
|
401
|
-
fromOffset: number;
|
|
402
|
-
toOffset: number;
|
|
403
|
-
};
|
|
404
|
-
emptyChildAt(side: number): boolean;
|
|
405
|
-
domAfterPos(pos: number): DOMNode;
|
|
406
|
-
setSelection(anchor: number, head: number, view: EditorView, force?: boolean): void;
|
|
407
|
-
ignoreMutation(mutation: ViewMutationRecord): boolean;
|
|
408
|
-
get contentLost(): boolean | null;
|
|
409
|
-
markDirty(from: number, to: number): void;
|
|
410
|
-
markParentsDirty(): void;
|
|
411
|
-
get domAtom(): boolean;
|
|
412
|
-
get ignoreForCoords(): boolean;
|
|
413
|
-
isText(text: string): boolean;
|
|
414
|
-
}
|
|
415
|
-
declare class NodeViewDesc extends ViewDesc {
|
|
416
|
-
node: Node;
|
|
417
|
-
outerDeco: readonly Decoration[];
|
|
418
|
-
innerDeco: DecorationSource;
|
|
419
|
-
readonly nodeDOM: DOMNode;
|
|
420
|
-
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, contentDOM: HTMLElement | null, nodeDOM: DOMNode, view: EditorView, pos: number);
|
|
421
|
-
static create(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView, pos: number): NodeViewDesc | TextViewDesc;
|
|
422
|
-
parseRule(): Omit<TagParseRule, "tag"> | null;
|
|
423
|
-
matchesNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource): boolean;
|
|
424
|
-
get size(): number;
|
|
425
|
-
get border(): 0 | 1;
|
|
426
|
-
updateChildren(view: EditorView, pos: number): void;
|
|
427
|
-
localCompositionInfo(view: EditorView, pos: number): {
|
|
428
|
-
node: Text;
|
|
429
|
-
pos: number;
|
|
430
|
-
text: string;
|
|
431
|
-
} | null;
|
|
432
|
-
protectLocalComposition(view: EditorView, { node, pos, text }: {
|
|
433
|
-
node: Text;
|
|
434
|
-
pos: number;
|
|
435
|
-
text: string;
|
|
436
|
-
}): void;
|
|
437
|
-
update(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): boolean;
|
|
438
|
-
updateInner(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): void;
|
|
439
|
-
updateOuterDeco(outerDeco: readonly Decoration[]): void;
|
|
440
|
-
selectNode(): void;
|
|
441
|
-
deselectNode(): void;
|
|
442
|
-
get domAtom(): boolean;
|
|
443
|
-
}
|
|
444
|
-
declare class TextViewDesc extends NodeViewDesc {
|
|
445
|
-
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, nodeDOM: DOMNode, view: EditorView);
|
|
446
|
-
parseRule(): {
|
|
447
|
-
skip: any;
|
|
448
|
-
};
|
|
449
|
-
update(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): boolean;
|
|
450
|
-
inParent(): boolean;
|
|
451
|
-
domFromPos(pos: number): {
|
|
452
|
-
node: globalThis.Node;
|
|
453
|
-
offset: number;
|
|
454
|
-
};
|
|
455
|
-
localPosFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
456
|
-
ignoreMutation(mutation: ViewMutationRecord): boolean;
|
|
457
|
-
slice(from: number, to: number, view: EditorView): TextViewDesc;
|
|
458
|
-
markDirty(from: number, to: number): void;
|
|
459
|
-
get domAtom(): boolean;
|
|
460
|
-
isText(text: string): boolean;
|
|
461
|
-
}
|
|
462
363
|
|
|
463
364
|
/**
|
|
464
365
|
An editor view manages the DOM structure that represents an
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EditorState, Transaction, Selection, Plugin } from 'prosemirror-state';
|
|
2
|
-
import { Mark, Node,
|
|
2
|
+
import { Mark, Node, Slice, ResolvedPos, DOMParser, DOMSerializer } from 'prosemirror-model';
|
|
3
3
|
import { Mapping } from 'prosemirror-transform';
|
|
4
4
|
|
|
5
5
|
type DOMNode = InstanceType<typeof window.Node>;
|
|
@@ -234,7 +234,6 @@ declare class DecorationGroup implements DecorationSource {
|
|
|
234
234
|
|
|
235
235
|
declare global {
|
|
236
236
|
interface Node {
|
|
237
|
-
pmViewDesc?: ViewDesc;
|
|
238
237
|
}
|
|
239
238
|
}
|
|
240
239
|
/**
|
|
@@ -361,104 +360,6 @@ interface MarkView {
|
|
|
361
360
|
*/
|
|
362
361
|
destroy?: () => void;
|
|
363
362
|
}
|
|
364
|
-
declare class ViewDesc {
|
|
365
|
-
parent: ViewDesc | undefined;
|
|
366
|
-
children: ViewDesc[];
|
|
367
|
-
dom: DOMNode;
|
|
368
|
-
contentDOM: HTMLElement | null;
|
|
369
|
-
dirty: number;
|
|
370
|
-
node: Node | null;
|
|
371
|
-
constructor(parent: ViewDesc | undefined, children: ViewDesc[], dom: DOMNode, contentDOM: HTMLElement | null);
|
|
372
|
-
matchesWidget(widget: Decoration): boolean;
|
|
373
|
-
matchesMark(mark: Mark): boolean;
|
|
374
|
-
matchesNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource): boolean;
|
|
375
|
-
matchesHack(nodeName: string): boolean;
|
|
376
|
-
parseRule(): Omit<TagParseRule, "tag"> | null;
|
|
377
|
-
stopEvent(event: Event): boolean;
|
|
378
|
-
get size(): number;
|
|
379
|
-
get border(): number;
|
|
380
|
-
destroy(): void;
|
|
381
|
-
posBeforeChild(child: ViewDesc): number;
|
|
382
|
-
get posBefore(): number;
|
|
383
|
-
get posAtStart(): number;
|
|
384
|
-
get posAfter(): number;
|
|
385
|
-
get posAtEnd(): number;
|
|
386
|
-
localPosFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
387
|
-
nearestDesc(dom: DOMNode): ViewDesc | undefined;
|
|
388
|
-
nearestDesc(dom: DOMNode, onlyNodes: true): NodeViewDesc | undefined;
|
|
389
|
-
getDesc(dom: DOMNode): ViewDesc | undefined;
|
|
390
|
-
posFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
391
|
-
descAt(pos: number): ViewDesc | undefined;
|
|
392
|
-
domFromPos(pos: number, side: number): {
|
|
393
|
-
node: DOMNode;
|
|
394
|
-
offset: number;
|
|
395
|
-
atom?: number;
|
|
396
|
-
};
|
|
397
|
-
parseRange(from: number, to: number, base?: number): {
|
|
398
|
-
node: DOMNode;
|
|
399
|
-
from: number;
|
|
400
|
-
to: number;
|
|
401
|
-
fromOffset: number;
|
|
402
|
-
toOffset: number;
|
|
403
|
-
};
|
|
404
|
-
emptyChildAt(side: number): boolean;
|
|
405
|
-
domAfterPos(pos: number): DOMNode;
|
|
406
|
-
setSelection(anchor: number, head: number, view: EditorView, force?: boolean): void;
|
|
407
|
-
ignoreMutation(mutation: ViewMutationRecord): boolean;
|
|
408
|
-
get contentLost(): boolean | null;
|
|
409
|
-
markDirty(from: number, to: number): void;
|
|
410
|
-
markParentsDirty(): void;
|
|
411
|
-
get domAtom(): boolean;
|
|
412
|
-
get ignoreForCoords(): boolean;
|
|
413
|
-
isText(text: string): boolean;
|
|
414
|
-
}
|
|
415
|
-
declare class NodeViewDesc extends ViewDesc {
|
|
416
|
-
node: Node;
|
|
417
|
-
outerDeco: readonly Decoration[];
|
|
418
|
-
innerDeco: DecorationSource;
|
|
419
|
-
readonly nodeDOM: DOMNode;
|
|
420
|
-
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, contentDOM: HTMLElement | null, nodeDOM: DOMNode, view: EditorView, pos: number);
|
|
421
|
-
static create(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView, pos: number): NodeViewDesc | TextViewDesc;
|
|
422
|
-
parseRule(): Omit<TagParseRule, "tag"> | null;
|
|
423
|
-
matchesNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource): boolean;
|
|
424
|
-
get size(): number;
|
|
425
|
-
get border(): 0 | 1;
|
|
426
|
-
updateChildren(view: EditorView, pos: number): void;
|
|
427
|
-
localCompositionInfo(view: EditorView, pos: number): {
|
|
428
|
-
node: Text;
|
|
429
|
-
pos: number;
|
|
430
|
-
text: string;
|
|
431
|
-
} | null;
|
|
432
|
-
protectLocalComposition(view: EditorView, { node, pos, text }: {
|
|
433
|
-
node: Text;
|
|
434
|
-
pos: number;
|
|
435
|
-
text: string;
|
|
436
|
-
}): void;
|
|
437
|
-
update(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): boolean;
|
|
438
|
-
updateInner(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): void;
|
|
439
|
-
updateOuterDeco(outerDeco: readonly Decoration[]): void;
|
|
440
|
-
selectNode(): void;
|
|
441
|
-
deselectNode(): void;
|
|
442
|
-
get domAtom(): boolean;
|
|
443
|
-
}
|
|
444
|
-
declare class TextViewDesc extends NodeViewDesc {
|
|
445
|
-
constructor(parent: ViewDesc | undefined, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, dom: DOMNode, nodeDOM: DOMNode, view: EditorView);
|
|
446
|
-
parseRule(): {
|
|
447
|
-
skip: any;
|
|
448
|
-
};
|
|
449
|
-
update(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView): boolean;
|
|
450
|
-
inParent(): boolean;
|
|
451
|
-
domFromPos(pos: number): {
|
|
452
|
-
node: globalThis.Node;
|
|
453
|
-
offset: number;
|
|
454
|
-
};
|
|
455
|
-
localPosFromDOM(dom: DOMNode, offset: number, bias: number): number;
|
|
456
|
-
ignoreMutation(mutation: ViewMutationRecord): boolean;
|
|
457
|
-
slice(from: number, to: number, view: EditorView): TextViewDesc;
|
|
458
|
-
markDirty(from: number, to: number): void;
|
|
459
|
-
get domAtom(): boolean;
|
|
460
|
-
isText(text: string): boolean;
|
|
461
|
-
}
|
|
462
363
|
|
|
463
364
|
/**
|
|
464
365
|
An editor view manages the DOM structure that represents an
|
package/dist/index.js
CHANGED
|
@@ -201,11 +201,13 @@ function clientRect(node) {
|
|
|
201
201
|
function scrollRectIntoView(view, rect, startDOM) {
|
|
202
202
|
let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5;
|
|
203
203
|
let doc = view.dom.ownerDocument;
|
|
204
|
-
for (let parent = startDOM || view.dom;;
|
|
204
|
+
for (let parent = startDOM || view.dom;;) {
|
|
205
205
|
if (!parent)
|
|
206
206
|
break;
|
|
207
|
-
if (parent.nodeType != 1)
|
|
207
|
+
if (parent.nodeType != 1) {
|
|
208
|
+
parent = parentNode(parent);
|
|
208
209
|
continue;
|
|
210
|
+
}
|
|
209
211
|
let elt = parent;
|
|
210
212
|
let atTop = elt == doc.body;
|
|
211
213
|
let bounding = atTop ? windowRect(doc) : clientRect(elt);
|
|
@@ -234,8 +236,10 @@ function scrollRectIntoView(view, rect, startDOM) {
|
|
|
234
236
|
rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY };
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
|
-
|
|
239
|
+
let pos = atTop ? "fixed" : getComputedStyle(parent).position;
|
|
240
|
+
if (/^(fixed|sticky)$/.test(pos))
|
|
238
241
|
break;
|
|
242
|
+
parent = pos == "absolute" ? parent.offsetParent : parentNode(parent);
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
245
|
// Store the scroll position of the editor's parent nodes, along with
|
|
@@ -4705,6 +4709,7 @@ class DOMObserver {
|
|
|
4705
4709
|
view.input.lastFocus = 0;
|
|
4706
4710
|
selectionToDOM(view);
|
|
4707
4711
|
this.currentSelection.set(sel);
|
|
4712
|
+
view.scrollToSelection();
|
|
4708
4713
|
}
|
|
4709
4714
|
else if (from > -1 || newSel) {
|
|
4710
4715
|
if (from > -1) {
|
package/package.json
CHANGED
package/src/domcoords.ts
CHANGED
|
@@ -32,9 +32,9 @@ function clientRect(node: HTMLElement): Rect {
|
|
|
32
32
|
export function scrollRectIntoView(view: EditorView, rect: Rect, startDOM: Node) {
|
|
33
33
|
let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5
|
|
34
34
|
let doc = view.dom.ownerDocument
|
|
35
|
-
for (let parent: Node | null = startDOM || view.dom;;
|
|
35
|
+
for (let parent: Node | null = startDOM || view.dom;;) {
|
|
36
36
|
if (!parent) break
|
|
37
|
-
if (parent.nodeType != 1) continue
|
|
37
|
+
if (parent.nodeType != 1) { parent = parentNode(parent); continue }
|
|
38
38
|
let elt = parent as HTMLElement
|
|
39
39
|
let atTop = elt == doc.body
|
|
40
40
|
let bounding = atTop ? windowRect(doc) : clientRect(elt as HTMLElement)
|
|
@@ -60,7 +60,9 @@ export function scrollRectIntoView(view: EditorView, rect: Rect, startDOM: Node)
|
|
|
60
60
|
rect = {left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY}
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
let pos: string = atTop ? "fixed" : getComputedStyle(parent as HTMLElement).position
|
|
64
|
+
if (/^(fixed|sticky)$/.test(pos)) break
|
|
65
|
+
parent = pos == "absolute" ? (parent as HTMLElement).offsetParent : parentNode(parent)
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
package/src/domobserver.ts
CHANGED
package/src/viewdesc.ts
CHANGED
|
@@ -7,7 +7,10 @@ import {Decoration, DecorationSource, WidgetConstructor, WidgetType, NodeType} f
|
|
|
7
7
|
import {EditorView} from "./index"
|
|
8
8
|
|
|
9
9
|
declare global {
|
|
10
|
-
interface Node {
|
|
10
|
+
interface Node {
|
|
11
|
+
/// @internal
|
|
12
|
+
pmViewDesc?: ViewDesc
|
|
13
|
+
}
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/// A ViewMutationRecord represents a DOM
|