prosemirror-view 1.28.3 → 1.29.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 +20 -2
- package/README.md +2 -2
- package/dist/index.cjs +22 -11
- package/dist/index.d.ts +6 -6
- package/dist/index.js +18 -11
- package/package.json +1 -1
- package/src/clipboard.ts +12 -8
- package/src/decoration.ts +7 -4
- package/src/domchange.ts +1 -1
- package/src/index.ts +6 -6
- package/src/input.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## 1.29.1 (2022-11-14)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix a problem when returning decorations from an outer editor from the `decorations` prop.
|
|
6
|
+
|
|
7
|
+
## 1.29.0 (2022-10-12)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Fix an issue where HTML comments added to the clipboard by the OS throw off the clipboard parser.
|
|
12
|
+
|
|
13
|
+
Make sure Chrome Android's native behavior on pressing Enter in an empty nested list item is replaced by the result of the editor's Enter key handler.
|
|
14
|
+
|
|
15
|
+
### New features
|
|
16
|
+
|
|
17
|
+
The `transformPastedHTML`, `transformPastedText`, `transformPasted`, `transformCopied`, and `clipboardTextSerializer` props are now passed the view instance as last argument.
|
|
18
|
+
|
|
1
19
|
## 1.28.3 (2022-10-05)
|
|
2
20
|
|
|
3
21
|
### Bug fixes
|
|
@@ -20,11 +38,11 @@ Fix an issue where the editor would reset its scroll position to the top of the
|
|
|
20
38
|
|
|
21
39
|
### Bug fixes
|
|
22
40
|
|
|
23
|
-
Fix an issue where the editor wouldn't realize it was focused on IE when IE's resize controls are on an element inside the content.
|
|
41
|
+
Fix an issue where the editor wouldn't realize it was focused on IE when IE's resize controls are on an element inside the content.
|
|
24
42
|
|
|
25
43
|
### New features
|
|
26
44
|
|
|
27
|
-
The new `transformCopied` prop can be used to transform a copied/cut slice before it is serialized to the clipboard.
|
|
45
|
+
The new `transformCopied` prop can be used to transform a copied/cut slice before it is serialized to the clipboard.
|
|
28
46
|
|
|
29
47
|
## 1.27.2 (2022-08-19)
|
|
30
48
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# prosemirror-view
|
|
2
2
|
|
|
3
|
-
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**
|
|
3
|
+
[ [**WEBSITE**](https://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-view/blob/master/CHANGELOG.md) ]
|
|
4
4
|
|
|
5
5
|
This is a [core module](https://prosemirror.net/docs/ref/#view) of [ProseMirror](https://prosemirror.net).
|
|
6
6
|
ProseMirror is a well-behaved rich semantic content editor based on
|
|
@@ -19,7 +19,7 @@ This code is released under an
|
|
|
19
19
|
[MIT license](https://github.com/prosemirror/prosemirror/tree/master/LICENSE).
|
|
20
20
|
There's a [forum](http://discuss.prosemirror.net) for general
|
|
21
21
|
discussion and support requests, and the
|
|
22
|
-
[
|
|
22
|
+
[GitHub bug tracker](https://github.com/prosemirror/prosemirror/issues)
|
|
23
23
|
is the place to report issues.
|
|
24
24
|
|
|
25
25
|
We aim to be an inclusive, welcoming community. To make that explicit,
|
package/dist/index.cjs
CHANGED
|
@@ -2908,7 +2908,7 @@ function captureKeyDown(view, event) {
|
|
|
2908
2908
|
|
|
2909
2909
|
function serializeForClipboard(view, slice) {
|
|
2910
2910
|
view.someProp("transformCopied", function (f) {
|
|
2911
|
-
slice = f(slice);
|
|
2911
|
+
slice = f(slice, view);
|
|
2912
2912
|
});
|
|
2913
2913
|
var context = [],
|
|
2914
2914
|
_slice = slice,
|
|
@@ -2951,7 +2951,7 @@ function serializeForClipboard(view, slice) {
|
|
|
2951
2951
|
|
|
2952
2952
|
if (firstChild && firstChild.nodeType == 1) firstChild.setAttribute("data-pm-slice", "".concat(openStart, " ").concat(openEnd).concat(wrappers ? " -".concat(wrappers) : "", " ").concat(JSON.stringify(context)));
|
|
2953
2953
|
var text = view.someProp("clipboardTextSerializer", function (f) {
|
|
2954
|
-
return f(slice);
|
|
2954
|
+
return f(slice, view);
|
|
2955
2955
|
}) || slice.content.textBetween(0, slice.content.size, "\n\n");
|
|
2956
2956
|
return {
|
|
2957
2957
|
dom: wrap,
|
|
@@ -2967,11 +2967,11 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2967
2967
|
|
|
2968
2968
|
if (asText) {
|
|
2969
2969
|
view.someProp("transformPastedText", function (f) {
|
|
2970
|
-
text = f(text, inCode || plainText);
|
|
2970
|
+
text = f(text, inCode || plainText, view);
|
|
2971
2971
|
});
|
|
2972
2972
|
if (inCode) return text ? new prosemirrorModel.Slice(prosemirrorModel.Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : prosemirrorModel.Slice.empty;
|
|
2973
2973
|
var parsed = view.someProp("clipboardTextParser", function (f) {
|
|
2974
|
-
return f(text, $context, plainText);
|
|
2974
|
+
return f(text, $context, plainText, view);
|
|
2975
2975
|
});
|
|
2976
2976
|
|
|
2977
2977
|
if (parsed) {
|
|
@@ -2988,7 +2988,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2988
2988
|
}
|
|
2989
2989
|
} else {
|
|
2990
2990
|
view.someProp("transformPastedHTML", function (f) {
|
|
2991
|
-
html = f(html);
|
|
2991
|
+
html = f(html, view);
|
|
2992
2992
|
});
|
|
2993
2993
|
dom = readHTML(html);
|
|
2994
2994
|
if (webkit) restoreReplacedSpaces(dom);
|
|
@@ -2996,8 +2996,15 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2996
2996
|
|
|
2997
2997
|
var contextNode = dom && dom.querySelector("[data-pm-slice]");
|
|
2998
2998
|
var sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || "");
|
|
2999
|
-
if (sliceData && sliceData[3]) for (var i = +sliceData[3]; i > 0
|
|
3000
|
-
|
|
2999
|
+
if (sliceData && sliceData[3]) for (var i = +sliceData[3]; i > 0; i--) {
|
|
3000
|
+
var child = dom.firstChild;
|
|
3001
|
+
|
|
3002
|
+
while (child && child.nodeType != 1) {
|
|
3003
|
+
child = child.nextSibling;
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
if (!child) break;
|
|
3007
|
+
dom = child;
|
|
3001
3008
|
}
|
|
3002
3009
|
|
|
3003
3010
|
if (!slice) {
|
|
@@ -3032,7 +3039,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
3032
3039
|
}
|
|
3033
3040
|
|
|
3034
3041
|
view.someProp("transformPasted", function (f) {
|
|
3035
|
-
slice = f(slice);
|
|
3042
|
+
slice = f(slice, view);
|
|
3036
3043
|
});
|
|
3037
3044
|
return slice;
|
|
3038
3045
|
}
|
|
@@ -3862,7 +3869,7 @@ editHandlers.drop = function (view, _event) {
|
|
|
3862
3869
|
|
|
3863
3870
|
if (slice) {
|
|
3864
3871
|
view.someProp("transformPasted", function (f) {
|
|
3865
|
-
slice = f(slice);
|
|
3872
|
+
slice = f(slice, view);
|
|
3866
3873
|
});
|
|
3867
3874
|
} else {
|
|
3868
3875
|
slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
|
|
@@ -4435,7 +4442,11 @@ var DecorationGroup = function () {
|
|
|
4435
4442
|
return members[0];
|
|
4436
4443
|
|
|
4437
4444
|
default:
|
|
4438
|
-
return new DecorationGroup(members)
|
|
4445
|
+
return new DecorationGroup(members.every(function (m) {
|
|
4446
|
+
return m instanceof DecorationSet;
|
|
4447
|
+
}) ? members : members.reduce(function (r, m) {
|
|
4448
|
+
return r.concat(m instanceof DecorationSet ? m : m.members);
|
|
4449
|
+
}, []));
|
|
4439
4450
|
}
|
|
4440
4451
|
}
|
|
4441
4452
|
}]);
|
|
@@ -5180,7 +5191,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
5180
5191
|
var change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide);
|
|
5181
5192
|
|
|
5182
5193
|
if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some(function (n) {
|
|
5183
|
-
return n.nodeName == "DIV" || n.nodeName == "P";
|
|
5194
|
+
return n.nodeName == "DIV" || n.nodeName == "P" || n.nodeName == "LI";
|
|
5184
5195
|
}) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", function (f) {
|
|
5185
5196
|
return f(view, keyEvent(13, "Enter"));
|
|
5186
5197
|
})) {
|
package/dist/index.d.ts
CHANGED
|
@@ -673,7 +673,7 @@ interface EditorProps<P = any> {
|
|
|
673
673
|
Can be used to transform pasted HTML text, _before_ it is parsed,
|
|
674
674
|
for example to clean it up.
|
|
675
675
|
*/
|
|
676
|
-
transformPastedHTML?: (this: P, html: string) => string;
|
|
676
|
+
transformPastedHTML?: (this: P, html: string, view: EditorView) => string;
|
|
677
677
|
/**
|
|
678
678
|
The [parser](https://prosemirror.net/docs/ref/#model.DOMParser) to use when reading content from
|
|
679
679
|
the clipboard. When not given, the value of the
|
|
@@ -684,7 +684,7 @@ interface EditorProps<P = any> {
|
|
|
684
684
|
Transform pasted plain text. The `plain` flag will be true when
|
|
685
685
|
the text is pasted as plain text.
|
|
686
686
|
*/
|
|
687
|
-
transformPastedText?: (this: P, text: string, plain: boolean) => string;
|
|
687
|
+
transformPastedText?: (this: P, text: string, plain: boolean, view: EditorView) => string;
|
|
688
688
|
/**
|
|
689
689
|
A function to parse text from the clipboard into a document
|
|
690
690
|
slice. Called after
|
|
@@ -694,17 +694,17 @@ interface EditorProps<P = any> {
|
|
|
694
694
|
[`clipboardParser`](https://prosemirror.net/docs/ref/#view.EditorProps.clipboardParser) on it.
|
|
695
695
|
The `plain` flag will be true when the text is pasted as plain text.
|
|
696
696
|
*/
|
|
697
|
-
clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean) => Slice;
|
|
697
|
+
clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean, view: EditorView) => Slice;
|
|
698
698
|
/**
|
|
699
699
|
Can be used to transform pasted or dragged-and-dropped content
|
|
700
700
|
before it is applied to the document.
|
|
701
701
|
*/
|
|
702
|
-
transformPasted?: (this: P, slice: Slice) => Slice;
|
|
702
|
+
transformPasted?: (this: P, slice: Slice, view: EditorView) => Slice;
|
|
703
703
|
/**
|
|
704
704
|
Can be used to transform copied or cut content before it is
|
|
705
705
|
serialized to the clipboard.
|
|
706
706
|
*/
|
|
707
|
-
transformCopied?: (this: P, slice: Slice) => Slice;
|
|
707
|
+
transformCopied?: (this: P, slice: Slice, view: EditorView) => Slice;
|
|
708
708
|
/**
|
|
709
709
|
Allows you to pass custom rendering and behavior logic for
|
|
710
710
|
nodes. Should map node names to constructor functions that
|
|
@@ -759,7 +759,7 @@ interface EditorProps<P = any> {
|
|
|
759
759
|
editor will use [`textBetween`](https://prosemirror.net/docs/ref/#model.Node.textBetween) on the
|
|
760
760
|
selected range.
|
|
761
761
|
*/
|
|
762
|
-
clipboardTextSerializer?: (this: P, content: Slice) => string;
|
|
762
|
+
clipboardTextSerializer?: (this: P, content: Slice, view: EditorView) => string;
|
|
763
763
|
/**
|
|
764
764
|
A set of [document decorations](https://prosemirror.net/docs/ref/#view.Decoration) to show in the
|
|
765
765
|
view.
|
package/dist/index.js
CHANGED
|
@@ -2540,7 +2540,7 @@ function captureKeyDown(view, event) {
|
|
|
2540
2540
|
}
|
|
2541
2541
|
|
|
2542
2542
|
function serializeForClipboard(view, slice) {
|
|
2543
|
-
view.someProp("transformCopied", f => { slice = f(slice); });
|
|
2543
|
+
view.someProp("transformCopied", f => { slice = f(slice, view); });
|
|
2544
2544
|
let context = [], { content, openStart, openEnd } = slice;
|
|
2545
2545
|
while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) {
|
|
2546
2546
|
openStart--;
|
|
@@ -2565,7 +2565,7 @@ function serializeForClipboard(view, slice) {
|
|
|
2565
2565
|
}
|
|
2566
2566
|
if (firstChild && firstChild.nodeType == 1)
|
|
2567
2567
|
firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`);
|
|
2568
|
-
let text = view.someProp("clipboardTextSerializer", f => f(slice)) ||
|
|
2568
|
+
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
|
|
2569
2569
|
slice.content.textBetween(0, slice.content.size, "\n\n");
|
|
2570
2570
|
return { dom: wrap, text };
|
|
2571
2571
|
}
|
|
@@ -2577,10 +2577,10 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2577
2577
|
return null;
|
|
2578
2578
|
let asText = text && (plainText || inCode || !html);
|
|
2579
2579
|
if (asText) {
|
|
2580
|
-
view.someProp("transformPastedText", f => { text = f(text, inCode || plainText); });
|
|
2580
|
+
view.someProp("transformPastedText", f => { text = f(text, inCode || plainText, view); });
|
|
2581
2581
|
if (inCode)
|
|
2582
2582
|
return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty;
|
|
2583
|
-
let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText));
|
|
2583
|
+
let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText, view));
|
|
2584
2584
|
if (parsed) {
|
|
2585
2585
|
slice = parsed;
|
|
2586
2586
|
}
|
|
@@ -2596,7 +2596,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2596
2596
|
}
|
|
2597
2597
|
}
|
|
2598
2598
|
else {
|
|
2599
|
-
view.someProp("transformPastedHTML", f => { html = f(html); });
|
|
2599
|
+
view.someProp("transformPastedHTML", f => { html = f(html, view); });
|
|
2600
2600
|
dom = readHTML(html);
|
|
2601
2601
|
if (webkit)
|
|
2602
2602
|
restoreReplacedSpaces(dom);
|
|
@@ -2604,8 +2604,14 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2604
2604
|
let contextNode = dom && dom.querySelector("[data-pm-slice]");
|
|
2605
2605
|
let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || "");
|
|
2606
2606
|
if (sliceData && sliceData[3])
|
|
2607
|
-
for (let i = +sliceData[3]; i > 0
|
|
2608
|
-
|
|
2607
|
+
for (let i = +sliceData[3]; i > 0; i--) {
|
|
2608
|
+
let child = dom.firstChild;
|
|
2609
|
+
while (child && child.nodeType != 1)
|
|
2610
|
+
child = child.nextSibling;
|
|
2611
|
+
if (!child)
|
|
2612
|
+
break;
|
|
2613
|
+
dom = child;
|
|
2614
|
+
}
|
|
2609
2615
|
if (!slice) {
|
|
2610
2616
|
let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema);
|
|
2611
2617
|
slice = parser.parseSlice(dom, {
|
|
@@ -2631,7 +2637,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
|
|
|
2631
2637
|
slice = closeSlice(slice, openStart, openEnd);
|
|
2632
2638
|
}
|
|
2633
2639
|
}
|
|
2634
|
-
view.someProp("transformPasted", f => { slice = f(slice); });
|
|
2640
|
+
view.someProp("transformPasted", f => { slice = f(slice, view); });
|
|
2635
2641
|
return slice;
|
|
2636
2642
|
}
|
|
2637
2643
|
const inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;
|
|
@@ -3421,7 +3427,7 @@ editHandlers.drop = (view, _event) => {
|
|
|
3421
3427
|
let $mouse = view.state.doc.resolve(eventPos.pos);
|
|
3422
3428
|
let slice = dragging && dragging.slice;
|
|
3423
3429
|
if (slice) {
|
|
3424
|
-
view.someProp("transformPasted", f => { slice = f(slice); });
|
|
3430
|
+
view.someProp("transformPasted", f => { slice = f(slice, view); });
|
|
3425
3431
|
}
|
|
3426
3432
|
else {
|
|
3427
3433
|
slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
|
|
@@ -3970,7 +3976,8 @@ class DecorationGroup {
|
|
|
3970
3976
|
switch (members.length) {
|
|
3971
3977
|
case 0: return empty;
|
|
3972
3978
|
case 1: return members[0];
|
|
3973
|
-
default: return new DecorationGroup(members)
|
|
3979
|
+
default: return new DecorationGroup(members.every(m => m instanceof DecorationSet) ? members :
|
|
3980
|
+
members.reduce((r, m) => r.concat(m instanceof DecorationSet ? m : m.members), []));
|
|
3974
3981
|
}
|
|
3975
3982
|
}
|
|
3976
3983
|
}
|
|
@@ -4593,7 +4600,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4593
4600
|
view.input.lastKeyCode = null;
|
|
4594
4601
|
let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide);
|
|
4595
4602
|
if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) &&
|
|
4596
|
-
addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P") &&
|
|
4603
|
+
addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P" || n.nodeName == "LI") &&
|
|
4597
4604
|
(!change || change.endA >= change.endB) &&
|
|
4598
4605
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
4599
4606
|
view.input.lastIOSEnter = 0;
|
package/package.json
CHANGED
package/src/clipboard.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as browser from "./browser"
|
|
|
3
3
|
import {EditorView} from "./index"
|
|
4
4
|
|
|
5
5
|
export function serializeForClipboard(view: EditorView, slice: Slice) {
|
|
6
|
-
view.someProp("transformCopied", f => { slice = f(slice
|
|
6
|
+
view.someProp("transformCopied", f => { slice = f(slice!, view) })
|
|
7
7
|
|
|
8
8
|
let context = [], {content, openStart, openEnd} = slice
|
|
9
9
|
while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild!.childCount == 1) {
|
|
@@ -33,7 +33,7 @@ export function serializeForClipboard(view: EditorView, slice: Slice) {
|
|
|
33
33
|
(firstChild as HTMLElement).setAttribute(
|
|
34
34
|
"data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`)
|
|
35
35
|
|
|
36
|
-
let text = view.someProp("clipboardTextSerializer", f => f(slice)) ||
|
|
36
|
+
let text = view.someProp("clipboardTextSerializer", f => f(slice, view)) ||
|
|
37
37
|
slice.content.textBetween(0, slice.content.size, "\n\n")
|
|
38
38
|
|
|
39
39
|
return {dom: wrap, text}
|
|
@@ -46,9 +46,9 @@ export function parseFromClipboard(view: EditorView, text: string, html: string
|
|
|
46
46
|
if (!html && !text) return null
|
|
47
47
|
let asText = text && (plainText || inCode || !html)
|
|
48
48
|
if (asText) {
|
|
49
|
-
view.someProp("transformPastedText", f => { text = f(text, inCode || plainText) })
|
|
49
|
+
view.someProp("transformPastedText", f => { text = f(text, inCode || plainText, view) })
|
|
50
50
|
if (inCode) return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty
|
|
51
|
-
let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText))
|
|
51
|
+
let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText, view))
|
|
52
52
|
if (parsed) {
|
|
53
53
|
slice = parsed
|
|
54
54
|
} else {
|
|
@@ -61,15 +61,19 @@ export function parseFromClipboard(view: EditorView, text: string, html: string
|
|
|
61
61
|
})
|
|
62
62
|
}
|
|
63
63
|
} else {
|
|
64
|
-
view.someProp("transformPastedHTML", f => { html = f(html
|
|
64
|
+
view.someProp("transformPastedHTML", f => { html = f(html!, view) })
|
|
65
65
|
dom = readHTML(html!)
|
|
66
66
|
if (browser.webkit) restoreReplacedSpaces(dom)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
let contextNode = dom && dom.querySelector("[data-pm-slice]")
|
|
70
70
|
let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || "")
|
|
71
|
-
if (sliceData && sliceData[3]) for (let i = +sliceData[3]; i > 0
|
|
72
|
-
|
|
71
|
+
if (sliceData && sliceData[3]) for (let i = +sliceData[3]; i > 0; i--) {
|
|
72
|
+
let child = dom!.firstChild
|
|
73
|
+
while (child && child.nodeType != 1) child = child.nextSibling
|
|
74
|
+
if (!child) break
|
|
75
|
+
dom = child as HTMLElement
|
|
76
|
+
}
|
|
73
77
|
|
|
74
78
|
if (!slice) {
|
|
75
79
|
let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema)
|
|
@@ -97,7 +101,7 @@ export function parseFromClipboard(view: EditorView, text: string, html: string
|
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
|
|
100
|
-
view.someProp("transformPasted", f => { slice = f(slice
|
|
104
|
+
view.someProp("transformPasted", f => { slice = f(slice!, view) })
|
|
101
105
|
return slice
|
|
102
106
|
}
|
|
103
107
|
|
package/src/decoration.ts
CHANGED
|
@@ -528,11 +528,14 @@ class DecorationGroup implements DecorationSource {
|
|
|
528
528
|
|
|
529
529
|
// Create a group for the given array of decoration sets, or return
|
|
530
530
|
// a single set when possible.
|
|
531
|
-
static from(members: readonly
|
|
531
|
+
static from(members: readonly DecorationSource[]): DecorationSource {
|
|
532
532
|
switch (members.length) {
|
|
533
533
|
case 0: return empty
|
|
534
534
|
case 1: return members[0]
|
|
535
|
-
default: return new DecorationGroup(
|
|
535
|
+
default: return new DecorationGroup(
|
|
536
|
+
members.every(m => m instanceof DecorationSet) ? members as DecorationSet[] :
|
|
537
|
+
members.reduce((r, m) => r.concat(m instanceof DecorationSet ? m : (m as DecorationGroup).members),
|
|
538
|
+
[] as DecorationSet[]))
|
|
536
539
|
}
|
|
537
540
|
}
|
|
538
541
|
}
|
|
@@ -753,8 +756,8 @@ function insertAhead(array: Decoration[], i: number, deco: Decoration) {
|
|
|
753
756
|
}
|
|
754
757
|
|
|
755
758
|
// Get the decorations associated with the current props of a view.
|
|
756
|
-
export function viewDecorations(view: EditorView):
|
|
757
|
-
let found = []
|
|
759
|
+
export function viewDecorations(view: EditorView): DecorationSource {
|
|
760
|
+
let found: DecorationSource[] = []
|
|
758
761
|
view.someProp("decorations", f => {
|
|
759
762
|
let result = f(view.state)
|
|
760
763
|
if (result && result != empty) found.push(result)
|
package/src/domchange.ts
CHANGED
|
@@ -111,7 +111,7 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
|
|
|
111
111
|
|
|
112
112
|
let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide)
|
|
113
113
|
if ((browser.ios && view.input.lastIOSEnter > Date.now() - 225 || browser.android) &&
|
|
114
|
-
addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P") &&
|
|
114
|
+
addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P" || n.nodeName == "LI") &&
|
|
115
115
|
(!change || change.endA >= change.endB) &&
|
|
116
116
|
view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
|
|
117
117
|
view.input.lastIOSEnter = 0
|
package/src/index.ts
CHANGED
|
@@ -638,7 +638,7 @@ export interface EditorProps<P = any> {
|
|
|
638
638
|
|
|
639
639
|
/// Can be used to transform pasted HTML text, _before_ it is parsed,
|
|
640
640
|
/// for example to clean it up.
|
|
641
|
-
transformPastedHTML?: (this: P, html: string) => string
|
|
641
|
+
transformPastedHTML?: (this: P, html: string, view: EditorView) => string
|
|
642
642
|
|
|
643
643
|
/// The [parser](#model.DOMParser) to use when reading content from
|
|
644
644
|
/// the clipboard. When not given, the value of the
|
|
@@ -647,7 +647,7 @@ export interface EditorProps<P = any> {
|
|
|
647
647
|
|
|
648
648
|
/// Transform pasted plain text. The `plain` flag will be true when
|
|
649
649
|
/// the text is pasted as plain text.
|
|
650
|
-
transformPastedText?: (this: P, text: string, plain: boolean) => string
|
|
650
|
+
transformPastedText?: (this: P, text: string, plain: boolean, view: EditorView) => string
|
|
651
651
|
|
|
652
652
|
/// A function to parse text from the clipboard into a document
|
|
653
653
|
/// slice. Called after
|
|
@@ -656,15 +656,15 @@ export interface EditorProps<P = any> {
|
|
|
656
656
|
/// in `<p>` tags, and call
|
|
657
657
|
/// [`clipboardParser`](#view.EditorProps.clipboardParser) on it.
|
|
658
658
|
/// The `plain` flag will be true when the text is pasted as plain text.
|
|
659
|
-
clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean) => Slice
|
|
659
|
+
clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean, view: EditorView) => Slice
|
|
660
660
|
|
|
661
661
|
/// Can be used to transform pasted or dragged-and-dropped content
|
|
662
662
|
/// before it is applied to the document.
|
|
663
|
-
transformPasted?: (this: P, slice: Slice) => Slice
|
|
663
|
+
transformPasted?: (this: P, slice: Slice, view: EditorView) => Slice
|
|
664
664
|
|
|
665
665
|
/// Can be used to transform copied or cut content before it is
|
|
666
666
|
/// serialized to the clipboard.
|
|
667
|
-
transformCopied?: (this: P, slice: Slice) => Slice
|
|
667
|
+
transformCopied?: (this: P, slice: Slice, view: EditorView) => Slice
|
|
668
668
|
|
|
669
669
|
/// Allows you to pass custom rendering and behavior logic for
|
|
670
670
|
/// nodes. Should map node names to constructor functions that
|
|
@@ -711,7 +711,7 @@ export interface EditorProps<P = any> {
|
|
|
711
711
|
/// selection when copying text to the clipboard. By default, the
|
|
712
712
|
/// editor will use [`textBetween`](#model.Node.textBetween) on the
|
|
713
713
|
/// selected range.
|
|
714
|
-
clipboardTextSerializer?: (this: P, content: Slice) => string
|
|
714
|
+
clipboardTextSerializer?: (this: P, content: Slice, view: EditorView) => string
|
|
715
715
|
|
|
716
716
|
/// A set of [document decorations](#view.Decoration) to show in the
|
|
717
717
|
/// view.
|
package/src/input.ts
CHANGED
|
@@ -666,7 +666,7 @@ editHandlers.drop = (view, _event) => {
|
|
|
666
666
|
let $mouse = view.state.doc.resolve(eventPos.pos)
|
|
667
667
|
let slice = dragging && dragging.slice
|
|
668
668
|
if (slice) {
|
|
669
|
-
view.someProp("transformPasted", f => { slice = f(slice
|
|
669
|
+
view.someProp("transformPasted", f => { slice = f(slice!, view) })
|
|
670
670
|
} else {
|
|
671
671
|
slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"),
|
|
672
672
|
brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse)
|