slate-react 0.126.0 → 0.126.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.
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../../../packages/slate-react/src/components/string.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AACjE,OAAO,EAAU,IAAI,EAAQ,OAAO,EAAQ,MAAM,OAAO,CAAA;AAOzD;;GAEG;AAEH,QAAA,MAAM,MAAM,UAAW;IACrB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,OAAO,CAAA;IACf,IAAI,EAAE,IAAI,CAAA;CACX,sBAuCA,CAAA;AAiDD;;GAEG;AAEH,eAAO,MAAM,eAAe,UAAW;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,sBA8BA,CAAA;AAED,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../../../packages/slate-react/src/components/string.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAA;AACjE,OAAO,EAAU,IAAI,EAAQ,OAAO,EAAQ,MAAM,OAAO,CAAA;AAOzD;;GAEG;AAEH,QAAA,MAAM,MAAM,UAAW;IACrB,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,OAAO,CAAA;IACf,IAAI,EAAE,IAAI,CAAA;CACX,sBAuCA,CAAA;AAgED;;GAEG;AAEH,eAAO,MAAM,eAAe,UAAW;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,sBAoCA,CAAA;AAED,eAAe,MAAM,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"android-input-manager.d.ts","sourceRoot":"","sources":["../../../../../packages/slate-react/src/hooks/android-input-manager/android-input-manager.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAgC,KAAK,EAAE,KAAK,EAAc,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAyBvD,MAAM,MAAM,MAAM,GAAG;IAAE,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,CAAA;AAgB5D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,WAAW,CAAA;IAEnB,4BAA4B,EAAE,aAAa,CAAC,MAAM,IAAI,CAAC,CAAA;IACvD,oBAAoB,EAAE,aAAa,CAAC,MAAM,IAAI,CAAC,CAAA;CAChD,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,aAAa,EAAE,MAAM,IAAI,CAAA;IAEzB,eAAe,EAAE,MAAM,OAAO,CAAA;IAC9B,gBAAgB,EAAE,MAAM,OAAO,CAAA;IAC/B,iBAAiB,EAAE,MAAM,OAAO,CAAA;IAChC,UAAU,EAAE,MAAM,OAAO,GAAG,QAAQ,CAAA;IAEpC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/C,oBAAoB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAC7E,sBAAsB,EAAE,CACtB,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,KAC1C,IAAI,CAAA;IACT,oBAAoB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACjD,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAEnE,kBAAkB,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,IAAI,CAAA;IACzD,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB,CAAA;AAED,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,4BAA4B,EAC5B,oBAAoB,GACrB,EAAE,gCAAgC,GAAG,mBAAmB,CA+uBxD"}
1
+ {"version":3,"file":"android-input-manager.d.ts","sourceRoot":"","sources":["../../../../../packages/slate-react/src/hooks/android-input-manager/android-input-manager.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAItC,OAAO,EAAgC,KAAK,EAAE,KAAK,EAAc,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAyBvD,MAAM,MAAM,MAAM,GAAG;IAAE,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,CAAA;AA0B5D,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,WAAW,CAAA;IAEnB,4BAA4B,EAAE,aAAa,CAAC,MAAM,IAAI,CAAC,CAAA;IACvD,oBAAoB,EAAE,aAAa,CAAC,MAAM,IAAI,CAAC,CAAA;CAChD,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,aAAa,EAAE,MAAM,IAAI,CAAA;IAEzB,eAAe,EAAE,MAAM,OAAO,CAAA;IAC9B,gBAAgB,EAAE,MAAM,OAAO,CAAA;IAC/B,iBAAiB,EAAE,MAAM,OAAO,CAAA;IAChC,UAAU,EAAE,MAAM,OAAO,GAAG,QAAQ,CAAA;IAEpC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/C,oBAAoB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAC7E,sBAAsB,EAAE,CACtB,KAAK,EAAE,KAAK,CAAC,gBAAgB,CAAC,cAAc,CAAC,KAC1C,IAAI,CAAA;IACT,oBAAoB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IACjD,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;IAEnE,kBAAkB,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,KAAK,IAAI,CAAA;IACzD,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB,CAAA;AAED,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,4BAA4B,EAC5B,oBAAoB,GACrB,EAAE,gCAAgC,GAAG,mBAAmB,CA21BxD"}
package/dist/index.es.js CHANGED
@@ -3,11 +3,11 @@ import debounce from 'lodash/debounce';
3
3
  import throttle from 'lodash/throttle';
4
4
  import React, { createContext, useContext, useRef, useEffect, useLayoutEffect, useState, memo, forwardRef, useCallback, useReducer, useMemo, Fragment, Component } from 'react';
5
5
  import scrollIntoView from 'scroll-into-view-if-needed';
6
- import { Range, Editor, Node, Path, Transforms, Location, Text as Text$1, Scrubber } from 'slate';
7
- import { DOMEditor, isTrackedMutation, EDITOR_TO_FORCE_RENDER, IS_NODE_MAP_DIRTY, EDITOR_TO_PENDING_DIFFS, applyStringDiff, EDITOR_TO_PENDING_INSERTION_MARKS, isDOMSelection, IS_COMPOSING, EDITOR_TO_PENDING_SELECTION, EDITOR_TO_PENDING_ACTION, EDITOR_TO_USER_MARKS, targetRange, verifyDiffState, EDITOR_TO_PLACEHOLDER_ELEMENT, normalizeStringDiff, mergeStringDiffs, normalizeRange, normalizePoint, CAN_USE_DOM, IS_ANDROID, EDITOR_TO_SCHEDULE_FLUSH, MARK_PLACEHOLDER_SYMBOL, PLACEHOLDER_SYMBOL, IS_WEBKIT, isTextDecorationsEqual, isElementDecorationsEqual, EDITOR_TO_KEY_TO_ELEMENT, NODE_TO_ELEMENT, ELEMENT_TO_NODE, NODE_TO_INDEX, NODE_TO_PARENT, Key, splitDecorationsByChild, IS_READ_ONLY, getActiveElement, getSelection, IS_FOCUSED, getDefaultView, EDITOR_TO_WINDOW, EDITOR_TO_ELEMENT, IS_FIREFOX, containsShadowAware, EDITOR_TO_USER_SELECTION, HAS_BEFORE_INPUT_SUPPORT, isPlainTextOnlyPaste, Hotkeys, IS_CHROME, IS_FIREFOX_LEGACY, IS_IOS, IS_WECHATBROWSER, IS_UC_MOBILE, isDOMNode, TRIPLE_CLICK, isDOMElement, EDITOR_TO_ON_CHANGE, withDOM } from 'slate-dom';
6
+ import { Node, Range, Editor, Path, Transforms, Location, Text as Text$1, Scrubber } from 'slate';
7
+ import { DOMEditor, isTrackedMutation, EDITOR_TO_FORCE_RENDER, IS_NODE_MAP_DIRTY, EDITOR_TO_PENDING_DIFFS, EDITOR_TO_PENDING_SELECTION, applyStringDiff, EDITOR_TO_PENDING_INSERTION_MARKS, isDOMSelection, IS_COMPOSING, EDITOR_TO_PENDING_ACTION, EDITOR_TO_USER_MARKS, targetRange, verifyDiffState, EDITOR_TO_PLACEHOLDER_ELEMENT, normalizeStringDiff, mergeStringDiffs, normalizeRange, normalizePoint, CAN_USE_DOM, IS_ANDROID, EDITOR_TO_SCHEDULE_FLUSH, MARK_PLACEHOLDER_SYMBOL, PLACEHOLDER_SYMBOL, IS_WEBKIT, isTextDecorationsEqual, isElementDecorationsEqual, EDITOR_TO_KEY_TO_ELEMENT, NODE_TO_ELEMENT, ELEMENT_TO_NODE, NODE_TO_INDEX, NODE_TO_PARENT, Key, splitDecorationsByChild, IS_READ_ONLY, getActiveElement, getSelection, IS_FOCUSED, getDefaultView, EDITOR_TO_WINDOW, EDITOR_TO_ELEMENT, IS_FIREFOX, containsShadowAware, EDITOR_TO_USER_SELECTION, HAS_BEFORE_INPUT_SUPPORT, isPlainTextOnlyPaste, Hotkeys, IS_CHROME, IS_FIREFOX_LEGACY, IS_IOS, IS_WECHATBROWSER, IS_UC_MOBILE, isDOMNode, TRIPLE_CLICK, isDOMElement, EDITOR_TO_ON_CHANGE, withDOM } from 'slate-dom';
8
8
  export { NODE_TO_INDEX, NODE_TO_PARENT } from 'slate-dom';
9
- import { ResizeObserver } from '@juggle/resize-observer';
10
9
  import ReactDOM from 'react-dom';
10
+ import { ResizeObserver } from '@juggle/resize-observer';
11
11
 
12
12
  function _objectWithoutPropertiesLoose(source, excluded) {
13
13
  if (source == null) return {};
@@ -104,6 +104,14 @@ function _objectSpread$8(e) { for (var r = 1; r < arguments.length; r++) { var t
104
104
  var RESOLVE_DELAY = 25;
105
105
  // Time with no user interaction before the current user action is considered as done.
106
106
  var FLUSH_DELAY = 200;
107
+ // Time with no composition input after which a composition that never ended is
108
+ // treated as stale. Long enough that pausing mid-word does not cut a live
109
+ // composition short.
110
+ var COMPOSITION_IDLE_TIMEOUT = 5000;
111
+ // How often a deferred flush re-checks whether the composition is still live.
112
+ // Only bounds how quickly the value catches up with a composition that ended
113
+ // without firing `compositionend`; one that ends normally flushes immediately.
114
+ var COMPOSITION_RECHECK_DELAY = 50;
107
115
  // Replace with `const debug = console.log` to debug
108
116
  var debug = function debug() {};
109
117
  // Type guard to check if a value is a DataTransfer
@@ -118,6 +126,8 @@ function createAndroidInputManager(_ref) {
118
126
  var compositionEndTimeoutId = null;
119
127
  var flushTimeoutId = null;
120
128
  var actionTimeoutId = null;
129
+ var lastCompositionActivity = 0;
130
+ var compositionCleared = false;
121
131
  var idCounter = 0;
122
132
  var insertPositionHint = false;
123
133
  var applyPendingSelection = () => {
@@ -151,6 +161,47 @@ function createAndroidInputManager(_ref) {
151
161
  }
152
162
  action.run();
153
163
  };
164
+ // `compositionend` is not fired reliably in every browser, which Slate
165
+ // already works around on keydown. Deferring flushes on a composition that
166
+ // never ends would strand the typed text outside the value, so a composition
167
+ // that has gone quiet, or that has lost focus, no longer holds flushes back.
168
+ var isCompositionLive = () => {
169
+ if (!IS_COMPOSING.get(editor) || compositionCleared) {
170
+ return false;
171
+ }
172
+ try {
173
+ var editable = ReactEditor.toDOMNode(editor, editor);
174
+ var {
175
+ activeElement
176
+ } = ReactEditor.getWindow(editor).document;
177
+ if (activeElement !== editable && !editable.contains(activeElement)) {
178
+ return false;
179
+ }
180
+ } catch (_unused) {
181
+ // Fall back to the idle check below if the editable can't be resolved.
182
+ }
183
+ return Date.now() - lastCompositionActivity < COMPOSITION_IDLE_TIMEOUT;
184
+ };
185
+ // A leaf that Slate models as empty renders as a zero-width string, which on
186
+ // Android is a `<br>` rather than a text node. When the IME composes the
187
+ // first character into such a leaf, the browser creates a text node for the
188
+ // composition. Applying the pending diffs re-renders that leaf as a text
189
+ // leaf, which unmounts the zero-width span and takes the text node the IME is
190
+ // composing in with it, silently cancelling the composition.
191
+ var hasPendingDiffsInEmptyLeaf = () => {
192
+ var _EDITOR_TO_PENDING_DI;
193
+ return !!((_EDITOR_TO_PENDING_DI = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI !== void 0 && _EDITOR_TO_PENDING_DI.some(_ref2 => {
194
+ var {
195
+ path
196
+ } = _ref2;
197
+ try {
198
+ return Node.leaf(editor, path).text.length === 0;
199
+ } catch (_unused2) {
200
+ // The path may no longer resolve if the editor changed underneath us.
201
+ return false;
202
+ }
203
+ }));
204
+ };
154
205
  var flush = () => {
155
206
  if (flushTimeoutId) {
156
207
  clearTimeout(flushTimeoutId);
@@ -160,6 +211,15 @@ function createAndroidInputManager(_ref) {
160
211
  clearTimeout(actionTimeoutId);
161
212
  actionTimeoutId = null;
162
213
  }
214
+ // Defer flushing until the composition ends, so that the re-render that
215
+ // would replace the composing text node cannot happen mid-composition.
216
+ // Composing into a leaf that already has text is unaffected: applying the
217
+ // diff there only updates `textContent`, so the value still updates on
218
+ // every `compositionupdate`.
219
+ if (isCompositionLive() && hasPendingDiffsInEmptyLeaf()) {
220
+ flushTimeoutId = setTimeout(flush, COMPOSITION_RECHECK_DELAY);
221
+ return;
222
+ }
163
223
  if (!hasPendingDiffs() && !hasPendingAction()) {
164
224
  applyPendingSelection();
165
225
  return;
@@ -178,8 +238,8 @@ function createAndroidInputManager(_ref) {
178
238
  debug('flush', EDITOR_TO_PENDING_ACTION.get(editor), EDITOR_TO_PENDING_DIFFS.get(editor));
179
239
  var scheduleSelectionChange = hasPendingDiffs();
180
240
  var diff;
181
- while (diff = (_EDITOR_TO_PENDING_DI = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI === void 0 ? void 0 : _EDITOR_TO_PENDING_DI[0]) {
182
- var _EDITOR_TO_PENDING_DI, _EDITOR_TO_PENDING_DI2;
241
+ while (diff = (_EDITOR_TO_PENDING_DI2 = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI2 === void 0 ? void 0 : _EDITOR_TO_PENDING_DI2[0]) {
242
+ var _EDITOR_TO_PENDING_DI2, _EDITOR_TO_PENDING_DI3;
183
243
  var pendingMarks = EDITOR_TO_PENDING_INSERTION_MARKS.get(editor);
184
244
  if (pendingMarks !== undefined) {
185
245
  EDITOR_TO_PENDING_INSERTION_MARKS.delete(editor);
@@ -199,10 +259,10 @@ function createAndroidInputManager(_ref) {
199
259
  }
200
260
  // Remove diff only after we have applied it to account for it when transforming
201
261
  // pending ranges.
202
- EDITOR_TO_PENDING_DIFFS.set(editor, (_EDITOR_TO_PENDING_DI2 = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI2 === void 0 ? void 0 : _EDITOR_TO_PENDING_DI2.filter(_ref2 => {
262
+ EDITOR_TO_PENDING_DIFFS.set(editor, (_EDITOR_TO_PENDING_DI3 = EDITOR_TO_PENDING_DIFFS.get(editor)) === null || _EDITOR_TO_PENDING_DI3 === void 0 ? void 0 : _EDITOR_TO_PENDING_DI3.filter(_ref3 => {
203
263
  var {
204
264
  id
205
- } = _ref2;
265
+ } = _ref3;
206
266
  return id !== diff.id;
207
267
  }));
208
268
  if (!verifyDiffState(editor, diff)) {
@@ -246,13 +306,35 @@ function createAndroidInputManager(_ref) {
246
306
  if (compositionEndTimeoutId) {
247
307
  clearTimeout(compositionEndTimeoutId);
248
308
  }
309
+ // Diffs deferred by `flush` have to be applied synchronously here. IMEs
310
+ // that compose one syllable at a time (Hangul, kana) start the next
311
+ // composition in the same tick as this event, so an asynchronous render
312
+ // would replace the text node that composition has already started in.
313
+ if (hasPendingDiffsInEmptyLeaf() && !flushing) {
314
+ ReactDOM.flushSync(() => {
315
+ IS_COMPOSING.set(editor, false);
316
+ flush();
317
+ });
318
+ updatePlaceholderVisibility();
319
+ return;
320
+ }
249
321
  compositionEndTimeoutId = setTimeout(() => {
250
322
  IS_COMPOSING.set(editor, false);
251
323
  flush();
324
+ if (compositionCleared) {
325
+ var _EDITOR_TO_FORCE_REND;
326
+ // A cancelled composition can take the empty leaf's text node with
327
+ // it. A forced render lets RestoreDOM put the leaf's DOM back, so the
328
+ // next composition starts from a clean state instead of a bare <br>.
329
+ (_EDITOR_TO_FORCE_REND = EDITOR_TO_FORCE_RENDER.get(editor)) === null || _EDITOR_TO_FORCE_REND === void 0 || _EDITOR_TO_FORCE_REND();
330
+ }
331
+ updatePlaceholderVisibility();
252
332
  }, RESOLVE_DELAY);
253
333
  };
254
334
  var handleCompositionStart = _event => {
255
335
  IS_COMPOSING.set(editor, true);
336
+ lastCompositionActivity = Date.now();
337
+ compositionCleared = false;
256
338
  if (compositionEndTimeoutId) {
257
339
  clearTimeout(compositionEndTimeoutId);
258
340
  compositionEndTimeoutId = null;
@@ -271,8 +353,8 @@ function createAndroidInputManager(_ref) {
271
353
  placeholderElement.style.removeProperty('display');
272
354
  };
273
355
  var storeDiff = (path, diff) => {
274
- var _EDITOR_TO_PENDING_DI3;
275
- var pendingDiffs = (_EDITOR_TO_PENDING_DI3 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI3 !== void 0 ? _EDITOR_TO_PENDING_DI3 : [];
356
+ var _EDITOR_TO_PENDING_DI4;
357
+ var pendingDiffs = (_EDITOR_TO_PENDING_DI4 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI4 !== void 0 ? _EDITOR_TO_PENDING_DI4 : [];
276
358
  EDITOR_TO_PENDING_DIFFS.set(editor, pendingDiffs);
277
359
  var target = Node.leaf(editor, path);
278
360
  var idx = pendingDiffs.findIndex(change => Path.equals(change.path, path));
@@ -330,6 +412,36 @@ function createAndroidInputManager(_ref) {
330
412
  var {
331
413
  inputType: type
332
414
  } = event;
415
+ if (type === 'insertCompositionText' || type === 'deleteCompositionText') {
416
+ lastCompositionActivity = Date.now();
417
+ if (event.data) {
418
+ compositionCleared = false;
419
+ } else {
420
+ // The IME threw away what it was composing. The deferred text never
421
+ // reached the value, so the value is already in the desired state -
422
+ // drop the deferral instead of applying and re-deleting it, which
423
+ // would churn the DOM mid-composition and can make Android close the
424
+ // keyboard.
425
+ compositionCleared = true;
426
+ var deferredDiffs = EDITOR_TO_PENDING_DIFFS.get(editor);
427
+ if (deferredDiffs !== null && deferredDiffs !== void 0 && deferredDiffs.length) {
428
+ var allInEmptyLeaves = deferredDiffs.every(_ref4 => {
429
+ var {
430
+ path
431
+ } = _ref4;
432
+ try {
433
+ return Node.leaf(editor, path).text.length === 0;
434
+ } catch (_unused3) {
435
+ return false;
436
+ }
437
+ });
438
+ if (allInEmptyLeaves) {
439
+ EDITOR_TO_PENDING_DIFFS.set(editor, []);
440
+ EDITOR_TO_PENDING_SELECTION.delete(editor);
441
+ }
442
+ }
443
+ }
444
+ }
333
445
  var targetRange = null;
334
446
  var data = event.dataTransfer || event.data || undefined;
335
447
  if (insertPositionHint !== false && type !== 'insertText' && type !== 'insertCompositionText') {
@@ -662,8 +774,8 @@ function createAndroidInputManager(_ref) {
662
774
  return !!EDITOR_TO_PENDING_ACTION.get(editor);
663
775
  };
664
776
  var hasPendingDiffs = () => {
665
- var _EDITOR_TO_PENDING_DI4;
666
- return !!((_EDITOR_TO_PENDING_DI4 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI4 !== void 0 && _EDITOR_TO_PENDING_DI4.length);
777
+ var _EDITOR_TO_PENDING_DI5;
778
+ return !!((_EDITOR_TO_PENDING_DI5 = EDITOR_TO_PENDING_DIFFS.get(editor)) !== null && _EDITOR_TO_PENDING_DI5 !== void 0 && _EDITOR_TO_PENDING_DI5.length);
667
779
  };
668
780
  var hasPendingChanges = () => {
669
781
  return hasPendingAction() || hasPendingDiffs();
@@ -718,10 +830,10 @@ function createAndroidInputManager(_ref) {
718
830
  return;
719
831
  }
720
832
  if (mutations.some(mutation => isTrackedMutation(editor, mutation, mutations))) {
721
- var _EDITOR_TO_FORCE_REND;
833
+ var _EDITOR_TO_FORCE_REND2;
722
834
  // Cause a re-render to restore the dom state if we encounter tracked mutations without
723
835
  // a corresponding pending action.
724
- (_EDITOR_TO_FORCE_REND = EDITOR_TO_FORCE_RENDER.get(editor)) === null || _EDITOR_TO_FORCE_REND === void 0 || _EDITOR_TO_FORCE_REND();
836
+ (_EDITOR_TO_FORCE_REND2 = EDITOR_TO_FORCE_RENDER.get(editor)) === null || _EDITOR_TO_FORCE_REND2 === void 0 || _EDITOR_TO_FORCE_REND2();
725
837
  }
726
838
  };
727
839
  return {
@@ -862,6 +974,7 @@ var TextString = props => {
862
974
  text,
863
975
  isTrailing = false
864
976
  } = props;
977
+ var editor = useSlateStatic();
865
978
  var ref = useRef(null);
866
979
  var getTextContent = () => {
867
980
  return "".concat(text !== null && text !== void 0 ? text : '').concat(isTrailing ? '\n' : '');
@@ -879,6 +992,18 @@ var TextString = props => {
879
992
  // null coalescing text to make sure we're not outputing "null" as a string in the extreme case it is nullish at runtime
880
993
  var textWithTrailing = getTextContent();
881
994
  if (ref.current && ref.current.textContent !== textWithTrailing) {
995
+ // On Android the DOM intentionally runs ahead of the value while the IME
996
+ // composes, since input is buffered as pending diffs. Writing
997
+ // `textContent` here would replace the text node the composition lives in
998
+ // and cancel it; the pending diffs reconcile this span when the
999
+ // composition ends.
1000
+ if (IS_ANDROID && IS_COMPOSING.get(editor)) {
1001
+ var _ReactEditor$getWindo;
1002
+ var composingNode = (_ReactEditor$getWindo = ReactEditor.getWindow(editor).getSelection()) === null || _ReactEditor$getWindo === void 0 ? void 0 : _ReactEditor$getWindo.anchorNode;
1003
+ if (composingNode && ref.current.contains(composingNode)) {
1004
+ return;
1005
+ }
1006
+ }
882
1007
  ref.current.textContent = textWithTrailing;
883
1008
  }
884
1009
  // intentionally not specifying dependencies, so that this effect runs on every render
@@ -920,7 +1045,13 @@ var ZeroWidthString = props => {
920
1045
  // be because accepting an IME suggestion when at the start of a block (no
921
1046
  // preceding \uFEFF) removes one or more DOM elements that `toSlateRange`
922
1047
  // depends on. (https://github.com/ianstormtaylor/slate/issues/5703)
923
- return /*#__PURE__*/React.createElement("span", _objectSpread$6({}, attributes), !IS_ANDROID || !isLineBreak ? '\uFEFF' : null, isLineBreak ? /*#__PURE__*/React.createElement("br", null) : null);
1048
+ // A leaf with no text node at all forces the IME to create one when the
1049
+ // first character is composed there, and no re-render can then touch the
1050
+ // leaf without cancelling the composition. Rendering the zero-width space on
1051
+ // Android too gives the composition a React-owned text node to live in; the
1052
+ // wrapper keeps its data-slate-zero-width attributes, so selection mapping
1053
+ // is unchanged.
1054
+ return /*#__PURE__*/React.createElement("span", _objectSpread$6({}, attributes), '\uFEFF', isLineBreak ? /*#__PURE__*/React.createElement("br", null) : null);
924
1055
  };
925
1056
 
926
1057
  function ownKeys$5(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }