editable.ts 0.0.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.
Files changed (153) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +571 -0
  3. package/dist/editable.umd.cjs +2 -0
  4. package/dist/editable.umd.cjs.map +1 -0
  5. package/lib/block.d.ts +13 -0
  6. package/lib/block.d.ts.map +1 -0
  7. package/lib/block.js +58 -0
  8. package/lib/block.js.map +1 -0
  9. package/lib/clipboard.d.ts +22 -0
  10. package/lib/clipboard.d.ts.map +1 -0
  11. package/lib/clipboard.js +154 -0
  12. package/lib/clipboard.js.map +1 -0
  13. package/lib/config.d.ts +37 -0
  14. package/lib/config.d.ts.map +1 -0
  15. package/lib/config.js +64 -0
  16. package/lib/config.js.map +1 -0
  17. package/lib/content.d.ts +37 -0
  18. package/lib/content.d.ts.map +1 -0
  19. package/lib/content.js +526 -0
  20. package/lib/content.js.map +1 -0
  21. package/lib/core.d.ts +97 -0
  22. package/lib/core.d.ts.map +1 -0
  23. package/lib/core.js +261 -0
  24. package/lib/core.js.map +1 -0
  25. package/lib/create-default-behavior.d.ts +31 -0
  26. package/lib/create-default-behavior.d.ts.map +1 -0
  27. package/lib/create-default-behavior.js +178 -0
  28. package/lib/create-default-behavior.js.map +1 -0
  29. package/lib/create-default-events.d.ts +152 -0
  30. package/lib/create-default-events.d.ts.map +1 -0
  31. package/lib/create-default-events.js +183 -0
  32. package/lib/create-default-events.js.map +1 -0
  33. package/lib/cursor.d.ts +68 -0
  34. package/lib/cursor.d.ts.map +1 -0
  35. package/lib/cursor.js +354 -0
  36. package/lib/cursor.js.map +1 -0
  37. package/lib/dispatcher.d.ts +78 -0
  38. package/lib/dispatcher.d.ts.map +1 -0
  39. package/lib/dispatcher.js +416 -0
  40. package/lib/dispatcher.js.map +1 -0
  41. package/lib/eventable.d.ts +2 -0
  42. package/lib/eventable.d.ts.map +1 -0
  43. package/lib/eventable.js +104 -0
  44. package/lib/eventable.js.map +1 -0
  45. package/lib/feature-detection.d.ts +12 -0
  46. package/lib/feature-detection.d.ts.map +1 -0
  47. package/lib/feature-detection.js +42 -0
  48. package/lib/feature-detection.js.map +1 -0
  49. package/lib/highlight-support.d.ts +24 -0
  50. package/lib/highlight-support.d.ts.map +1 -0
  51. package/lib/highlight-support.js +172 -0
  52. package/lib/highlight-support.js.map +1 -0
  53. package/lib/highlight-text.d.ts +21 -0
  54. package/lib/highlight-text.d.ts.map +1 -0
  55. package/lib/highlight-text.js +147 -0
  56. package/lib/highlight-text.js.map +1 -0
  57. package/lib/keyboard.d.ts +33 -0
  58. package/lib/keyboard.d.ts.map +1 -0
  59. package/lib/keyboard.js +189 -0
  60. package/lib/keyboard.js.map +1 -0
  61. package/lib/monitored-highlighting.d.ts +28 -0
  62. package/lib/monitored-highlighting.d.ts.map +1 -0
  63. package/lib/monitored-highlighting.js +194 -0
  64. package/lib/monitored-highlighting.js.map +1 -0
  65. package/lib/node-iterator.d.ts +16 -0
  66. package/lib/node-iterator.d.ts.map +1 -0
  67. package/lib/node-iterator.js +97 -0
  68. package/lib/node-iterator.js.map +1 -0
  69. package/lib/node-type.d.ts +13 -0
  70. package/lib/node-type.d.ts.map +1 -0
  71. package/lib/node-type.js +15 -0
  72. package/lib/node-type.js.map +1 -0
  73. package/lib/parser.d.ts +89 -0
  74. package/lib/parser.d.ts.map +1 -0
  75. package/lib/parser.js +251 -0
  76. package/lib/parser.js.map +1 -0
  77. package/lib/plugins/highlighting/match-collection.d.ts +7 -0
  78. package/lib/plugins/highlighting/match-collection.d.ts.map +1 -0
  79. package/lib/plugins/highlighting/match-collection.js +62 -0
  80. package/lib/plugins/highlighting/match-collection.js.map +1 -0
  81. package/lib/plugins/highlighting/spellcheck-service.d.ts +12 -0
  82. package/lib/plugins/highlighting/spellcheck-service.d.ts.map +1 -0
  83. package/lib/plugins/highlighting/spellcheck-service.js +24 -0
  84. package/lib/plugins/highlighting/spellcheck-service.js.map +1 -0
  85. package/lib/plugins/highlighting/text-search.d.ts +10 -0
  86. package/lib/plugins/highlighting/text-search.d.ts.map +1 -0
  87. package/lib/plugins/highlighting/text-search.js +92 -0
  88. package/lib/plugins/highlighting/text-search.js.map +1 -0
  89. package/lib/plugins/highlighting/whitespace-highlighting.d.ts +14 -0
  90. package/lib/plugins/highlighting/whitespace-highlighting.d.ts.map +1 -0
  91. package/lib/plugins/highlighting/whitespace-highlighting.js +52 -0
  92. package/lib/plugins/highlighting/whitespace-highlighting.js.map +1 -0
  93. package/lib/quotes.d.ts +8 -0
  94. package/lib/quotes.d.ts.map +1 -0
  95. package/lib/quotes.js +170 -0
  96. package/lib/quotes.js.map +1 -0
  97. package/lib/range-container.d.ts +22 -0
  98. package/lib/range-container.d.ts.map +1 -0
  99. package/lib/range-container.js +52 -0
  100. package/lib/range-container.js.map +1 -0
  101. package/lib/range-save-restore.d.ts +13 -0
  102. package/lib/range-save-restore.d.ts.map +1 -0
  103. package/lib/range-save-restore.js +153 -0
  104. package/lib/range-save-restore.js.map +1 -0
  105. package/lib/selection-watcher.d.ts +55 -0
  106. package/lib/selection-watcher.d.ts.map +1 -0
  107. package/lib/selection-watcher.js +126 -0
  108. package/lib/selection-watcher.js.map +1 -0
  109. package/lib/selection.d.ts +74 -0
  110. package/lib/selection.d.ts.map +1 -0
  111. package/lib/selection.js +341 -0
  112. package/lib/selection.js.map +1 -0
  113. package/lib/smartQuotes.d.ts +16 -0
  114. package/lib/smartQuotes.d.ts.map +1 -0
  115. package/lib/smartQuotes.js +92 -0
  116. package/lib/smartQuotes.js.map +1 -0
  117. package/lib/util/binary_search.d.ts +23 -0
  118. package/lib/util/binary_search.d.ts.map +1 -0
  119. package/lib/util/binary_search.js +137 -0
  120. package/lib/util/binary_search.js.map +1 -0
  121. package/lib/util/clone-deep.d.ts +8 -0
  122. package/lib/util/clone-deep.d.ts.map +1 -0
  123. package/lib/util/clone-deep.js +10 -0
  124. package/lib/util/clone-deep.js.map +1 -0
  125. package/lib/util/dom.d.ts +43 -0
  126. package/lib/util/dom.d.ts.map +1 -0
  127. package/lib/util/dom.js +272 -0
  128. package/lib/util/dom.js.map +1 -0
  129. package/lib/util/element.d.ts +10 -0
  130. package/lib/util/element.d.ts.map +1 -0
  131. package/lib/util/element.js +29 -0
  132. package/lib/util/element.js.map +1 -0
  133. package/lib/util/error.d.ts +2 -0
  134. package/lib/util/error.d.ts.map +1 -0
  135. package/lib/util/error.js +16 -0
  136. package/lib/util/error.js.map +1 -0
  137. package/lib/util/log.d.ts +2 -0
  138. package/lib/util/log.d.ts.map +1 -0
  139. package/lib/util/log.js +18 -0
  140. package/lib/util/log.js.map +1 -0
  141. package/lib/util/merge.d.ts +6 -0
  142. package/lib/util/merge.d.ts.map +1 -0
  143. package/lib/util/merge.js +31 -0
  144. package/lib/util/merge.js.map +1 -0
  145. package/lib/util/string.d.ts +25 -0
  146. package/lib/util/string.d.ts.map +1 -0
  147. package/lib/util/string.js +68 -0
  148. package/lib/util/string.js.map +1 -0
  149. package/lib/util/viewport.d.ts +6 -0
  150. package/lib/util/viewport.d.ts.map +1 -0
  151. package/lib/util/viewport.js +8 -0
  152. package/lib/util/viewport.js.map +1 -0
  153. package/package.json +86 -0
package/lib/core.js ADDED
@@ -0,0 +1,261 @@
1
+ import config from './config.js';
2
+ import error from './util/error.js';
3
+ import * as parser from './parser.js';
4
+ import * as block from './block.js';
5
+ import * as content from './content.js';
6
+ import * as clipboard from './clipboard.js';
7
+ import Dispatcher from './dispatcher.js';
8
+ import Cursor from './cursor.js';
9
+ import highlightSupport from './highlight-support.js';
10
+ import MonitoredHighlighting from './monitored-highlighting.js';
11
+ import createDefaultEvents from './create-default-events.js';
12
+ import { textNodesUnder, getTextNodeAndRelativeOffset } from './util/element.js';
13
+ import { binaryCursorSearch } from './util/binary_search.js';
14
+ import { domArray, createRange, nodeContainsRange } from './util/dom.js';
15
+ export class Editable {
16
+ constructor(instanceConfig) {
17
+ const defaultInstanceConfig = {
18
+ window: window,
19
+ defaultBehavior: true,
20
+ mouseMoveSelectionChanges: false,
21
+ browserSpellcheck: true
22
+ };
23
+ this.config = Object.assign(defaultInstanceConfig, instanceConfig);
24
+ this.win = this.config.window;
25
+ this.editableSelector = `.${config.editableClass}`;
26
+ this.dispatcher = new Dispatcher(this);
27
+ if (this.config.defaultBehavior === true) {
28
+ this.dispatcher.on(createDefaultEvents(this));
29
+ }
30
+ }
31
+ static getGlobalConfig() {
32
+ return config;
33
+ }
34
+ static globalConfig(globalConfig) {
35
+ Object.assign(config, globalConfig);
36
+ clipboard.updateConfig(config);
37
+ }
38
+ add(target, options) {
39
+ this.enable(target, options);
40
+ return this;
41
+ }
42
+ remove(target) {
43
+ const targets = domArray(target, this.win.document);
44
+ this.disable(targets);
45
+ for (const element of targets) {
46
+ element.classList.remove(config.editableDisabledClass);
47
+ }
48
+ return this;
49
+ }
50
+ disable(target) {
51
+ const targets = domArray(target || `.${config.editableClass}`, this.win.document);
52
+ for (const element of targets) {
53
+ block.disable(element);
54
+ }
55
+ return this;
56
+ }
57
+ enable(target, options) {
58
+ const opts = typeof options === 'boolean' ? { normalize: options } : (options ?? {});
59
+ const { normalize = false, plainText = false } = opts;
60
+ const shouldSpellcheck = this.config.browserSpellcheck;
61
+ const targets = domArray(target || `.${config.editableDisabledClass}`, this.win.document);
62
+ for (const element of targets) {
63
+ block.init(element, { normalize, plainText, shouldSpellcheck });
64
+ this.dispatcher.notify('init', element);
65
+ }
66
+ return this;
67
+ }
68
+ suspend(target) {
69
+ const targets = domArray(target || `.${config.editableClass}`, this.win.document);
70
+ for (const element of targets) {
71
+ element.removeAttribute('contenteditable');
72
+ }
73
+ this.dispatcher.suspend();
74
+ return this;
75
+ }
76
+ continue(target) {
77
+ const targets = domArray(target || `.${config.editableClass}`, this.win.document);
78
+ for (const element of targets) {
79
+ element.setAttribute('contenteditable', 'true');
80
+ }
81
+ this.dispatcher.continue();
82
+ return this;
83
+ }
84
+ createCursor(element, position = 'beginning') {
85
+ const host = Cursor.findHost(element, this.editableSelector);
86
+ if (!host)
87
+ return undefined;
88
+ const range = createRange(this.win);
89
+ if (position === 'beginning' || position === 'end') {
90
+ range.selectNodeContents(element);
91
+ range.collapse(position === 'beginning');
92
+ }
93
+ else if (element !== host) {
94
+ if (position === 'before') {
95
+ range.setStartBefore(element);
96
+ range.setEndBefore(element);
97
+ }
98
+ else if (position === 'after') {
99
+ range.setStartAfter(element);
100
+ range.setEndAfter(element);
101
+ }
102
+ }
103
+ else {
104
+ error('EditableJS: cannot create cursor outside of an editable block.');
105
+ }
106
+ return new Cursor(host, range);
107
+ }
108
+ createCursorAtCharacterOffset({ element, offset }) {
109
+ const textNodes = textNodesUnder(element);
110
+ const { node, relativeOffset } = getTextNodeAndRelativeOffset({ textNodes, absOffset: offset });
111
+ if (!node)
112
+ throw new Error('Could not find text node for offset');
113
+ const newRange = createRange(this.win);
114
+ newRange.setStart(node, relativeOffset);
115
+ newRange.collapse(true);
116
+ const host = Cursor.findHost(element, this.editableSelector);
117
+ if (!host)
118
+ throw new Error('No editable host found');
119
+ const nextCursor = new Cursor(host, newRange);
120
+ nextCursor.setVisibleSelection();
121
+ return nextCursor;
122
+ }
123
+ createCursorAtBeginning(element) {
124
+ return this.createCursor(element, 'beginning');
125
+ }
126
+ createCursorAtEnd(element) {
127
+ return this.createCursor(element, 'end');
128
+ }
129
+ createCursorBefore(element) {
130
+ return this.createCursor(element, 'before');
131
+ }
132
+ createCursorAfter(element) {
133
+ return this.createCursor(element, 'after');
134
+ }
135
+ getContent(element) {
136
+ return content.extractContent(element);
137
+ }
138
+ appendTo(inputElement, contentToAppend) {
139
+ const element = content.adoptElement(inputElement, this.win.document);
140
+ const cursor = this.createCursor(element, 'end');
141
+ if (!cursor)
142
+ throw new Error('Could not create cursor');
143
+ cursor.insertAfter(typeof contentToAppend === 'string'
144
+ ? content.createFragmentFromString(contentToAppend)
145
+ : contentToAppend);
146
+ return cursor;
147
+ }
148
+ prependTo(inputElement, contentToPrepend) {
149
+ const element = content.adoptElement(inputElement, this.win.document);
150
+ const cursor = this.createCursor(element, 'beginning');
151
+ if (!cursor)
152
+ throw new Error('Could not create cursor');
153
+ cursor.insertBefore(typeof contentToPrepend === 'string'
154
+ ? content.createFragmentFromString(contentToPrepend)
155
+ : contentToPrepend);
156
+ return cursor;
157
+ }
158
+ getSelection(editableHost) {
159
+ const selection = this.dispatcher.selectionWatcher.getFreshSelection();
160
+ if (!editableHost || !selection)
161
+ return selection;
162
+ const range = selection.range;
163
+ if (editableHost?.isConnected && nodeContainsRange(editableHost, range)) {
164
+ return selection;
165
+ }
166
+ return undefined;
167
+ }
168
+ setupHighlighting(hightlightingConfig) {
169
+ this.highlighting = new MonitoredHighlighting(this, hightlightingConfig, undefined);
170
+ return this;
171
+ }
172
+ setupSpellcheck(conf) {
173
+ let marker;
174
+ if (conf.markerNode) {
175
+ marker = conf.markerNode.outerHTML;
176
+ }
177
+ this.setupHighlighting({
178
+ throttle: conf.throttle,
179
+ spellcheck: {
180
+ marker: marker,
181
+ spellcheckService: conf.spellcheckService
182
+ }
183
+ });
184
+ this.spellcheck = {
185
+ checkSpelling: (elem) => {
186
+ this.highlighting?.highlight(elem);
187
+ }
188
+ };
189
+ return this;
190
+ }
191
+ highlight({ editableHost, text, highlightId, textRange, raiseEvents, type = 'comment' }) {
192
+ if (!textRange) {
193
+ const result = highlightSupport.highlightText(editableHost, text, highlightId, type, raiseEvents ? this.dispatcher : undefined, this.win);
194
+ return result || -1;
195
+ }
196
+ if (typeof textRange.start !== 'number' || typeof textRange.end !== 'number') {
197
+ error('Error in Editable.highlight: You passed a textRange object with invalid keys. Expected shape: { start: Number, end: Number }');
198
+ return -1;
199
+ }
200
+ if (textRange.start === textRange.end) {
201
+ error('Error in Editable.highlight: You passed a textRange object with equal start and end offsets, which is considered a cursor and therefore unfit to create a highlight.');
202
+ return -1;
203
+ }
204
+ return highlightSupport.highlightRange(editableHost, text, highlightId, textRange.start, textRange.end, raiseEvents ? this.dispatcher : undefined, this.win, type);
205
+ }
206
+ getHighlightPositions({ editableHost, type }) {
207
+ const result = highlightSupport.extractHighlightedRanges(editableHost, type);
208
+ if (!result)
209
+ return {};
210
+ // Convert the result to TextRange format (without nativeRange)
211
+ const textRanges = {};
212
+ for (const highlightId in result) {
213
+ const { start, end, text } = result[highlightId];
214
+ textRanges[highlightId] = { start, end, text };
215
+ }
216
+ return textRanges;
217
+ }
218
+ removeHighlight({ editableHost, highlightId, raiseEvents }) {
219
+ highlightSupport.removeHighlight(editableHost, highlightId, raiseEvents ? this.dispatcher : undefined);
220
+ }
221
+ decorateHighlight({ editableHost, highlightId, addCssClass, removeCssClass }) {
222
+ highlightSupport.updateHighlight(editableHost, highlightId, addCssClass, removeCssClass);
223
+ }
224
+ on(event, handler) {
225
+ this.dispatcher.on(event, handler);
226
+ return this;
227
+ }
228
+ off(...args) {
229
+ this.dispatcher.off.apply(this.dispatcher, args);
230
+ return this;
231
+ }
232
+ unload() {
233
+ this.dispatcher.unload();
234
+ return this;
235
+ }
236
+ findClosestCursorOffset({ element, origCoordinates, requiredOnFirstLine = false, requiredOnLastLine = false }) {
237
+ const positionX = this.dispatcher.switchContext && this.dispatcher.switchContext.positionX !== undefined
238
+ ? this.dispatcher.switchContext.positionX
239
+ : origCoordinates.left;
240
+ return binaryCursorSearch({
241
+ host: element,
242
+ requiredOnFirstLine,
243
+ requiredOnLastLine,
244
+ positionX
245
+ });
246
+ }
247
+ }
248
+ // Expose modules and editable
249
+ Editable.parser = parser;
250
+ Editable.content = content;
251
+ // Set up callback functions for several events.
252
+ const eventNames = ['focus', 'blur', 'flow', 'selection', 'cursor', 'newline',
253
+ 'insert', 'split', 'merge', 'empty', 'change', 'switch',
254
+ 'move', 'clipboard', 'paste', 'spellcheckUpdated', 'selectToBoundary'];
255
+ eventNames.forEach((name) => {
256
+ // Generate a callback function to subscribe to an event.
257
+ Editable.prototype[name] = function (handler) {
258
+ return this.on(name, handler);
259
+ };
260
+ });
261
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Editable } from './core.js';
2
+ import type Cursor from './cursor.js';
3
+ import type Selection from './selection.js';
4
+ /**
5
+ * The Behavior module defines the behavior triggered in response to the Editable.JS
6
+ * events (see {{#crossLink "Editable"}}{{/crossLink}}).
7
+ * The behavior can be overwritten by a user with Editable.init() or on
8
+ * Editable.add() per element.
9
+ *
10
+ * @module core
11
+ * @submodule behavior
12
+ */
13
+ export default function createDefaultBehavior(editable: Editable): {
14
+ /** @param {HTMLElement} element */
15
+ focus(element: HTMLElement): void;
16
+ blur(element: HTMLElement): void;
17
+ selection(element: HTMLElement, selection: Selection): void;
18
+ cursor(element: HTMLElement, cursor: Cursor): void;
19
+ newline(element: HTMLElement, cursor: Cursor): void;
20
+ insert(element: HTMLElement, direction: string, cursor: Cursor): void;
21
+ split(element: HTMLElement, before: string, after: string, cursor: Cursor): void;
22
+ merge(element: HTMLElement, direction: string, cursor: Cursor): void;
23
+ empty(element: HTMLElement): void;
24
+ switch(element: HTMLElement, direction: string, cursor: Cursor): void;
25
+ move(element: HTMLElement, selection: Selection, direction: string): void;
26
+ paste(element: HTMLElement, blocks: string[], cursor: Cursor): void;
27
+ clipboard(element: HTMLElement, action: string, cursor: Cursor): void;
28
+ toggleBold(selection: Selection): void;
29
+ toggleEmphasis(selection: Selection): void;
30
+ };
31
+ //# sourceMappingURL=create-default-behavior.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-default-behavior.d.ts","sourceRoot":"","sources":["../src/create-default-behavior.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C;;;;;;;;GAQG;AAEH,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAE,QAAQ,EAAE,QAAQ;IAU7D,mCAAmC;mBACnB,WAAW,GAAG,IAAI;kBASnB,WAAW,GAAG,IAAI;uBAWb,WAAW,aAAa,SAAS,GAAG,IAAI;oBAI3C,WAAW,UAAU,MAAM,GAAG,IAAI;qBAIjC,WAAW,UAAU,MAAM,GAAG,IAAI;oBAuBnC,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;mBAatD,WAAW,UAAU,MAAM,SAAS,MAAM,UAAU,MAAM,GAAG,IAAI;mBAiBjE,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;mBAgCrD,WAAW,GAAG,IAAI;oBAIjB,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;kBAmBvD,WAAW,aAAa,SAAS,aAAa,MAAM,GAAG,IAAI;mBAI1D,WAAW,UAAU,MAAM,EAAE,UAAU,MAAM,GAAG,IAAI;uBA0BhD,WAAW,UAAU,MAAM,UAAU,MAAM,GAAG,IAAI;0BAI/C,SAAS,GAAG,IAAI;8BAIZ,SAAS,GAAG,IAAI;EAI9C"}
@@ -0,0 +1,178 @@
1
+ import * as parser from './parser.js';
2
+ import * as content from './content.js';
3
+ import log from './util/log.js';
4
+ import * as nodeType from './node-type.js';
5
+ /**
6
+ * The Behavior module defines the behavior triggered in response to the Editable.JS
7
+ * events (see {{#crossLink "Editable"}}{{/crossLink}}).
8
+ * The behavior can be overwritten by a user with Editable.init() or on
9
+ * Editable.add() per element.
10
+ *
11
+ * @module core
12
+ * @submodule behavior
13
+ */
14
+ export default function createDefaultBehavior(editable) {
15
+ const document = editable.win.document;
16
+ /**
17
+ * Factory for the default behavior.
18
+ * Provides default behavior of the Editable.JS API.
19
+ *
20
+ * @static
21
+ */
22
+ return {
23
+ /** @param {HTMLElement} element */
24
+ focus(element) {
25
+ if (!parser.isVoid(element))
26
+ return;
27
+ // Add an zero width space if the editable is empty to force it to have a height
28
+ // E.g. Firefox does not render empty block elements
29
+ // and most browsers do not render empty inline elements.
30
+ element.appendChild(document.createTextNode('\uFEFF'));
31
+ },
32
+ blur(element) {
33
+ // Note: there is a special case when the tab is changed where
34
+ // we can get a blur event even if the cursor is still in the editable.
35
+ // This blur would cause us to loose the cursor position (cause of cleanInternals()).
36
+ // To prevent this we check if the activeElement is still the editable.
37
+ // (Note: document.getSelection() did not work reliably in this case.)
38
+ if (document.activeElement === element)
39
+ return;
40
+ content.cleanInternals(element);
41
+ },
42
+ selection(element, selection) {
43
+ log(selection ? 'Default selection behavior' : 'Default selection empty behavior');
44
+ },
45
+ cursor(element, cursor) {
46
+ log('Default cursor behavior');
47
+ },
48
+ newline(element, cursor) {
49
+ // When the cursor is at the text end, we'll need to add an empty text node
50
+ // after the br tag to ensure that the cursor shows up on the next line
51
+ if (cursor.isAtTextEnd()) {
52
+ const br = document.createElement('br');
53
+ cursor.insertBefore(br);
54
+ // Only append a zero width space if there's none after the br tag
55
+ // We don't need to remove them as they get cleaned up on blur
56
+ const nextSibling = br.nextSibling;
57
+ if (nextSibling?.nodeType !== nodeType.textNode ||
58
+ nextSibling.textContent?.[0] !== '\uFEFF') {
59
+ cursor.insertAfter(document.createTextNode('\uFEFF'));
60
+ }
61
+ }
62
+ else {
63
+ cursor.insertBefore(document.createElement('br'));
64
+ }
65
+ cursor.setVisibleSelection();
66
+ },
67
+ insert(element, direction, cursor) {
68
+ const newElement = element.cloneNode(false);
69
+ if (newElement.id)
70
+ newElement.removeAttribute('id');
71
+ if (direction === 'before') {
72
+ element.parentNode?.insertBefore(newElement, element);
73
+ }
74
+ else {
75
+ element.parentNode?.insertBefore(newElement, element.nextSibling);
76
+ }
77
+ editable.createCursorAtEnd(newElement)?.setVisibleSelection();
78
+ },
79
+ split(element, before, after, cursor) {
80
+ const fragment = content.createFragmentFromString(before);
81
+ const newNode = element.cloneNode(false);
82
+ newNode.appendChild(fragment);
83
+ const parent = element.parentNode;
84
+ if (parent) {
85
+ parent.insertBefore(newNode, element);
86
+ }
87
+ element.innerHTML = after;
88
+ content.tidyHtml(newNode);
89
+ content.tidyHtml(element);
90
+ cursor.setVisibleSelection();
91
+ },
92
+ merge(element, direction, cursor) {
93
+ const target = direction === 'before'
94
+ ? element.previousElementSibling
95
+ : element.nextElementSibling;
96
+ if (!target)
97
+ return;
98
+ const targetContent = content.extractContent(target, false);
99
+ const elementContent = content.extractContent(element, false);
100
+ // Calculate text lengths before merging to position cursor correctly
101
+ const tempDiv = document.createElement('div');
102
+ tempDiv.innerHTML = targetContent;
103
+ const targetTextLength = tempDiv.textContent?.length || 0;
104
+ tempDiv.innerHTML = elementContent;
105
+ const elementTextLength = tempDiv.textContent?.length || 0;
106
+ const mergedContent = direction === 'before'
107
+ ? targetContent + elementContent
108
+ : elementContent + targetContent;
109
+ element.innerHTML = mergedContent;
110
+ target.remove();
111
+ // Position cursor at the merge boundary
112
+ const cursorOffset = direction === 'before'
113
+ ? targetTextLength
114
+ : elementTextLength;
115
+ editable.createCursorAtCharacterOffset({ element, offset: cursorOffset });
116
+ },
117
+ empty(element) {
118
+ log('Default empty behavior');
119
+ },
120
+ switch(element, direction, cursor) {
121
+ switch (direction) {
122
+ case 'before':
123
+ const prevSibling = element.previousElementSibling;
124
+ if (prevSibling) {
125
+ const prevCursor = editable.createCursorAtEnd(prevSibling);
126
+ if (prevCursor)
127
+ prevCursor.setVisibleSelection();
128
+ }
129
+ break;
130
+ case 'after':
131
+ const nextSibling = element.nextElementSibling;
132
+ if (nextSibling) {
133
+ const nextCursor = editable.createCursorAtBeginning(nextSibling);
134
+ if (nextCursor)
135
+ nextCursor.setVisibleSelection();
136
+ }
137
+ break;
138
+ }
139
+ },
140
+ move(element, selection, direction) {
141
+ log('Default move behavior');
142
+ },
143
+ paste(element, blocks, cursor) {
144
+ cursor.insertBefore(blocks[0]);
145
+ if (blocks.length <= 1) {
146
+ cursor.setVisibleSelection();
147
+ return;
148
+ }
149
+ const parent = element.parentNode;
150
+ if (!parent)
151
+ return;
152
+ let currentElement = element;
153
+ blocks.slice(1).forEach((str) => {
154
+ const newElement = element.cloneNode(false);
155
+ if (newElement.id)
156
+ newElement.removeAttribute('id');
157
+ const fragment = content.createFragmentFromString(str);
158
+ newElement.appendChild(fragment);
159
+ parent.insertBefore(newElement, currentElement.nextSibling);
160
+ currentElement = newElement;
161
+ });
162
+ // focus last element
163
+ const lastCursor = editable.createCursorAtEnd(currentElement);
164
+ if (lastCursor)
165
+ lastCursor.setVisibleSelection();
166
+ },
167
+ clipboard(element, action, cursor) {
168
+ log('Default clipboard behavior');
169
+ },
170
+ toggleBold(selection) {
171
+ selection.toggleBold();
172
+ },
173
+ toggleEmphasis(selection) {
174
+ selection.toggleEmphasis();
175
+ }
176
+ };
177
+ }
178
+ //# sourceMappingURL=create-default-behavior.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-default-behavior.js","sourceRoot":"","sources":["../src/create-default-behavior.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import type { Editable } from './core.js';
2
+ import type Cursor from './cursor.js';
3
+ import type Selection from './selection.js';
4
+ export default function createDefaultEvents(editable: Editable): {
5
+ /**
6
+ * The focus event is triggered when an element gains focus.
7
+ * The default behavior is to... TODO
8
+ *
9
+ * @event focus
10
+ * @param {HTMLElement} element The element triggering the event.
11
+ */
12
+ focus(element: HTMLElement): void;
13
+ /**
14
+ * The blur event is triggered when an element looses focus.
15
+ * The default behavior is to... TODO
16
+ *
17
+ * @event blur
18
+ * @param {HTMLElement} element The element triggering the event.
19
+ */
20
+ blur(element: HTMLElement): void;
21
+ /**
22
+ * The selection event is triggered after the user has selected some
23
+ * content.
24
+ * The default behavior is to... TODO
25
+ *
26
+ * @event selection
27
+ * @param {HTMLElement} element The element triggering the event.
28
+ * @param {Selection} selection The actual Selection object.
29
+ */
30
+ selection(element: HTMLElement, selection: Selection): void;
31
+ /**
32
+ * The cursor event is triggered after cursor position has changed.
33
+ * The default behavior is to... TODO
34
+ *
35
+ * @event cursor
36
+ * @param {HTMLElement} element The element triggering the event.
37
+ * @param {Cursor} cursor The actual Cursor object.
38
+ */
39
+ cursor(element: HTMLElement, cursor: Cursor): void;
40
+ /**
41
+ * The newline event is triggered when a newline should be inserted. This
42
+ * happens when SHIFT+ENTER key is pressed.
43
+ * The default behavior is to add a <br />
44
+ *
45
+ * @event newline
46
+ * @param {HTMLElement} element The element triggering the event.
47
+ * @param {Cursor} cursor The actual cursor object.
48
+ */
49
+ newline(element: HTMLElement, cursor: Cursor): void;
50
+ /**
51
+ * The split event is triggered when a block should be split into two
52
+ * blocks. This happens when ENTER is pressed within a non-empty block.
53
+ * The default behavior is to... TODO
54
+ *
55
+ * @event split
56
+ * @param {HTMLElement} element The element triggering the event.
57
+ * @param {String} before The HTML string before the split.
58
+ * @param {String} after The HTML string after the split.
59
+ * @param {Cursor} cursor The actual cursor object.
60
+ */
61
+ split(element: HTMLElement, before: string, after: string, cursor: Cursor): void;
62
+ /**
63
+ * The insert event is triggered when a new block should be inserted. This
64
+ * happens when ENTER key is pressed at the beginning of a block (should
65
+ * insert before) or at the end of a block (should insert after).
66
+ * The default behavior is to... TODO
67
+ *
68
+ * @event insert
69
+ * @param {HTMLElement} element The element triggering the event.
70
+ * @param {String} direction The insert direction: "before" or "after".
71
+ * @param {Cursor} cursor The actual cursor object.
72
+ */
73
+ insert(element: HTMLElement, direction: string, cursor: Cursor): void;
74
+ /**
75
+ * The merge event is triggered when two needs to be merged. This happens
76
+ * when BACKSPACE is pressed at the beginning of a block (should merge with
77
+ * the preceding block) or DEL is pressed at the end of a block (should
78
+ * merge with the following block).
79
+ * The default behavior is to... TODO
80
+ *
81
+ * @event merge
82
+ * @param {HTMLElement} element The element triggering the event.
83
+ * @param {String} direction The merge direction: "before" or "after".
84
+ * @param {Cursor} cursor The actual cursor object.
85
+ */
86
+ merge(element: HTMLElement, direction: string, cursor: Cursor): void;
87
+ /**
88
+ * The empty event is triggered when a block is emptied.
89
+ * The default behavior is to... TODO
90
+ *
91
+ * @event empty
92
+ * @param {HTMLElement} element The element triggering the event.
93
+ */
94
+ empty(element: HTMLElement): void;
95
+ /**
96
+ * The switch event is triggered when the user switches to another block.
97
+ * This happens when an ARROW key is pressed near the boundaries of a block.
98
+ * The default behavior is to... TODO
99
+ *
100
+ * @event switch
101
+ * @param {HTMLElement} element The element triggering the event.
102
+ * @param {String} direction The switch direction: "before" or "after".
103
+ * @param {Cursor} cursor The actual cursor object.*
104
+ */
105
+ switch(element: HTMLElement, direction: string, cursor: Cursor): void;
106
+ /**
107
+ * The move event is triggered when the user moves a selection in a block.
108
+ * This happens when the user selects some (or all) content in a block and
109
+ * an ARROW key is pressed (up: drag before, down: drag after).
110
+ * The default behavior is to... TODO
111
+ *
112
+ * @event move
113
+ * @param {HTMLElement} element The element triggering the event.
114
+ * @param {Selection} selection The actual Selection object.
115
+ * @param {String} direction The move direction: "before" or "after".
116
+ */
117
+ move(element: HTMLElement, selection: Selection, direction: string): void;
118
+ /**
119
+ * The clipboard event is triggered when the user copies or cuts
120
+ * a selection within a block.
121
+ *
122
+ * @event clipboard
123
+ * @param {HTMLElement} element The element triggering the event.
124
+ * @param {String} action The clipboard action: "copy" or "cut".
125
+ * @param {Selection} selection A selection object around the copied content.
126
+ */
127
+ clipboard(element: HTMLElement, action: string, selection: Selection): void;
128
+ /**
129
+ * The paste event is triggered when the user pastes text
130
+ *
131
+ * @event paste
132
+ * @param {HTMLElement} The element triggering the event.
133
+ * @param {Array of String} The pasted blocks
134
+ * @param {Cursor} The cursor object.
135
+ */
136
+ paste(element: HTMLElement, blocks: string[], cursor: Cursor): void;
137
+ /**
138
+ * The toggleBold event is triggered when the bold keyboard shortcut is used
139
+ *
140
+ * @event toggleBold
141
+ * @param {Selection} The selection object.
142
+ */
143
+ toggleBold(selection: Selection): void;
144
+ /**
145
+ * The toggleEmphasis event is triggered when the italic keyboard shortcut is used
146
+ *
147
+ * @event toggleEmphasis
148
+ * @param {Selection} The selection object.
149
+ */
150
+ toggleEmphasis(selection: Selection): void;
151
+ };
152
+ //# sourceMappingURL=create-default-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-default-events.d.ts","sourceRoot":"","sources":["../src/create-default-events.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAE3C,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAE,QAAQ,EAAE,QAAQ;IAI3D;;;;;;OAMG;mBACa,WAAW,GAAG,IAAI;IAIlC;;;;;;OAMG;kBACY,WAAW,GAAG,IAAI;IAIjC;;;;;;;;OAQG;uBACiB,WAAW,aAAa,SAAS,GAAG,IAAI;IAI5D;;;;;;;OAOG;oBACc,WAAW,UAAU,MAAM,GAAG,IAAI;IAInD;;;;;;;;OAQG;qBACe,WAAW,UAAU,MAAM,GAAG,IAAI;IAIpD;;;;;;;;;;OAUG;mBACa,WAAW,UAAU,MAAM,SAAS,MAAM,UAAU,MAAM,GAAG,IAAI;IAIjF;;;;;;;;;;OAUG;oBACc,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;IAItE;;;;;;;;;;;OAWG;mBACa,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;IAIrE;;;;;;OAMG;mBACa,WAAW,GAAG,IAAI;IAIlC;;;;;;;;;OASG;oBACc,WAAW,aAAa,MAAM,UAAU,MAAM,GAAG,IAAI;IAItE;;;;;;;;;;OAUG;kBACY,WAAW,aAAa,SAAS,aAAa,MAAM,GAAG,IAAI;IAI1E;;;;;;;;OAQG;uBACiB,WAAW,UAAU,MAAM,aAAa,SAAS,GAAG,IAAI;IAI5E;;;;;;;OAOG;mBACa,WAAW,UAAU,MAAM,EAAE,UAAU,MAAM,GAAG,IAAI;IAIpE;;;;;OAKG;0BACoB,SAAS,GAAG,IAAI;IAIvC;;;;;OAKG;8BACwB,SAAS,GAAG,IAAI;EAI9C"}