edytor 2.0.0 → 3.0.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.
Files changed (222) hide show
  1. package/README.md +19 -4
  2. package/dist/block/block.svelte.js +2 -4
  3. package/dist/clipboard/htmlFlow.d.ts +20 -7
  4. package/dist/clipboard/htmlFlow.js +23 -15
  5. package/dist/clipboard/serializeClipboardFragment.d.ts +37 -4
  6. package/dist/clipboard/serializeClipboardFragment.js +6 -4
  7. package/dist/clipboard/textBlocks.d.ts +8 -0
  8. package/dist/clipboard/textBlocks.js +6 -2
  9. package/dist/cloudflare/room/admission.js +3 -3
  10. package/dist/cloudflare/room/context.d.ts +1 -1
  11. package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
  12. package/dist/cloudflare/routeDocumentSocket.js +53 -0
  13. package/dist/collaboration/comments/client.d.ts +1 -1
  14. package/dist/collaboration/comments/client.js +1 -1
  15. package/dist/collaboration/remoteSelection.js +3 -3
  16. package/dist/components/Edytor.svelte +2 -10
  17. package/dist/components/Edytor.svelte.d.ts +1 -3
  18. package/dist/crdt/admission.d.ts +5 -10
  19. package/dist/crdt/admission.js +5 -11
  20. package/dist/crdt/doc/funnel.d.ts +7 -6
  21. package/dist/crdt/doc/funnel.js +10 -9
  22. package/dist/crdt/doc/gate.d.ts +0 -17
  23. package/dist/crdt/doc/gate.js +2 -41
  24. package/dist/crdt/doc/history.js +2 -2
  25. package/dist/crdt/document.d.ts +5 -14
  26. package/dist/crdt/document.js +5 -19
  27. package/dist/crdt/edytor-doc.d.ts +4 -4
  28. package/dist/crdt/edytor-doc.js +3 -7
  29. package/dist/crdt/index.d.ts +3 -3
  30. package/dist/crdt/index.js +2 -2
  31. package/dist/crdt/protocol.d.ts +2 -2
  32. package/dist/crdt/protocol.js +2 -2
  33. package/dist/crdt/providers/index.d.ts +1 -1
  34. package/dist/crdt/providers/room.d.ts +10 -9
  35. package/dist/crdt/providers/room.js +13 -10
  36. package/dist/crdt/providers/websocket.d.ts +1 -1
  37. package/dist/crdt/providers/websocket.js +28 -29
  38. package/dist/crdt/semantics.js +3 -1
  39. package/dist/dnd/autoScroll.d.ts +15 -7
  40. package/dist/dnd/autoScroll.js +10 -15
  41. package/dist/dnd/dropIndicator.js +2 -5
  42. package/dist/dnd/external.d.ts +6 -0
  43. package/dist/dnd/external.js +17 -0
  44. package/dist/dnd/geometry.d.ts +2 -0
  45. package/dist/dnd/geometry.js +3 -4
  46. package/dist/dnd/placement.d.ts +1 -1
  47. package/dist/dnd/pragmatic.d.ts +3 -1
  48. package/dist/dnd/pragmatic.js +12 -2
  49. package/dist/dnd/vendor/pragmatic/UPSTREAM.md +51 -18
  50. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.d.ts +4 -0
  51. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/drop-target-for-external.js +6 -0
  52. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.d.ts +0 -2
  53. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/element-adapter.js +4 -22
  54. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter-types.d.ts +26 -0
  55. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.d.ts +30 -0
  56. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/external-adapter.js +203 -0
  57. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-items.js +13 -0
  58. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/get-available-types.js +9 -0
  59. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/is-an-available-type.js +19 -0
  60. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.d.ts +4 -0
  61. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/adapter/monitor-for-external.js +6 -0
  62. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/honey-pot-fix/make-honey-pot-fix.js +4 -16
  63. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/internal-types.d.ts +1 -8
  64. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-drop-target.js +5 -6
  65. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/make-adapter/make-monitor.js +2 -3
  66. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.d.ts +1 -1
  67. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/element/custom-native-drag-preview/set-custom-native-drag-preview.js +6 -24
  68. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.d.ts +2 -0
  69. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/contains-files.js +5 -0
  70. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.d.ts +3 -0
  71. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/get-files.js +12 -0
  72. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/public-utils/external/native-types.d.ts +12 -0
  73. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window-in-safari.js +10 -0
  74. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/changing-window/is-entering-window.js +55 -0
  75. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.d.ts +4 -0
  76. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/entry-point/external.js +8 -0
  77. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/internal-types.d.ts +0 -4
  78. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/get-scroll-by.js +16 -72
  79. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/over-element/try-scroll.js +1 -9
  80. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/configuration.js +4 -29
  81. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/get-scroll-change.js +2 -3
  82. package/dist/edytor.svelte.d.ts +2 -5
  83. package/dist/edytor.svelte.js +17 -31
  84. package/dist/events/onBeforeInput.js +1 -1
  85. package/dist/events/onDrop.d.ts +0 -6
  86. package/dist/events/onDrop.js +10 -23
  87. package/dist/events/onInput.d.ts +0 -12
  88. package/dist/events/onInput.js +1 -67
  89. package/dist/export/forms.d.ts +627 -0
  90. package/dist/export/forms.js +749 -0
  91. package/dist/export/index.d.ts +170 -0
  92. package/dist/export/index.js +161 -0
  93. package/dist/export/markdown.d.ts +41 -0
  94. package/dist/export/markdown.js +585 -0
  95. package/dist/export/markdownWriter.d.ts +9 -0
  96. package/dist/export/markdownWriter.js +133 -0
  97. package/dist/export/mdx.d.ts +15 -0
  98. package/dist/export/mdx.js +33 -0
  99. package/dist/index.d.ts +3 -3
  100. package/dist/index.js +1 -1
  101. package/dist/kinds.js +1 -1
  102. package/dist/plugins/anchored.svelte.d.ts +21 -25
  103. package/dist/plugins/anchored.svelte.js +23 -39
  104. package/dist/plugins/blockHandles/BlockHandleController.svelte.js +24 -32
  105. package/dist/plugins/blockHandles/dragPreview.d.ts +26 -7
  106. package/dist/plugins/blockHandles/dragPreview.js +33 -0
  107. package/dist/plugins/blockMenu/BlockMenuController.svelte.d.ts +5 -0
  108. package/dist/plugins/blockMenu/BlockMenuController.svelte.js +7 -2
  109. package/dist/plugins/blockMenu/blockMenuPlugin.js +5 -50
  110. package/dist/plugins/chrome.d.ts +27 -5
  111. package/dist/plugins/chrome.js +24 -9
  112. package/dist/plugins/code/CodePlugin.svelte +12 -9
  113. package/dist/plugins/code/header.svelte.js +7 -11
  114. package/dist/plugins/code/languageMenu.svelte.d.ts +5 -2
  115. package/dist/plugins/code/languageMenu.svelte.js +13 -20
  116. package/dist/plugins/columns/ColumnsPlugin.svelte +7 -20
  117. package/dist/plugins/columns/resize.svelte.d.ts +2 -3
  118. package/dist/plugins/columns/resize.svelte.js +2 -5
  119. package/dist/plugins/comments/CommentsController.svelte.d.ts +6 -0
  120. package/dist/plugins/comments/CommentsController.svelte.js +20 -0
  121. package/dist/plugins/equation/EquationPlugin.svelte +12 -22
  122. package/dist/plugins/equation/equation.svelte.d.ts +7 -15
  123. package/dist/plugins/equation/equation.svelte.js +13 -50
  124. package/dist/plugins/equation/tex.d.ts +17 -0
  125. package/dist/plugins/equation/tex.js +42 -0
  126. package/dist/plugins/fileDrop.d.ts +38 -23
  127. package/dist/plugins/fileDrop.js +82 -76
  128. package/dist/plugins/find/FindController.svelte.d.ts +5 -0
  129. package/dist/plugins/find/FindController.svelte.js +14 -14
  130. package/dist/plugins/find/findPlugin.js +1 -15
  131. package/dist/plugins/image/ImageChrome.svelte +8 -2
  132. package/dist/plugins/image/ImagePlugin.svelte +15 -52
  133. package/dist/plugins/image/controls.svelte.js +16 -2
  134. package/dist/plugins/image/toolbar.svelte.d.ts +5 -4
  135. package/dist/plugins/image/toolbar.svelte.js +21 -31
  136. package/dist/plugins/index.d.ts +1 -1
  137. package/dist/plugins/list.svelte.d.ts +9 -0
  138. package/dist/plugins/list.svelte.js +18 -0
  139. package/dist/plugins/marquee/marqueePlugin.js +0 -4
  140. package/dist/plugins/media/AudioPlugin.svelte +1 -1
  141. package/dist/plugins/media/BookmarkPlugin.svelte +6 -97
  142. package/dist/plugins/media/EmbedPlugin.svelte +5 -90
  143. package/dist/plugins/media/EmptySlot.svelte +36 -20
  144. package/dist/plugins/media/EmptySlot.svelte.d.ts +6 -15
  145. package/dist/plugins/media/FilePlugin.svelte +1 -19
  146. package/dist/plugins/media/MediaEmpty.svelte +2 -55
  147. package/dist/plugins/media/MediaEmpty.svelte.d.ts +18 -14
  148. package/dist/plugins/media/SourceBlock.svelte +142 -52
  149. package/dist/plugins/media/SourceBlock.svelte.d.ts +10 -4
  150. package/dist/plugins/media/VideoPlugin.svelte +1 -1
  151. package/dist/plugins/media/empty.svelte.js +2 -7
  152. package/dist/plugins/media/media.d.ts +2 -63
  153. package/dist/plugins/media/media.js +1 -194
  154. package/dist/plugins/media/sources.d.ts +60 -0
  155. package/dist/plugins/media/sources.js +165 -0
  156. package/dist/plugins/media/urlPaste.svelte.d.ts +2 -1
  157. package/dist/plugins/media/urlPaste.svelte.js +12 -21
  158. package/dist/plugins/mention/MentionPlugin.svelte +8 -35
  159. package/dist/plugins/page/PagePlugin.svelte +2 -9
  160. package/dist/plugins/page/page.js +1 -1
  161. package/dist/plugins/pageLink/PageLinkPlugin.svelte +6 -13
  162. package/dist/plugins/richtext/RichTextPlugin.svelte +85 -197
  163. package/dist/plugins/richtext/body.js +1 -1
  164. package/dist/plugins/richtext/calloutIcons.svelte.d.ts +2 -2
  165. package/dist/plugins/richtext/calloutIcons.svelte.js +5 -7
  166. package/dist/plugins/richtext/richTextOperations.d.ts +1 -19
  167. package/dist/plugins/richtext/richTextOperations.js +3 -49
  168. package/dist/plugins/slashMenu/SlashMenuController.svelte.d.ts +2 -0
  169. package/dist/plugins/slashMenu/SlashMenuController.svelte.js +7 -0
  170. package/dist/plugins/slashMenu/slashMenuPlugin.js +5 -14
  171. package/dist/plugins/table/TableChrome.svelte +2 -3
  172. package/dist/plugins/table/TablePlugin.svelte +20 -54
  173. package/dist/plugins/table/chrome.svelte.d.ts +5 -2
  174. package/dist/plugins/table/chrome.svelte.js +30 -54
  175. package/dist/plugins/table/table.js +3 -3
  176. package/dist/plugins/toc/TocPlugin.svelte +2 -4
  177. package/dist/plugins/toolbar/ToolbarController.svelte.d.ts +7 -0
  178. package/dist/plugins/toolbar/ToolbarController.svelte.js +20 -13
  179. package/dist/plugins/toolbar/toolbarPlugin.js +19 -53
  180. package/dist/plugins/triggers/TriggerController.svelte.d.ts +7 -2
  181. package/dist/plugins/triggers/TriggerController.svelte.js +11 -4
  182. package/dist/plugins/triggers/place.js +1 -2
  183. package/dist/plugins/triggers/triggers.d.ts +6 -1
  184. package/dist/plugins/triggers/triggers.js +12 -13
  185. package/dist/plugins/uploads.svelte.d.ts +5 -2
  186. package/dist/plugins/uploads.svelte.js +25 -15
  187. package/dist/plugins.d.ts +26 -0
  188. package/dist/plugins.js +0 -24
  189. package/dist/selection/replaceSelection.js +2 -2
  190. package/dist/selection/selection.svelte.d.ts +4 -10
  191. package/dist/selection/selection.svelte.js +7 -11
  192. package/dist/session/bindings.js +1 -1
  193. package/dist/session/commands.d.ts +7 -11
  194. package/dist/session/commands.js +13 -19
  195. package/dist/session/inputRules.js +1 -1
  196. package/dist/session/navigation.js +1 -1
  197. package/dist/session/suggestions.svelte.d.ts +0 -11
  198. package/dist/session/suggestions.svelte.js +15 -3
  199. package/dist/session/uploads.d.ts +8 -8
  200. package/dist/surface/lines.js +1 -3
  201. package/dist/surface/observer.svelte.d.ts +17 -1
  202. package/dist/surface/observer.svelte.js +72 -17
  203. package/dist/surface/overlay.d.ts +0 -14
  204. package/dist/surface/overlay.js +0 -25
  205. package/dist/surface/projector.svelte.js +1 -1
  206. package/dist/text/text.svelte.js +3 -13
  207. package/dist/utils/sanitize.d.ts +38 -0
  208. package/dist/utils/sanitize.js +82 -0
  209. package/dist/utils.d.ts +2 -0
  210. package/dist/utils.js +5 -0
  211. package/package.json +18 -1
  212. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/max-z-index.js +0 -3
  213. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop/util/supports-popover.js +0 -16
  214. package/dist/dnd/vendor/pragmatic/pragmatic-drag-and-drop-auto-scroll/shared/is-axis-allowed.js +0 -3
  215. package/dist/plugins/code/LanguageMenu.svelte +0 -25
  216. package/dist/plugins/code/LanguageMenu.svelte.d.ts +0 -9
  217. package/dist/plugins/equation/EquationEditor.svelte +0 -27
  218. package/dist/plugins/equation/EquationEditor.svelte.d.ts +0 -9
  219. package/dist/plugins/image/ImageToolbarHost.svelte +0 -37
  220. package/dist/plugins/image/ImageToolbarHost.svelte.d.ts +0 -9
  221. package/dist/plugins/richtext/CalloutIconPicker.svelte +0 -26
  222. package/dist/plugins/richtext/CalloutIconPicker.svelte.d.ts +0 -9
@@ -1,8 +1,7 @@
1
1
  import { canScrollOnEdge } from '../shared/can-scroll-on-edge.js';
2
- import { edgeAxisLookup, edges } from '../shared/edges.js';
2
+ import { edges } from '../shared/edges.js';
3
3
  import { getOverElementHitbox } from '../shared/get-over-element-hitbox.js';
4
4
  import { getScrollChange } from '../shared/get-scroll-change.js';
5
- import { isAxisAllowed } from '../shared/is-axis-allowed.js';
6
5
  import { isWithin } from '../shared/is-within.js';
7
6
  function getRectDefault(element) {
8
7
  return element.getBoundingClientRect();
@@ -13,7 +12,6 @@ export function getScrollBy({
13
12
  timeSinceLastFrame,
14
13
  engagement,
15
14
  config,
16
- allowedAxis,
17
15
  getRect = getRectDefault
18
16
  }) {
19
17
  const client = {
@@ -26,15 +24,6 @@ export function getScrollBy({
26
24
  clientRect,
27
25
  config
28
26
  });
29
- const axis = edgeAxisLookup[edge];
30
-
31
- // Note: changing the allowed axis during a drag will not
32
- // reset time dampening. It was decided it would be too
33
- // complex to implement initially, and we can add it
34
- // later if needed.
35
- if (!isAxisAllowed(axis, allowedAxis)) {
36
- return map;
37
- }
38
27
  if (!isWithin({
39
28
  client,
40
29
  clientRect: hitbox
@@ -50,66 +39,21 @@ export function getScrollBy({
50
39
  });
51
40
  return map;
52
41
  }, new Map());
53
- const left = (() => {
54
- const axis = 'horizontal';
55
- const leftEdge = scrollableEdges.get('left');
56
- if (leftEdge) {
57
- return getScrollChange({
58
- client,
59
- edge: leftEdge.edge,
60
- hitbox: leftEdge.hitbox,
61
- axis,
62
- timeSinceLastFrame,
63
- engagement,
64
- isDistanceDampeningEnabled: true,
65
- config
66
- });
67
- }
68
- const rightEdge = scrollableEdges.get('right');
69
- if (rightEdge) {
70
- return getScrollChange({
71
- client,
72
- edge: rightEdge.edge,
73
- hitbox: rightEdge.hitbox,
74
- axis,
75
- timeSinceLastFrame,
76
- engagement,
77
- isDistanceDampeningEnabled: true,
78
- config
79
- });
80
- }
81
- return 0;
82
- })();
83
- const top = (() => {
84
- const axis = 'vertical';
85
- const bottomEdge = scrollableEdges.get('bottom');
86
- if (bottomEdge) {
87
- return getScrollChange({
88
- client,
89
- edge: bottomEdge.edge,
90
- hitbox: bottomEdge.hitbox,
91
- axis,
92
- timeSinceLastFrame,
93
- engagement,
94
- isDistanceDampeningEnabled: true,
95
- config
96
- });
97
- }
98
- const topEdge = scrollableEdges.get('top');
99
- if (topEdge) {
100
- return getScrollChange({
101
- client,
102
- edge: topEdge.edge,
103
- hitbox: topEdge.hitbox,
104
- axis,
105
- timeSinceLastFrame,
106
- engagement,
107
- isDistanceDampeningEnabled: true,
108
- config
109
- });
110
- }
111
- return 0;
112
- })();
42
+ // edytor: one change per axis, the first of its edges the pointer is over.
43
+ const change = (axis, first, second) => {
44
+ const entry = scrollableEdges.get(first) ?? scrollableEdges.get(second);
45
+ return entry ? getScrollChange({
46
+ client,
47
+ edge: entry.edge,
48
+ hitbox: entry.hitbox,
49
+ axis,
50
+ timeSinceLastFrame,
51
+ engagement,
52
+ config
53
+ }) : 0;
54
+ };
55
+ const left = change('horizontal', 'left', 'right');
56
+ const top = change('vertical', 'bottom', 'top');
113
57
  return {
114
58
  left,
115
59
  top
@@ -1,4 +1,4 @@
1
- import { getInternalConfig } from '../shared/configuration.js';
1
+ import { internalConfig as config } from '../shared/configuration.js';
2
2
  import { markAndGetEngagement } from '../shared/engagement-history.js';
3
3
  import { selector } from './data-attributes.js';
4
4
  import { getScrollBy } from './get-scroll-by.js';
@@ -16,7 +16,6 @@ function tryScrollElements({
16
16
  left: true
17
17
  }
18
18
  }) {
19
- var _container$getConfigu, _container$getAllowed, _container$getAllowed2;
20
19
  // we cannot do any more scrolling
21
20
  if (!isScrollingAvailable(available)) {
22
21
  return available;
@@ -64,14 +63,11 @@ function tryScrollElements({
64
63
  // Marking engagement even if no edges are scrollable.
65
64
  // We are marking engagement as soon as the element is scrolled over
66
65
  const engagement = markAndGetEngagement(element);
67
- const config = getInternalConfig((_container$getConfigu = container.getConfiguration) === null || _container$getConfigu === void 0 ? void 0 : _container$getConfigu.call(container, feedback));
68
- const allowedAxis = (_container$getAllowed = (_container$getAllowed2 = container.getAllowedAxis) === null || _container$getAllowed2 === void 0 ? void 0 : _container$getAllowed2.call(container, feedback)) !== null && _container$getAllowed !== void 0 ? _container$getAllowed : 'all';
69
66
  const scrollBy = getScrollBy({
70
67
  element,
71
68
  engagement,
72
69
  input,
73
70
  timeSinceLastFrame,
74
- allowedAxis,
75
71
  config
76
72
  });
77
73
 
@@ -111,7 +107,6 @@ function tryScrollWindow({
111
107
  element
112
108
  };
113
109
  for (const entry of entries) {
114
- var _entry$getConfigurati, _entry$getAllowedAxis, _entry$getAllowedAxis2;
115
110
  // this entry is not allowing scrolling, we need to look for another
116
111
  if (entry.canScroll && !entry.canScroll(feedback)) {
117
112
  continue;
@@ -120,14 +115,11 @@ function tryScrollWindow({
120
115
  // Note: if we had an event for when the user is leaving a tab
121
116
  // we _could_ conceptually reset the engagement
122
117
  const engagement = markAndGetEngagement(element);
123
- const config = getInternalConfig((_entry$getConfigurati = entry.getConfiguration) === null || _entry$getConfigurati === void 0 ? void 0 : _entry$getConfigurati.call(entry, feedback));
124
- const allowedAxis = (_entry$getAllowedAxis = (_entry$getAllowedAxis2 = entry.getAllowedAxis) === null || _entry$getAllowedAxis2 === void 0 ? void 0 : _entry$getAllowedAxis2.call(entry, feedback)) !== null && _entry$getAllowedAxis !== void 0 ? _entry$getAllowedAxis : 'all';
125
118
  const scrollBy = getScrollBy({
126
119
  element,
127
120
  engagement,
128
121
  input,
129
122
  config,
130
- allowedAxis,
131
123
  getRect: element => DOMRect.fromRect({
132
124
  y: 0,
133
125
  x: 0,
@@ -17,33 +17,8 @@ const baseConfig = {
17
17
  maxMainAxisHitboxSize: 180
18
18
  };
19
19
 
20
- /** What the max scroll should be per second. Using "per second" rather than "per frame"
21
- * as we want a consistent scroll speed regardless of frame rate.
22
- *
23
- *
24
- * I explored trying to make the max scroll speed dynamic based on particular factors.
25
- * However, it ended up being difficult to find a _perfect_ formula.
26
- *
27
- * Likely the perfect answer would involve:
28
- * - the size of the scrollable element
29
- * - the size of the scrollable element relative to the screen size
30
- * - the size of the drag preview
31
- * - the size of elements being scrolled in scrollable elements (expensive and difficult to compute)
32
- */
33
- const maxPixelScrollPerSecond = {
34
- // What the value would be if we were scrolling at 15px per frame at 60fps.
35
- // This is the default as it works well for most experiences.
36
- // In certain scenarios though it can feel a bit slow.
37
- standard: 15 * 60,
38
- // What the value would be if we were scrolling at 25px per frame at 60fps.
39
- // This is not the default as it feels too fast for a lot of experiences.
40
- fast: 25 * 60
20
+ // edytor: no element sets `getConfiguration`: the standard speed only.
21
+ export const internalConfig = {
22
+ ...baseConfig,
23
+ maxPixelScrollPerSecond: 15 * 60
41
24
  };
42
- export function getInternalConfig(provided) {
43
- var _provided$maxScrollSp;
44
- return {
45
- ...baseConfig,
46
- // only allowing limited control over the config at this stage
47
- maxPixelScrollPerSecond: maxPixelScrollPerSecond[(_provided$maxScrollSp = provided === null || provided === void 0 ? void 0 : provided.maxScrollSpeed) !== null && _provided$maxScrollSp !== void 0 ? _provided$maxScrollSp : 'standard']
48
- };
49
- }
@@ -62,7 +62,6 @@ export function getScrollChange({
62
62
  axis,
63
63
  hitbox,
64
64
  edge,
65
- isDistanceDampeningEnabled,
66
65
  config
67
66
  }) {
68
67
  // We have two forms of speed dampening:
@@ -77,13 +76,13 @@ export function getScrollChange({
77
76
  timeSinceLastFrame,
78
77
  config
79
78
  });
80
- const percentageDistanceDampening = isDistanceDampeningEnabled ? getDistanceDampening({
79
+ const percentageDistanceDampening = getDistanceDampening({
81
80
  client,
82
81
  edge,
83
82
  hitbox,
84
83
  axis,
85
84
  config
86
- }) : 1;
85
+ });
87
86
 
88
87
  // Dampen speed by time
89
88
  const percentageThroughTimeDampening = getPercentageInRange({
@@ -34,12 +34,9 @@ export type EdytorOptions = {
34
34
  * The assembled document this view renders — shared facade, history,
35
35
  * awareness and semantics live on it (see `crdt/document.ts`). When
36
36
  * injected the view borrows it: `destroy()` releases only view-owned
37
- * resources. When absent the view internally owns a document built
38
- * around `doc`/`awareness` (the legacy path — same behavior as before).
37
+ * resources. When absent the view owns a fresh one.
39
38
  */
40
39
  document?: EdytorDocument;
41
- doc?: YDoc;
42
- awareness?: Awareness;
43
40
  /** The local author of a view-owned document (with `document`, set it there). */
44
41
  actor?: DocumentActor;
45
42
  /** A view-owned document's `requireHydration` (with `document`, set it there). */
@@ -221,7 +218,7 @@ export declare class Edytor {
221
218
  * discarded.
222
219
  *
223
220
  * Releases every listener the editor holds on potentially-SHARED objects
224
- * — an injected doc/awareness outlives a single editor, so an
221
+ * — an injected document outlives a single editor, so an
225
222
  * undestroyed mount leaks a facade `update` listener and the undo
226
223
  * manager's doc observers forever.
227
224
  *
@@ -6,7 +6,7 @@ import { onCut } from './events/onCut.js';
6
6
  import { isControlEvent, isKindControl } from './events/nativeInteractiveControl.js';
7
7
  import { onInput } from './events/onInput.js';
8
8
  import { onPaste } from './events/onPaste.js';
9
- import { onDragLeave, onTextDragEnd, onTextDragStart, preventUnsupportedDrop } from './events/onDrop.js';
9
+ import { onTextDragEnd, onTextDragStart, preventUnsupportedDrop } from './events/onDrop.js';
10
10
  import { attachFocus, selectionIsInside, takeKeys } from './events/onFocus.js';
11
11
  import { insertLineBreak, runIntent } from './events/beforeInputCommands.js';
12
12
  import { textPointAt } from './selection/selection.utils.js';
@@ -29,7 +29,7 @@ import Announcer from './components/Announcer.svelte';
29
29
  import RemoteSelections from './collaboration/RemoteSelections.svelte';
30
30
  import Ranges from './components/Ranges.svelte';
31
31
  import { Handles } from './session/handles.js';
32
- import { id } from './utils.js';
32
+ import { cleanups, id } from './utils.js';
33
33
  import { Y } from './crdt/engine.js';
34
34
  import { markName } from './crdt/text/marks.js';
35
35
  import { callEach } from './crdt/protocols/observable.js';
@@ -193,11 +193,10 @@ export class Edytor {
193
193
  // CRDT (v14) — the document is the composition owner: it holds the ONE
194
194
  // engine doc, the shared facade (only structural read/write surface),
195
195
  // the default local history and the shared awareness. Injected
196
- // documents are borrowed; a view with no `document` option internally
197
- // owns one (built around `doc`/`awareness` when those are injected).
196
+ // documents are borrowed; a view with no `document` option owns a fresh one.
198
197
  document;
199
- /** @internal `true` when this view created its document — `destroy()` then releases it. */
200
- ownsDocument = false;
198
+ /** `true` when this view created its document — `destroy()` then releases it. */
199
+ #owned = false;
201
200
  get doc() {
202
201
  return this.document.doc;
203
202
  }
@@ -297,7 +296,7 @@ export class Edytor {
297
296
  this.dispatcher.record({ operation: command, status: this.history.replay(command) });
298
297
  };
299
298
  constructor(options) {
300
- const { readonly, hotkeys, plugins, document, doc, awareness, actor, requireHydration, presence, sync, value, onSelectionChange, labels, onChange, onDocChange, allowNesting } = options;
299
+ const { readonly, hotkeys, plugins, document, actor, requireHydration, presence, sync, value, onSelectionChange, labels, onChange, onDocChange, allowNesting } = options;
301
300
  for (const name of DOCUMENT_WRITES)
302
301
  Object.defineProperty(this, name, {
303
302
  value: (...args) => this.dispatcher.operate(name, args)
@@ -306,21 +305,14 @@ export class Edytor {
306
305
  this.labels = labels;
307
306
  this.allowNesting = allowNesting === true;
308
307
  if (document !== undefined) {
309
- if (DEV &&
310
- (doc !== undefined ||
311
- awareness !== undefined ||
312
- actor !== undefined ||
313
- requireHydration !== undefined)) {
314
- throw new Error('EdytorOptions: `document` cannot be combined with `doc`/`awareness`/`actor`/`requireHydration` — ' +
315
- 'the document owns them (compose them via attachDocument first).');
308
+ if (DEV && (actor !== undefined || requireHydration !== undefined)) {
309
+ throw new Error('EdytorOptions: `document` cannot be combined with `actor`/`requireHydration`: set them on the document.');
316
310
  }
317
311
  this.document = document;
318
312
  }
319
313
  else {
320
- // Legacy path — the view internally owns a document composed
321
- // around the injected (or a fresh) doc/awareness.
322
- this.document = attachDocument(doc ?? new Y.Doc(), { awareness, actor, requireHydration });
323
- this.ownsDocument = true;
314
+ this.document = attachDocument(new Y.Doc(), { actor, requireHydration });
315
+ this.#owned = true;
324
316
  }
325
317
  this.readonly = readonly || false;
326
318
  this.onChange = onChange;
@@ -388,7 +380,7 @@ export class Edytor {
388
380
  // decision; every other view binds on the one readiness event
389
381
  // (`<Edytor>` decides an injected document at mount, once the
390
382
  // providers of its sibling views attached).
391
- if (this.ownsDocument && !sync) {
383
+ if (this.#owned && !sync) {
392
384
  this.sync(value || { children: [] });
393
385
  }
394
386
  else {
@@ -409,7 +401,7 @@ export class Edytor {
409
401
  // document-lifetime additive declarations, and an injected
410
402
  // document's are left for the views that legitimately share it.
411
403
  this.document.untrackOrigin(this.transaction);
412
- if (this.ownsDocument) {
404
+ if (this.#owned) {
413
405
  this.document.destroy();
414
406
  }
415
407
  throw error;
@@ -611,9 +603,7 @@ export class Edytor {
611
603
  // A failed async handler (a command's hook or write) surfaces
612
604
  // through the platform's error reporting; the DOM ignores
613
605
  // the listener's promise.
614
- void Promise.resolve(result)
615
- .finally(clear)
616
- .catch((error) => typeof reportError === 'function' ? reportError(error) : console.error(error));
606
+ void Promise.resolve(result).finally(clear).catch(reportError);
617
607
  }
618
608
  else {
619
609
  clear();
@@ -812,7 +802,7 @@ export class Edytor {
812
802
  on(node, 'contextmenu', () => void this.surface.flush()), on(node, 'beforeinput', this.#withUserInput(this.onBeforeInput)),
813
803
  // An `input` records what the browser did; it says nothing new about
814
804
  // where the user wants the selection (a display still to land wins).
815
- on(node, 'input', this.#withUserInput(this.onInput, { bumpSerial: false })), on(node, 'copy', this.onCopy), on(node, 'cut', this.#withUserInput(this.onCut)), on(node, 'paste', this.#withUserInput(this.onPaste)), on(node, 'dragstart', (event) => onTextDragStart(this, event)), on(node, 'dragend', () => onTextDragEnd(this)), on(node, 'dragover', (event) => preventUnsupportedDrop(event, this)), on(node, 'dragleave', (event) => onDragLeave(this, event)), on(node, 'drop', this.#withUserInput((event) => preventUnsupportedDrop(event, this))), on(node, 'compositionstart', this.onCompositionStart), on(node, 'compositionend', this.onCompositionEnd), detachSurface);
805
+ on(node, 'input', this.#withUserInput(this.onInput, { bumpSerial: false })), on(node, 'copy', this.onCopy), on(node, 'cut', this.#withUserInput(this.onCut)), on(node, 'paste', this.#withUserInput(this.onPaste)), on(node, 'dragstart', (event) => onTextDragStart(this, event)), on(node, 'dragend', () => onTextDragEnd(this)), on(node, 'dragover', (event) => preventUnsupportedDrop(event, this)), on(node, 'drop', this.#withUserInput((event) => preventUnsupportedDrop(event, this))), on(node, 'compositionstart', this.onCompositionStart), on(node, 'compositionend', this.onCompositionEnd), detachSurface);
816
806
  // Chrome lives in the overlay, outside the host: remote carets, then the plugins'.
817
807
  const detachOverlay = this.overlay.attach(node);
818
808
  const presence = mount(RemoteSelections, {
@@ -830,11 +820,7 @@ export class Edytor {
830
820
  props: { announcer: this.announcer }
831
821
  });
832
822
  this.off.push(() => unmount(presence), () => unmount(ranges), () => unmount(live), detachOverlay);
833
- this.plugins.forEach((plugin) => {
834
- const action = plugin.onEdytorAttached?.({ node });
835
- if (typeof action === 'function')
836
- this.off.push(action);
837
- });
823
+ this.off.push(...cleanups(this.plugins, (plugin) => plugin.onEdytorAttached?.({ node })));
838
824
  return {
839
825
  destroy: () => {
840
826
  if (selectionIsInside(node))
@@ -864,7 +850,7 @@ export class Edytor {
864
850
  * discarded.
865
851
  *
866
852
  * Releases every listener the editor holds on potentially-SHARED objects
867
- * — an injected doc/awareness outlives a single editor, so an
853
+ * — an injected document outlives a single editor, so an
868
854
  * undestroyed mount leaks a facade `update` listener and the undo
869
855
  * manager's doc observers forever.
870
856
  *
@@ -908,7 +894,7 @@ export class Edytor {
908
894
  // awareness, doc) belong to the document — released exactly once,
909
895
  // and only when THIS view created it. A borrowed document keeps
910
896
  // serving its sibling views and headless consumers.
911
- if (this.ownsDocument) {
897
+ if (this.#owned) {
912
898
  this.document.destroy();
913
899
  }
914
900
  };
@@ -7,7 +7,7 @@ import { isAndroidChromeBrowser } from './events.utils.js';
7
7
  import { isNativeInteractiveControl, isNativeInteractiveEvent, ownsEvent } from './nativeInteractiveControl.js';
8
8
  import { runBeforeInputCommand } from './beforeInputCommands.js';
9
9
  import { deleteInText } from './beforeInputDeleteCommands.js';
10
- import { readDomText } from './onInput.js';
10
+ import { readDomText } from '../surface/observer.svelte.js';
11
11
  /** The Android no-op-Backspace and model-owned drift deadlines (named, counted browser rules). */
12
12
  const NATIVE_INPUT_REPAIR_WINDOW_MS = 150;
13
13
  const dirOf = (inputType) => INTENTS[inputType]?.dir;
@@ -31,9 +31,3 @@ export declare const onTextDragEnd: (edytor: Edytor) => undefined;
31
31
  * which is the control's (`isControlDrop`).
32
32
  */
33
33
  export declare const preventUnsupportedDrop: (event: DragEvent, edytor: Edytor) => void | Promise<void>;
34
- /**
35
- * A drag leaving the host (to the page around it, or out of the window):
36
- * a file drag's indicator goes. Moving between the host's own elements is
37
- * no leave.
38
- */
39
- export declare const onDragLeave: (edytor: Edytor, event: DragEvent) => void;
@@ -13,8 +13,9 @@ import { viewUploads } from '../session/uploads.js';
13
13
  * `Files` is intentionally accepted (so the browser never opens a dropped
14
14
  * file in place of the page): with the view's uploads (a media plugin given
15
15
  * an `upload`), file drops route through the plugin `onPaste` hook with the
16
- * drop indicator's placement (`ViewUploads.drop`: a block per file the kinds
17
- * take there; unclaimed files insert nothing); without them a drop carrying
16
+ * placement the uploads' drop target resolved (`ViewUploads.drop`, Pragmatic's
17
+ * external adapter: a block per file the kinds take there; unclaimed files
18
+ * insert nothing); without them a drop carrying
18
19
  * files is ignored, its effect `none`.
19
20
  */
20
21
  const ACCEPTED_FOREIGN_DROP_TYPES = ['Files', 'text/html', 'text/plain', 'text/uri-list'];
@@ -188,21 +189,19 @@ export const preventUnsupportedDrop = (event, edytor) => {
188
189
  if (isAcceptedForeignDrop(root, event.dataTransfer)) {
189
190
  event.preventDefault();
190
191
  event.stopPropagation();
191
- // Files show where they land (the block drag's indicator); none in a
192
- // read-only view or one without uploads, which takes no file drop (the
193
- // browser must not open the file).
194
- const shown = drop && !ownsEvent(root, event) && drop.over(event);
192
+ // Where files land shows from the uploads' drop target (Pragmatic's
193
+ // external adapter); a read-only view or one without uploads takes no
194
+ // file drop, and the browser must not open the file.
195
195
  if (event.dataTransfer)
196
196
  event.dataTransfer.dropEffect = files && (edytor.readonly || !drop) ? 'none' : 'copy';
197
- if (drop && !shown)
198
- drop.end();
199
197
  }
200
198
  return;
201
199
  }
202
200
  const accepted = isAcceptedForeignDrop(root, event.dataTransfer);
203
- // Where the files land: the indicator's placement, re-resolved at the drop point.
204
- const at = drop && accepted && !ownsEvent(root, event) ? drop.at(event) : null;
205
- drop?.end();
201
+ // Where the files land: the placement the uploads' drop target resolved at
202
+ // the drop point (its window listener captures, so it ran first).
203
+ const placed = drop?.take() ?? null;
204
+ const at = accepted && !ownsEvent(root, event) ? placed : null;
206
205
  if (accepted && isControlDrop(root, event))
207
206
  return;
208
207
  event.preventDefault();
@@ -219,15 +218,3 @@ export const preventUnsupportedDrop = (event, edytor) => {
219
218
  if (!edytor.isComposing)
220
219
  return insertFromDrop(edytor, root, event, at);
221
220
  };
222
- /**
223
- * A drag leaving the host (to the page around it, or out of the window):
224
- * a file drag's indicator goes. Moving between the host's own elements is
225
- * no leave.
226
- */
227
- export const onDragLeave = (edytor, event) => {
228
- const root = event.currentTarget;
229
- const to = event.relatedTarget;
230
- if (to instanceof Node && root.contains(to))
231
- return;
232
- viewUploads(edytor)?.drop.end();
233
- };
@@ -1,16 +1,4 @@
1
1
  import type { Edytor } from '../edytor.svelte.js';
2
- import type { Text } from '../text/text.svelte.js';
3
- /**
4
- * What the browser shows for `text`: its element's text nodes in order (WebKit's
5
- * converted-space wrappers read as plain spaces), the empty filler and the
6
- * trailing-newline marker stripped.
7
- */
8
- export declare const readDomText: (text: Text) => string;
9
- export declare const getCollapsedDomTextSelection: (edytor: Edytor) => {
10
- text: Text;
11
- offset: number;
12
- } | null;
13
- export declare const handleNativeLineBreakTextValue: (edytor: Edytor, text: Text, value: string) => Promise<boolean>;
14
2
  /**
15
3
  * An `input` event. Browser-made text is never adopted here: the mutation
16
4
  * queue is the only adopter (a native line break there runs as its
@@ -1,76 +1,10 @@
1
- import { diffText } from '../utils/diffText.js';
2
- import { getDomSelectionSnapshot } from '../selection/domSelection.js';
3
- import { domOffsetIn } from '../selection/selection.utils.js';
4
1
  import { isControlEvent } from './nativeInteractiveControl.js';
5
- import { runOccurrence } from './onBeforeInput.js';
6
2
  import { attemptOf, kindOf } from '../session/attempt.js';
7
- const ZERO_WIDTH_SPACE = '\u200B';
8
- /**
9
- * What the browser shows for `text`: its element's text nodes in order (WebKit's
10
- * converted-space wrappers read as plain spaces), the empty filler and the
11
- * trailing-newline marker stripped.
12
- */
13
- export const readDomText = (text) => {
14
- let value = '';
15
- const node = text.node;
16
- if (node) {
17
- const walker = (node.ownerDocument ?? document).createTreeWalker(node, NodeFilter.SHOW_TEXT);
18
- while (walker.nextNode()) {
19
- const leaf = walker.currentNode;
20
- value += leaf.parentElement?.closest('span.Apple-converted-space')
21
- ? leaf.data.replaceAll('\u00A0', ' ')
22
- : leaf.data;
23
- }
24
- }
25
- // An empty text's filler shares its node with what the browser typed, on either side.
26
- if (text.isEmpty)
27
- return value.replaceAll(ZERO_WIDTH_SPACE, '');
28
- if (text.endsWithNewline && value.endsWith(ZERO_WIDTH_SPACE)) {
29
- value = value.slice(0, -ZERO_WIDTH_SPACE.length);
30
- }
31
- return value;
32
- };
33
- export const getCollapsedDomTextSelection = (edytor) => {
34
- const selection = getDomSelectionSnapshot(edytor.node);
35
- if (!selection?.anchorNode || !selection.isCollapsed) {
36
- return null;
37
- }
38
- if (!edytor.node?.contains(selection.anchorNode)) {
39
- return null;
40
- }
41
- const text = edytor.selection.getTextOfNode(selection.anchorNode);
42
- if (!text?.node) {
43
- return null;
44
- }
45
- // No model rule here: the DOM caret is read BEFORE the reconcile writes
46
- // the model, so a native insertion legitimately sits past `text.length`
47
- // (`selectText` clamps the final write).
48
- return { text, offset: domOffsetIn(text, selection.anchorNode, selection.anchorOffset) };
49
- };
3
+ import { getCollapsedDomTextSelection } from '../surface/observer.svelte.js';
50
4
  const getInputType = (event) => {
51
5
  const inputType = event.inputType;
52
6
  return typeof inputType === 'string' ? inputType : '';
53
7
  };
54
- const getNativeLineBreakInsertionIndexFromValue = (text, value) => {
55
- const change = diffText(text.stringContent, value);
56
- return change && !change.remove && /^[\r\n]+$/.test(change.insert) ? change.at : null;
57
- };
58
- export const handleNativeLineBreakTextValue = async (edytor, text, value) => {
59
- if (!text.isInDocument)
60
- return false;
61
- const insertionIndex = getNativeLineBreakInsertionIndexFromValue(text, value);
62
- if (insertionIndex === null) {
63
- return false;
64
- }
65
- // The native line break is the key's occurrence: its intent, run by the model.
66
- const inputType = edytor.attempts.confirm()?.inputType === 'insertLineBreak' || value.includes('\n')
67
- ? 'insertLineBreak'
68
- : 'insertParagraph';
69
- text.refreshFromModel();
70
- edytor.selection.selectText(text, insertionIndex);
71
- await runOccurrence(edytor, { inputType, cancelable: false });
72
- return true;
73
- };
74
8
  /**
75
9
  * An `input` no attempt expected (its engine sent no `beforeinput`): the
76
10
  * browser changed the text under its caret — a browser-owned attempt of its own.