prosemirror-view 1.34.1 → 1.34.2
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 +18 -4
- package/dist/index.js +17 -4
- package/package.json +1 -1
- package/src/clipboard.ts +10 -1
- package/src/domobserver.ts +5 -2
- package/src/input.ts +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 1.34.2 (2024-09-03)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix pasting in Chrome with the require-trusted-types-for CSP enabled.
|
|
6
|
+
|
|
7
|
+
Fix an issue where, for some kinds of IME on Windows, pressing Enter while in a composition would execute the resulting command on the wrong selection, erasing some typed content.
|
|
8
|
+
|
|
1
9
|
## 1.34.1 (2024-08-26)
|
|
2
10
|
|
|
3
11
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -2766,6 +2766,15 @@ var _detachedDoc = null;
|
|
|
2766
2766
|
function detachedDoc() {
|
|
2767
2767
|
return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"));
|
|
2768
2768
|
}
|
|
2769
|
+
function maybeWrapTrusted(html) {
|
|
2770
|
+
var trustedTypes = window.trustedTypes;
|
|
2771
|
+
if (!trustedTypes) return html;
|
|
2772
|
+
return trustedTypes.createPolicy("detachedDocument", {
|
|
2773
|
+
createHTML: function createHTML(s) {
|
|
2774
|
+
return s;
|
|
2775
|
+
}
|
|
2776
|
+
}).createHTML(html);
|
|
2777
|
+
}
|
|
2769
2778
|
function readHTML(html) {
|
|
2770
2779
|
var metas = /^(\s*<meta [^>]*>)*/.exec(html);
|
|
2771
2780
|
if (metas) html = html.slice(metas[0].length);
|
|
@@ -2777,7 +2786,7 @@ function readHTML(html) {
|
|
|
2777
2786
|
}).join("") + html + wrap.map(function (n) {
|
|
2778
2787
|
return "</" + n + ">";
|
|
2779
2788
|
}).reverse().join("");
|
|
2780
|
-
elt.innerHTML = html;
|
|
2789
|
+
elt.innerHTML = maybeWrapTrusted(html);
|
|
2781
2790
|
if (wrap) for (var i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt;
|
|
2782
2791
|
return elt;
|
|
2783
2792
|
}
|
|
@@ -2901,7 +2910,7 @@ editHandlers.keydown = function (view, _event) {
|
|
|
2901
2910
|
view.input.lastKeyCode = event.keyCode;
|
|
2902
2911
|
view.input.lastKeyCodeTime = Date.now();
|
|
2903
2912
|
if (android && chrome && event.keyCode == 13) return;
|
|
2904
|
-
if (event.keyCode != 229) view.domObserver.forceFlush();
|
|
2913
|
+
if (view.domObserver.selectionChanged(view.domSelectionRange())) view.domObserver.flush();else if (event.keyCode != 229) view.domObserver.forceFlush();
|
|
2905
2914
|
if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) {
|
|
2906
2915
|
var now = Date.now();
|
|
2907
2916
|
view.input.lastIOSEnter = now;
|
|
@@ -4266,6 +4275,11 @@ var DOMObserver = function () {
|
|
|
4266
4275
|
}
|
|
4267
4276
|
return this.queue;
|
|
4268
4277
|
}
|
|
4278
|
+
}, {
|
|
4279
|
+
key: "selectionChanged",
|
|
4280
|
+
value: function selectionChanged(sel) {
|
|
4281
|
+
return !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel);
|
|
4282
|
+
}
|
|
4269
4283
|
}, {
|
|
4270
4284
|
key: "flush",
|
|
4271
4285
|
value: function flush() {
|
|
@@ -4273,8 +4287,8 @@ var DOMObserver = function () {
|
|
|
4273
4287
|
if (!view.docView || this.flushingSoon > -1) return;
|
|
4274
4288
|
var mutations = this.pendingRecords();
|
|
4275
4289
|
if (mutations.length) this.queue = [];
|
|
4276
|
-
var sel = view.domSelectionRange()
|
|
4277
|
-
|
|
4290
|
+
var sel = view.domSelectionRange(),
|
|
4291
|
+
newSel = this.selectionChanged(sel);
|
|
4278
4292
|
var from = -1,
|
|
4279
4293
|
to = -1,
|
|
4280
4294
|
typeOver = false,
|
package/dist/index.js
CHANGED
|
@@ -2937,6 +2937,15 @@ let _detachedDoc = null;
|
|
|
2937
2937
|
function detachedDoc() {
|
|
2938
2938
|
return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"));
|
|
2939
2939
|
}
|
|
2940
|
+
function maybeWrapTrusted(html) {
|
|
2941
|
+
let trustedTypes = window.trustedTypes;
|
|
2942
|
+
if (!trustedTypes)
|
|
2943
|
+
return html;
|
|
2944
|
+
// With the require-trusted-types-for CSP, Chrome will block
|
|
2945
|
+
// innerHTML, even on a detached document. This wraps the string in
|
|
2946
|
+
// a way that makes the browser allow us to use its parser again.
|
|
2947
|
+
return trustedTypes.createPolicy("detachedDocument", { createHTML: (s) => s }).createHTML(html);
|
|
2948
|
+
}
|
|
2940
2949
|
function readHTML(html) {
|
|
2941
2950
|
let metas = /^(\s*<meta [^>]*>)*/.exec(html);
|
|
2942
2951
|
if (metas)
|
|
@@ -2945,7 +2954,7 @@ function readHTML(html) {
|
|
|
2945
2954
|
let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap;
|
|
2946
2955
|
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()])
|
|
2947
2956
|
html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "</" + n + ">").reverse().join("");
|
|
2948
|
-
elt.innerHTML = html;
|
|
2957
|
+
elt.innerHTML = maybeWrapTrusted(html);
|
|
2949
2958
|
if (wrap)
|
|
2950
2959
|
for (let i = 0; i < wrap.length; i++)
|
|
2951
2960
|
elt = elt.querySelector(wrap[i]) || elt;
|
|
@@ -3086,7 +3095,9 @@ editHandlers.keydown = (view, _event) => {
|
|
|
3086
3095
|
// and handling them eagerly tends to corrupt the input.
|
|
3087
3096
|
if (android && chrome && event.keyCode == 13)
|
|
3088
3097
|
return;
|
|
3089
|
-
if (
|
|
3098
|
+
if (view.domObserver.selectionChanged(view.domSelectionRange()))
|
|
3099
|
+
view.domObserver.flush();
|
|
3100
|
+
else if (event.keyCode != 229)
|
|
3090
3101
|
view.domObserver.forceFlush();
|
|
3091
3102
|
// On iOS, if we preventDefault enter key presses, the virtual
|
|
3092
3103
|
// keyboard gets confused. So the hack here is to set a flag that
|
|
@@ -4609,6 +4620,9 @@ class DOMObserver {
|
|
|
4609
4620
|
this.queue.push(mut);
|
|
4610
4621
|
return this.queue;
|
|
4611
4622
|
}
|
|
4623
|
+
selectionChanged(sel) {
|
|
4624
|
+
return !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel);
|
|
4625
|
+
}
|
|
4612
4626
|
flush() {
|
|
4613
4627
|
let { view } = this;
|
|
4614
4628
|
if (!view.docView || this.flushingSoon > -1)
|
|
@@ -4616,8 +4630,7 @@ class DOMObserver {
|
|
|
4616
4630
|
let mutations = this.pendingRecords();
|
|
4617
4631
|
if (mutations.length)
|
|
4618
4632
|
this.queue = [];
|
|
4619
|
-
let sel = view.domSelectionRange();
|
|
4620
|
-
let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
|
|
4633
|
+
let sel = view.domSelectionRange(), newSel = this.selectionChanged(sel);
|
|
4621
4634
|
let from = -1, to = -1, typeOver = false, added = [];
|
|
4622
4635
|
if (view.editable) {
|
|
4623
4636
|
for (let i = 0; i < mutations.length; i++) {
|
package/package.json
CHANGED
package/src/clipboard.ts
CHANGED
|
@@ -204,6 +204,15 @@ function detachedDoc() {
|
|
|
204
204
|
return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"))
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
function maybeWrapTrusted(html: string): string {
|
|
208
|
+
let trustedTypes = (window as any).trustedTypes
|
|
209
|
+
if (!trustedTypes) return html
|
|
210
|
+
// With the require-trusted-types-for CSP, Chrome will block
|
|
211
|
+
// innerHTML, even on a detached document. This wraps the string in
|
|
212
|
+
// a way that makes the browser allow us to use its parser again.
|
|
213
|
+
return trustedTypes.createPolicy("detachedDocument", {createHTML: (s: string) => s}).createHTML(html)
|
|
214
|
+
}
|
|
215
|
+
|
|
207
216
|
function readHTML(html: string) {
|
|
208
217
|
let metas = /^(\s*<meta [^>]*>)*/.exec(html)
|
|
209
218
|
if (metas) html = html.slice(metas[0].length)
|
|
@@ -211,7 +220,7 @@ function readHTML(html: string) {
|
|
|
211
220
|
let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap
|
|
212
221
|
if (wrap = firstTag && wrapMap[firstTag[1].toLowerCase()])
|
|
213
222
|
html = wrap.map(n => "<" + n + ">").join("") + html + wrap.map(n => "</" + n + ">").reverse().join("")
|
|
214
|
-
elt.innerHTML = html
|
|
223
|
+
elt.innerHTML = maybeWrapTrusted(html)
|
|
215
224
|
if (wrap) for (let i = 0; i < wrap.length; i++) elt = elt.querySelector(wrap[i]) || elt
|
|
216
225
|
return elt
|
|
217
226
|
}
|
package/src/domobserver.ts
CHANGED
|
@@ -163,14 +163,17 @@ export class DOMObserver {
|
|
|
163
163
|
return this.queue
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
selectionChanged(sel: DOMSelectionRange) {
|
|
167
|
+
return !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel)
|
|
168
|
+
}
|
|
169
|
+
|
|
166
170
|
flush() {
|
|
167
171
|
let {view} = this
|
|
168
172
|
if (!view.docView || this.flushingSoon > -1) return
|
|
169
173
|
let mutations = this.pendingRecords()
|
|
170
174
|
if (mutations.length) this.queue = []
|
|
171
175
|
|
|
172
|
-
let sel = view.domSelectionRange()
|
|
173
|
-
let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel)
|
|
176
|
+
let sel = view.domSelectionRange(), newSel = this.selectionChanged(sel)
|
|
174
177
|
|
|
175
178
|
let from = -1, to = -1, typeOver = false, added: Node[] = []
|
|
176
179
|
if (view.editable) {
|
package/src/input.ts
CHANGED
|
@@ -112,7 +112,9 @@ editHandlers.keydown = (view: EditorView, _event: Event) => {
|
|
|
112
112
|
// to be part of a confused sequence of composition events fired,
|
|
113
113
|
// and handling them eagerly tends to corrupt the input.
|
|
114
114
|
if (browser.android && browser.chrome && event.keyCode == 13) return
|
|
115
|
-
|
|
115
|
+
|
|
116
|
+
if (view.domObserver.selectionChanged(view.domSelectionRange())) view.domObserver.flush()
|
|
117
|
+
else if (event.keyCode != 229) view.domObserver.forceFlush()
|
|
116
118
|
|
|
117
119
|
// On iOS, if we preventDefault enter key presses, the virtual
|
|
118
120
|
// keyboard gets confused. So the hack here is to set a flag that
|