prosemirror-view 1.33.10 → 1.34.0

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,17 @@
1
+ ## 1.34.0 (2024-08-23)
2
+
3
+ ### New features
4
+
5
+ The `DecorationGroup` interface now has a `forEachSet` method to iterate though the contained decoration sets.
6
+
7
+ ## 1.33.11 (2024-08-19)
8
+
9
+ ### Bug fixes
10
+
11
+ Delete the selection on composition start when on a mark boundary to force Chrome to apply the correct style to the composition.
12
+
13
+ When the browser starts a composition and the selection spans across blocks, start by clearing it to make sure the composed text node lands in a valid position.
14
+
1
15
  ## 1.33.10 (2024-08-13)
2
16
 
3
17
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -2219,13 +2219,7 @@ function selectCursorWrapper(view) {
2219
2219
  var node = view.cursorWrapper.dom,
2220
2220
  img = node.nodeName == "IMG";
2221
2221
  if (img) range.setStart(node.parentNode, domIndex(node) + 1);else range.setStart(node, 0);
2222
- var sel = view.state.selection;
2223
- if (sel.empty) {
2224
- range.collapse(true);
2225
- } else {
2226
- var end = view.domAtPos(sel.to);
2227
- range.setEnd(end.node, end.offset);
2228
- }
2222
+ range.collapse(true);
2229
2223
  domSel.removeAllRanges();
2230
2224
  domSel.addRange(range);
2231
2225
  if (!img && !view.state.selection.visible && ie && ie_version <= 11) {
@@ -3205,7 +3199,7 @@ editHandlers.compositionstart = editHandlers.compositionupdate = function (view)
3205
3199
  endComposition(view, true);
3206
3200
  view.markCursor = null;
3207
3201
  } else {
3208
- endComposition(view);
3202
+ endComposition(view, !state.selection.empty);
3209
3203
  if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) {
3210
3204
  var sel = view.domSelectionRange();
3211
3205
  for (var node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0;) {
@@ -3276,13 +3270,13 @@ function timestampFromCustomEvent() {
3276
3270
  return event.timeStamp;
3277
3271
  }
3278
3272
  function endComposition(view) {
3279
- var forceUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
3273
+ var restarting = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
3280
3274
  if (android && view.domObserver.flushingSoon >= 0) return;
3281
3275
  view.domObserver.forceFlush();
3282
3276
  clearComposition(view);
3283
- if (forceUpdate || view.docView && view.docView.dirty) {
3277
+ if (restarting || view.docView && view.docView.dirty) {
3284
3278
  var sel = selectionFromDOM(view);
3285
- if (sel && !sel.eq(view.state.selection)) view.dispatch(view.state.tr.setSelection(sel));else view.updateState(view.state);
3279
+ 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);
3286
3280
  return true;
3287
3281
  }
3288
3282
  return false;
@@ -3822,6 +3816,11 @@ var DecorationSet = function () {
3822
3816
  }
3823
3817
  return result;
3824
3818
  }
3819
+ }, {
3820
+ key: "forEachSet",
3821
+ value: function forEachSet(f) {
3822
+ f(this);
3823
+ }
3825
3824
  }], [{
3826
3825
  key: "create",
3827
3826
  value: function create(doc, decorations) {
@@ -3885,6 +3884,11 @@ var DecorationGroup = function () {
3885
3884
  }
3886
3885
  return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none;
3887
3886
  }
3887
+ }, {
3888
+ key: "forEachSet",
3889
+ value: function forEachSet(f) {
3890
+ for (var i = 0; i < this.members.length; i++) this.members[i].forEachSet(f);
3891
+ }
3888
3892
  }], [{
3889
3893
  key: "from",
3890
3894
  value: function from(members) {
package/dist/index.d.cts CHANGED
@@ -160,6 +160,10 @@ interface DecorationSource {
160
160
  Extract a DecorationSource containing decorations for the given child node at the given offset.
161
161
  */
162
162
  forChild(offset: number, child: Node): DecorationSource;
163
+ /**
164
+ Call the given function for each decoration set in the group.
165
+ */
166
+ forEachSet(f: (set: DecorationSet) => void): void;
163
167
  }
164
168
  /**
165
169
  A collection of [decorations](https://prosemirror.net/docs/ref/#view.Decoration), organized in such
@@ -215,6 +219,7 @@ declare class DecorationSet implements DecorationSource {
215
219
  The empty set of decorations.
216
220
  */
217
221
  static empty: DecorationSet;
222
+ forEachSet(f: (set: DecorationSet) => void): void;
218
223
  }
219
224
  declare class DecorationGroup implements DecorationSource {
220
225
  readonly members: readonly DecorationSet[];
@@ -224,6 +229,7 @@ declare class DecorationGroup implements DecorationSource {
224
229
  eq(other: DecorationGroup): boolean;
225
230
  locals(node: Node): readonly any[];
226
231
  static from(members: readonly DecorationSource[]): DecorationSource;
232
+ forEachSet(f: (set: DecorationSet) => void): void;
227
233
  }
228
234
 
229
235
  declare global {
package/dist/index.d.ts CHANGED
@@ -160,6 +160,10 @@ interface DecorationSource {
160
160
  Extract a DecorationSource containing decorations for the given child node at the given offset.
161
161
  */
162
162
  forChild(offset: number, child: Node): DecorationSource;
163
+ /**
164
+ Call the given function for each decoration set in the group.
165
+ */
166
+ forEachSet(f: (set: DecorationSet) => void): void;
163
167
  }
164
168
  /**
165
169
  A collection of [decorations](https://prosemirror.net/docs/ref/#view.Decoration), organized in such
@@ -215,6 +219,7 @@ declare class DecorationSet implements DecorationSource {
215
219
  The empty set of decorations.
216
220
  */
217
221
  static empty: DecorationSet;
222
+ forEachSet(f: (set: DecorationSet) => void): void;
218
223
  }
219
224
  declare class DecorationGroup implements DecorationSource {
220
225
  readonly members: readonly DecorationSet[];
@@ -224,6 +229,7 @@ declare class DecorationGroup implements DecorationSource {
224
229
  eq(other: DecorationGroup): boolean;
225
230
  locals(node: Node): readonly any[];
226
231
  static from(members: readonly DecorationSource[]): DecorationSource;
232
+ forEachSet(f: (set: DecorationSet) => void): void;
227
233
  }
228
234
 
229
235
  declare global {
package/dist/index.js CHANGED
@@ -2290,14 +2290,7 @@ function selectCursorWrapper(view) {
2290
2290
  range.setStart(node.parentNode, domIndex(node) + 1);
2291
2291
  else
2292
2292
  range.setStart(node, 0);
2293
- let sel = view.state.selection;
2294
- if (sel.empty) {
2295
- range.collapse(true);
2296
- }
2297
- else {
2298
- let end = view.domAtPos(sel.to);
2299
- range.setEnd(end.node, end.offset);
2300
- }
2293
+ range.collapse(true);
2301
2294
  domSel.removeAllRanges();
2302
2295
  domSel.addRange(range);
2303
2296
  // Kludge to kill 'control selection' in IE11 when selecting an
@@ -3419,7 +3412,7 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
3419
3412
  view.markCursor = null;
3420
3413
  }
3421
3414
  else {
3422
- endComposition(view);
3415
+ endComposition(view, !state.selection.empty);
3423
3416
  // In firefox, if the cursor is after but outside a marked node,
3424
3417
  // the inserted text won't inherit the marks. So this moves it
3425
3418
  // inside if necessary.
@@ -3500,15 +3493,17 @@ function timestampFromCustomEvent() {
3500
3493
  /**
3501
3494
  @internal
3502
3495
  */
3503
- function endComposition(view, forceUpdate = false) {
3496
+ function endComposition(view, restarting = false) {
3504
3497
  if (android && view.domObserver.flushingSoon >= 0)
3505
3498
  return;
3506
3499
  view.domObserver.forceFlush();
3507
3500
  clearComposition(view);
3508
- if (forceUpdate || view.docView && view.docView.dirty) {
3501
+ if (restarting || view.docView && view.docView.dirty) {
3509
3502
  let sel = selectionFromDOM(view);
3510
3503
  if (sel && !sel.eq(view.state.selection))
3511
3504
  view.dispatch(view.state.tr.setSelection(sel));
3505
+ else if ((view.markCursor || restarting) && !view.state.selection.empty)
3506
+ view.dispatch(view.state.tr.deleteSelection());
3512
3507
  else
3513
3508
  view.updateState(view.state);
3514
3509
  return true;
@@ -4165,6 +4160,7 @@ class DecorationSet {
4165
4160
  }
4166
4161
  return result;
4167
4162
  }
4163
+ forEachSet(f) { f(this); }
4168
4164
  }
4169
4165
  /**
4170
4166
  The empty set of decorations.
@@ -4240,6 +4236,10 @@ class DecorationGroup {
4240
4236
  members.reduce((r, m) => r.concat(m instanceof DecorationSet ? m : m.members), []));
4241
4237
  }
4242
4238
  }
4239
+ forEachSet(f) {
4240
+ for (let i = 0; i < this.members.length; i++)
4241
+ this.members[i].forEachSet(f);
4242
+ }
4243
4243
  }
4244
4244
  function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {
4245
4245
  let children = oldChildren.slice();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.33.10",
3
+ "version": "1.34.0",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/decoration.ts CHANGED
@@ -262,6 +262,8 @@ export interface DecorationSource {
262
262
  forChild(offset: number, child: Node): DecorationSource
263
263
  /// @internal
264
264
  eq(other: DecorationSource): boolean
265
+ /// Call the given function for each decoration set in the group.
266
+ forEachSet(f: (set: DecorationSet) => void): void
265
267
  }
266
268
 
267
269
  /// A collection of [decorations](#view.Decoration), organized in such
@@ -475,6 +477,8 @@ export class DecorationSet implements DecorationSource {
475
477
 
476
478
  /// @internal
477
479
  static removeOverlap = removeOverlap
480
+
481
+ forEachSet(f: (set: DecorationSet) => void) { f(this) }
478
482
  }
479
483
 
480
484
  const empty = DecorationSet.empty
@@ -542,6 +546,10 @@ class DecorationGroup implements DecorationSource {
542
546
  [] as DecorationSet[]))
543
547
  }
544
548
  }
549
+
550
+ forEachSet(f: (set: DecorationSet) => void) {
551
+ for (let i = 0; i < this.members.length; i++) this.members[i].forEachSet(f)
552
+ }
545
553
  }
546
554
 
547
555
  function mapChildren(
package/src/input.ts CHANGED
@@ -463,7 +463,7 @@ editHandlers.compositionstart = editHandlers.compositionupdate = view => {
463
463
  endComposition(view, true)
464
464
  view.markCursor = null
465
465
  } else {
466
- endComposition(view)
466
+ endComposition(view, !state.selection.empty)
467
467
  // In firefox, if the cursor is after but outside a marked node,
468
468
  // the inserted text won't inherit the marks. So this moves it
469
469
  // inside if necessary.
@@ -539,13 +539,14 @@ function timestampFromCustomEvent() {
539
539
  }
540
540
 
541
541
  /// @internal
542
- export function endComposition(view: EditorView, forceUpdate = false) {
542
+ export function endComposition(view: EditorView, restarting = false) {
543
543
  if (browser.android && view.domObserver.flushingSoon >= 0) return
544
544
  view.domObserver.forceFlush()
545
545
  clearComposition(view)
546
- if (forceUpdate || view.docView && view.docView.dirty) {
546
+ if (restarting || view.docView && view.docView.dirty) {
547
547
  let sel = selectionFromDOM(view)
548
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())
549
550
  else view.updateState(view.state)
550
551
  return true
551
552
  }
package/src/selection.ts CHANGED
@@ -140,13 +140,7 @@ function selectCursorWrapper(view: EditorView) {
140
140
  let node = view.cursorWrapper!.dom, img = node.nodeName == "IMG"
141
141
  if (img) range.setStart(node.parentNode!, domIndex(node) + 1)
142
142
  else range.setStart(node, 0)
143
- let sel = view.state.selection
144
- if (sel.empty) {
145
- range.collapse(true)
146
- } else {
147
- let end = view.domAtPos(sel.to)
148
- range.setEnd(end.node, end.offset)
149
- }
143
+ range.collapse(true)
150
144
  domSel.removeAllRanges()
151
145
  domSel.addRange(range)
152
146
  // Kludge to kill 'control selection' in IE11 when selecting an