prosemirror-view 1.37.0 → 1.37.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 CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.37.1 (2024-12-11)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where `display: content` elements could break `posAtCoords`.
6
+
7
+ Work around an issue with Chrome reporting the selection incorrectly during composition.
8
+
1
9
  ## 1.37.0 (2024-11-23)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -389,10 +389,10 @@ function posFromCaret(view, node, offset, coords) {
389
389
  var outsideBlock = -1;
390
390
  for (var cur = node, sawBlock = false;;) {
391
391
  if (cur == view.dom) break;
392
- var desc = view.docView.nearestDesc(cur, true);
392
+ var desc = view.docView.nearestDesc(cur, true),
393
+ rect = void 0;
393
394
  if (!desc) return null;
394
- if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
395
- var rect = desc.dom.getBoundingClientRect();
395
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
396
396
  if (desc.node.isBlock && desc.parent) {
397
397
  if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore;else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) outsideBlock = desc.posAfter;
398
398
  sawBlock = true;
@@ -2874,7 +2874,7 @@ var InputState = _createClass(function InputState() {
2874
2874
  this.lastIOSEnterFallbackTimeout = -1;
2875
2875
  this.lastFocus = 0;
2876
2876
  this.lastTouch = 0;
2877
- this.lastAndroidDelete = 0;
2877
+ this.lastChromeDelete = 0;
2878
2878
  this.composing = false;
2879
2879
  this.compositionNode = null;
2880
2880
  this.composingTimeout = -1;
@@ -4661,7 +4661,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
4661
4661
  if (android && chrome) view.domObserver.suppressSelectionUpdates();
4662
4662
  return;
4663
4663
  }
4664
- if (chrome && android && change.endB == change.start) view.input.lastAndroidDelete = Date.now();
4664
+ if (chrome && change.endB == change.start) view.input.lastChromeDelete = Date.now();
4665
4665
  if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse.sel && parse.sel.anchor == parse.sel.head && parse.sel.head == change.endA) {
4666
4666
  change.endB -= 2;
4667
4667
  $to = parse.doc.resolveNoCache(change.endB - parse.from);
@@ -4698,7 +4698,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
4698
4698
  if (!tr) tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
4699
4699
  if (parse.sel) {
4700
4700
  var _sel3 = resolveSelection(view, tr.doc, parse.sel);
4701
- if (_sel3 && !(chrome && android && view.composing && _sel3.empty && (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) && (_sel3.head == chFrom || _sel3.head == tr.mapping.map(chTo) - 1) || ie && _sel3.empty && _sel3.head == chFrom)) tr.setSelection(_sel3);
4701
+ if (_sel3 && !(chrome && view.composing && _sel3.empty && (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) && (_sel3.head == chFrom || _sel3.head == tr.mapping.map(chTo) - 1) || ie && _sel3.empty && _sel3.head == chFrom)) tr.setSelection(_sel3);
4702
4702
  }
4703
4703
  if (storedMarks) tr.ensureMarks(storedMarks);
4704
4704
  if (compositionID) tr.setMeta("composition", compositionID);
package/dist/index.js CHANGED
@@ -396,11 +396,12 @@ function posFromCaret(view, node, offset, coords) {
396
396
  for (let cur = node, sawBlock = false;;) {
397
397
  if (cur == view.dom)
398
398
  break;
399
- let desc = view.docView.nearestDesc(cur, true);
399
+ let desc = view.docView.nearestDesc(cur, true), rect;
400
400
  if (!desc)
401
401
  return null;
402
- if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
403
- let rect = desc.dom.getBoundingClientRect();
402
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
403
+ // Ignore elements with zero-size bounding rectangles
404
+ ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) {
404
405
  if (desc.node.isBlock && desc.parent) {
405
406
  // Only apply the horizontal test to the innermost block. Vertical for any parent.
406
407
  if (!sawBlock && rect.left > coords.left || rect.top > coords.top)
@@ -3042,7 +3043,7 @@ class InputState {
3042
3043
  this.lastIOSEnterFallbackTimeout = -1;
3043
3044
  this.lastFocus = 0;
3044
3045
  this.lastTouch = 0;
3045
- this.lastAndroidDelete = 0;
3046
+ this.lastChromeDelete = 0;
3046
3047
  this.composing = false;
3047
3048
  this.compositionNode = null;
3048
3049
  this.composingTimeout = -1;
@@ -5020,11 +5021,11 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5020
5021
  view.domObserver.suppressSelectionUpdates(); // #820
5021
5022
  return;
5022
5023
  }
5023
- // Chrome Android will occasionally, during composition, delete the
5024
+ // Chrome will occasionally, during composition, delete the
5024
5025
  // entire composition and then immediately insert it again. This is
5025
5026
  // used to detect that situation.
5026
- if (chrome && android && change.endB == change.start)
5027
- view.input.lastAndroidDelete = Date.now();
5027
+ if (chrome && change.endB == change.start)
5028
+ view.input.lastChromeDelete = Date.now();
5028
5029
  // This tries to detect Android virtual keyboard
5029
5030
  // enter-and-pick-suggestion action. That sometimes (see issue
5030
5031
  // #1059) first fires a DOM mutation, before moving the selection to
@@ -5075,13 +5076,13 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5075
5076
  tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from));
5076
5077
  if (parse.sel) {
5077
5078
  let sel = resolveSelection(view, tr.doc, parse.sel);
5078
- // Chrome Android will sometimes, during composition, report the
5079
+ // Chrome will sometimes, during composition, report the
5079
5080
  // selection in the wrong place. If it looks like that is
5080
5081
  // happening, don't update the selection.
5081
5082
  // Edge just doesn't move the cursor forward when you start typing
5082
5083
  // in an empty block or between br nodes.
5083
- if (sel && !(chrome && android && view.composing && sel.empty &&
5084
- (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) &&
5084
+ if (sel && !(chrome && view.composing && sel.empty &&
5085
+ (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) &&
5085
5086
  (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) ||
5086
5087
  ie && sel.empty && sel.head == chFrom))
5087
5088
  tr.setSelection(sel);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.37.0",
3
+ "version": "1.37.1",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/domchange.ts CHANGED
@@ -196,11 +196,11 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
196
196
  return
197
197
  }
198
198
 
199
- // Chrome Android will occasionally, during composition, delete the
199
+ // Chrome will occasionally, during composition, delete the
200
200
  // entire composition and then immediately insert it again. This is
201
201
  // used to detect that situation.
202
- if (browser.chrome && browser.android && change.endB == change.start)
203
- view.input.lastAndroidDelete = Date.now()
202
+ if (browser.chrome && change.endB == change.start)
203
+ view.input.lastChromeDelete = Date.now()
204
204
 
205
205
  // This tries to detect Android virtual keyboard
206
206
  // enter-and-pick-suggestion action. That sometimes (see issue
@@ -252,13 +252,13 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
252
252
  tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from))
253
253
  if (parse.sel) {
254
254
  let sel = resolveSelection(view, tr.doc, parse.sel)
255
- // Chrome Android will sometimes, during composition, report the
255
+ // Chrome will sometimes, during composition, report the
256
256
  // selection in the wrong place. If it looks like that is
257
257
  // happening, don't update the selection.
258
258
  // Edge just doesn't move the cursor forward when you start typing
259
259
  // in an empty block or between br nodes.
260
- if (sel && !(browser.chrome && browser.android && view.composing && sel.empty &&
261
- (change.start != change.endB || view.input.lastAndroidDelete < Date.now() - 100) &&
260
+ if (sel && !(browser.chrome && view.composing && sel.empty &&
261
+ (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) &&
262
262
  (sel.head == chFrom || sel.head == tr.mapping.map(chTo) - 1) ||
263
263
  browser.ie && sel.empty && sel.head == chFrom))
264
264
  tr.setSelection(sel)
package/src/domcoords.ts CHANGED
@@ -225,10 +225,11 @@ function posFromCaret(view: EditorView, node: Node, offset: number, coords: {top
225
225
  let outsideBlock = -1
226
226
  for (let cur = node, sawBlock = false;;) {
227
227
  if (cur == view.dom) break
228
- let desc = view.docView.nearestDesc(cur, true)
228
+ let desc = view.docView.nearestDesc(cur, true), rect
229
229
  if (!desc) return null
230
- if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM)) {
231
- let rect = (desc.dom as HTMLElement).getBoundingClientRect()
230
+ if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) &&
231
+ // Ignore elements with zero-size bounding rectangles
232
+ ((rect = (desc.dom as HTMLElement).getBoundingClientRect()).width || rect.height)) {
232
233
  if (desc.node.isBlock && desc.parent) {
233
234
  // Only apply the horizontal test to the innermost block. Vertical for any parent.
234
235
  if (!sawBlock && rect.left > coords.left || rect.top > coords.top) outsideBlock = desc.posBefore
package/src/input.ts CHANGED
@@ -28,7 +28,7 @@ export class InputState {
28
28
  lastIOSEnterFallbackTimeout = -1
29
29
  lastFocus = 0
30
30
  lastTouch = 0
31
- lastAndroidDelete = 0
31
+ lastChromeDelete = 0
32
32
  composing = false
33
33
  compositionNode: Text | null = null
34
34
  composingTimeout = -1