prosemirror-view 1.39.1 → 1.39.3

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 CHANGED
@@ -1,3 +1,19 @@
1
+ ## 1.39.3 (2025-05-14)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where clicks using different mouse buttons could be grouped into a single double- or triple-click.
6
+
7
+ Only delete the selection when starting a composition when it crosses block boundaries.
8
+
9
+ ## 1.39.2 (2025-04-22)
10
+
11
+ ### Bug fixes
12
+
13
+ Default to using `trustedTypes.defaultPolicy` for clipboard input, when available.
14
+
15
+ Fix an issue where pasting multiple lines from the virtual keyboard on Android would have only the effect of an enter press.
16
+
1
17
  ## 1.39.1 (2025-04-04)
2
18
 
3
19
  ## 1.39.0 (2025-04-04)
package/dist/index.cjs CHANGED
@@ -2813,7 +2813,7 @@ var _policy = null;
2813
2813
  function maybeWrapTrusted(html) {
2814
2814
  var trustedTypes = window.trustedTypes;
2815
2815
  if (!trustedTypes) return html;
2816
- if (!_policy) _policy = trustedTypes.createPolicy("ProseMirrorClipboard", {
2816
+ if (!_policy) _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", {
2817
2817
  createHTML: function createHTML(s) {
2818
2818
  return s;
2819
2819
  }
@@ -2879,7 +2879,8 @@ var InputState = _createClass(function InputState() {
2879
2879
  time: 0,
2880
2880
  x: 0,
2881
2881
  y: 0,
2882
- type: ""
2882
+ type: "",
2883
+ button: 0
2883
2884
  };
2884
2885
  this.lastSelectionOrigin = null;
2885
2886
  this.lastSelectionTime = 0;
@@ -3105,14 +3106,15 @@ handlers.mousedown = function (view, _event) {
3105
3106
  var flushed = forceDOMFlush(view);
3106
3107
  var now = Date.now(),
3107
3108
  type = "singleClick";
3108
- if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) {
3109
+ if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] && view.input.lastClick.button == event.button) {
3109
3110
  if (view.input.lastClick.type == "singleClick") type = "doubleClick";else if (view.input.lastClick.type == "doubleClick") type = "tripleClick";
3110
3111
  }
3111
3112
  view.input.lastClick = {
3112
3113
  time: now,
3113
3114
  x: event.clientX,
3114
3115
  y: event.clientY,
3115
- type: type
3116
+ type: type,
3117
+ button: event.button
3116
3118
  };
3117
3119
  var pos = view.posAtCoords(eventCoords(event));
3118
3120
  if (!pos) return;
@@ -3329,8 +3331,9 @@ function endComposition(view) {
3329
3331
  view.domObserver.forceFlush();
3330
3332
  clearComposition(view);
3331
3333
  if (restarting || view.docView && view.docView.dirty) {
3332
- var sel = selectionFromDOM(view);
3333
- if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel));else if ((view.markCursor || restarting) && !view.state.selection.empty) view.dispatch(view.state.tr.deleteSelection());else view.updateState(view.state);
3334
+ var sel = selectionFromDOM(view),
3335
+ cur = view.state.selection;
3336
+ if (sel && !sel.eq(cur)) view.dispatch(view.state.tr.setSelection(sel));else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent) view.dispatch(view.state.tr.deleteSelection());else view.updateState(view.state);
3334
3337
  return true;
3335
3338
  }
3336
3339
  return false;
@@ -4668,7 +4671,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
4668
4671
  var nextSel;
4669
4672
  if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some(function (n) {
4670
4673
  return n.nodeName == "DIV" || n.nodeName == "P";
4671
- })) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && (nextSel = prosemirrorState.Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && nextSel.head > $from.pos) && view.someProp("handleKeyDown", function (f) {
4674
+ })) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) && (nextSel = prosemirrorState.Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && nextSel.head > $from.pos) && view.someProp("handleKeyDown", function (f) {
4672
4675
  return f(view, keyEvent(13, "Enter"));
4673
4676
  })) {
4674
4677
  view.input.lastIOSEnter = 0;
package/dist/index.js CHANGED
@@ -2984,7 +2984,7 @@ function maybeWrapTrusted(html) {
2984
2984
  // innerHTML, even on a detached document. This wraps the string in
2985
2985
  // a way that makes the browser allow us to use its parser again.
2986
2986
  if (!_policy)
2987
- _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
2987
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
2988
2988
  return _policy.createHTML(html);
2989
2989
  }
2990
2990
  function readHTML(html) {
@@ -3047,7 +3047,7 @@ class InputState {
3047
3047
  this.mouseDown = null;
3048
3048
  this.lastKeyCode = null;
3049
3049
  this.lastKeyCodeTime = 0;
3050
- this.lastClick = { time: 0, x: 0, y: 0, type: "" };
3050
+ this.lastClick = { time: 0, x: 0, y: 0, type: "", button: 0 };
3051
3051
  this.lastSelectionOrigin = null;
3052
3052
  this.lastSelectionTime = 0;
3053
3053
  this.lastIOSEnter = 0;
@@ -3289,13 +3289,14 @@ handlers.mousedown = (view, _event) => {
3289
3289
  view.input.shiftKey = event.shiftKey;
3290
3290
  let flushed = forceDOMFlush(view);
3291
3291
  let now = Date.now(), type = "singleClick";
3292
- if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) {
3292
+ if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] &&
3293
+ view.input.lastClick.button == event.button) {
3293
3294
  if (view.input.lastClick.type == "singleClick")
3294
3295
  type = "doubleClick";
3295
3296
  else if (view.input.lastClick.type == "doubleClick")
3296
3297
  type = "tripleClick";
3297
3298
  }
3298
- view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type };
3299
+ view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type, button: event.button };
3299
3300
  let pos = view.posAtCoords(eventCoords(event));
3300
3301
  if (!pos)
3301
3302
  return;
@@ -3552,10 +3553,10 @@ function endComposition(view, restarting = false) {
3552
3553
  view.domObserver.forceFlush();
3553
3554
  clearComposition(view);
3554
3555
  if (restarting || view.docView && view.docView.dirty) {
3555
- let sel = selectionFromDOM(view);
3556
- if (sel && !sel.eq(view.state.selection))
3556
+ let sel = selectionFromDOM(view), cur = view.state.selection;
3557
+ if (sel && !sel.eq(cur))
3557
3558
  view.dispatch(view.state.tr.setSelection(sel));
3558
- else if ((view.markCursor || restarting) && !view.state.selection.empty)
3559
+ else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent)
3559
3560
  view.dispatch(view.state.tr.deleteSelection());
3560
3561
  else
3561
3562
  view.updateState(view.state);
@@ -5023,6 +5024,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5023
5024
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
5024
5025
  (!inlineChange && $from.pos < parse.doc.content.size &&
5025
5026
  (!$from.sameParent($to) || !$from.parent.inlineContent) &&
5027
+ !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) &&
5026
5028
  (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
5027
5029
  nextSel.head > $from.pos)) &&
5028
5030
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.39.1",
3
+ "version": "1.39.3",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/clipboard.ts CHANGED
@@ -212,7 +212,8 @@ function maybeWrapTrusted(html: string): string {
212
212
  // With the require-trusted-types-for CSP, Chrome will block
213
213
  // innerHTML, even on a detached document. This wraps the string in
214
214
  // a way that makes the browser allow us to use its parser again.
215
- if (!_policy) _policy = trustedTypes.createPolicy("ProseMirrorClipboard", {createHTML: (s: string) => s})
215
+ if (!_policy)
216
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", {createHTML: (s: string) => s})
216
217
  return _policy.createHTML(html)
217
218
  }
218
219
 
package/src/domchange.ts CHANGED
@@ -183,6 +183,7 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
183
183
  (!inlineChange || addedNodes.some(n => n.nodeName == "DIV" || n.nodeName == "P"))) ||
184
184
  (!inlineChange && $from.pos < parse.doc.content.size &&
185
185
  (!$from.sameParent($to) || !$from.parent.inlineContent) &&
186
+ !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) &&
186
187
  (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) &&
187
188
  nextSel.head > $from.pos)) &&
188
189
  view.someProp("handleKeyDown", f => f(view, keyEvent(13, "Enter")))) {
package/src/input.ts CHANGED
@@ -21,7 +21,7 @@ export class InputState {
21
21
  mouseDown: MouseDown | null = null
22
22
  lastKeyCode: number | null = null
23
23
  lastKeyCodeTime = 0
24
- lastClick = {time: 0, x: 0, y: 0, type: ""}
24
+ lastClick = {time: 0, x: 0, y: 0, type: "", button: 0}
25
25
  lastSelectionOrigin: string | null = null
26
26
  lastSelectionTime = 0
27
27
  lastIOSEnter = 0
@@ -278,11 +278,12 @@ handlers.mousedown = (view, _event) => {
278
278
  view.input.shiftKey = event.shiftKey
279
279
  let flushed = forceDOMFlush(view)
280
280
  let now = Date.now(), type = "singleClick"
281
- if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier]) {
281
+ if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] &&
282
+ view.input.lastClick.button == event.button) {
282
283
  if (view.input.lastClick.type == "singleClick") type = "doubleClick"
283
284
  else if (view.input.lastClick.type == "doubleClick") type = "tripleClick"
284
285
  }
285
- view.input.lastClick = {time: now, x: event.clientX, y: event.clientY, type}
286
+ view.input.lastClick = {time: now, x: event.clientX, y: event.clientY, type, button: event.button}
286
287
 
287
288
  let pos = view.posAtCoords(eventCoords(event))
288
289
  if (!pos) return
@@ -544,9 +545,9 @@ export function endComposition(view: EditorView, restarting = false) {
544
545
  view.domObserver.forceFlush()
545
546
  clearComposition(view)
546
547
  if (restarting || view.docView && view.docView.dirty) {
547
- let sel = selectionFromDOM(view)
548
- if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel))
549
- else if ((view.markCursor || restarting) && !view.state.selection.empty) view.dispatch(view.state.tr.deleteSelection())
548
+ let sel = selectionFromDOM(view), cur = view.state.selection
549
+ if (sel && !sel.eq(cur)) view.dispatch(view.state.tr.setSelection(sel))
550
+ else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent) view.dispatch(view.state.tr.deleteSelection())
550
551
  else view.updateState(view.state)
551
552
  return true
552
553
  }