@atlaskit/editor-plugin-placeholder 6.5.4 → 6.6.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 (47) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/placeholderPlugin.js +19 -568
  3. package/dist/cjs/pm-plugins/adf-builders.js +30 -0
  4. package/dist/cjs/pm-plugins/animation.js +58 -0
  5. package/dist/cjs/pm-plugins/constants.js +18 -0
  6. package/dist/cjs/pm-plugins/decorations.js +96 -0
  7. package/dist/cjs/pm-plugins/main.js +168 -0
  8. package/dist/cjs/pm-plugins/placeholderPluginLegacy.js +617 -0
  9. package/dist/cjs/pm-plugins/types.js +5 -0
  10. package/dist/cjs/pm-plugins/utils.js +243 -0
  11. package/dist/es2019/placeholderPlugin.js +8 -548
  12. package/dist/es2019/pm-plugins/adf-builders.js +22 -0
  13. package/dist/es2019/pm-plugins/animation.js +49 -0
  14. package/dist/es2019/pm-plugins/constants.js +12 -0
  15. package/dist/es2019/pm-plugins/decorations.js +87 -0
  16. package/dist/es2019/pm-plugins/main.js +162 -0
  17. package/dist/es2019/pm-plugins/placeholderPluginLegacy.js +598 -0
  18. package/dist/es2019/pm-plugins/types.js +1 -0
  19. package/dist/es2019/pm-plugins/utils.js +234 -0
  20. package/dist/esm/placeholderPlugin.js +17 -563
  21. package/dist/esm/pm-plugins/adf-builders.js +24 -0
  22. package/dist/esm/pm-plugins/animation.js +52 -0
  23. package/dist/esm/pm-plugins/constants.js +12 -0
  24. package/dist/esm/pm-plugins/decorations.js +90 -0
  25. package/dist/esm/pm-plugins/main.js +162 -0
  26. package/dist/esm/pm-plugins/placeholderPluginLegacy.js +607 -0
  27. package/dist/esm/pm-plugins/types.js +1 -0
  28. package/dist/esm/pm-plugins/utils.js +232 -0
  29. package/dist/types/placeholderPlugin.d.ts +0 -8
  30. package/dist/types/pm-plugins/adf-builders.d.ts +4 -0
  31. package/dist/types/pm-plugins/animation.d.ts +1 -0
  32. package/dist/types/pm-plugins/constants.d.ts +9 -0
  33. package/dist/types/pm-plugins/decorations.d.ts +4 -0
  34. package/dist/types/pm-plugins/main.d.ts +6 -0
  35. package/dist/types/pm-plugins/placeholderPluginLegacy.d.ts +13 -0
  36. package/dist/types/pm-plugins/types.d.ts +37 -0
  37. package/dist/types/pm-plugins/utils.d.ts +27 -0
  38. package/dist/types-ts4.5/placeholderPlugin.d.ts +0 -8
  39. package/dist/types-ts4.5/pm-plugins/adf-builders.d.ts +4 -0
  40. package/dist/types-ts4.5/pm-plugins/animation.d.ts +1 -0
  41. package/dist/types-ts4.5/pm-plugins/constants.d.ts +9 -0
  42. package/dist/types-ts4.5/pm-plugins/decorations.d.ts +4 -0
  43. package/dist/types-ts4.5/pm-plugins/main.d.ts +6 -0
  44. package/dist/types-ts4.5/pm-plugins/placeholderPluginLegacy.d.ts +13 -0
  45. package/dist/types-ts4.5/pm-plugins/types.d.ts +37 -0
  46. package/dist/types-ts4.5/pm-plugins/utils.d.ts +27 -0
  47. package/package.json +6 -9
@@ -1,572 +1,26 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- function ownKeys(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; }
3
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
- import { code, text } from '@atlaskit/adf-utils/builders';
5
- import { placeholderTextMessages as messages } from '@atlaskit/editor-common/messages';
6
- import { processRawValue } from '@atlaskit/editor-common/process-raw-value';
7
- import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
8
- import { bracketTyped, browser, hasDocAsParent, isEmptyDocument, isEmptyParagraph } from '@atlaskit/editor-common/utils';
9
- import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
10
1
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
11
- import { findParentNode } from '@atlaskit/editor-prosemirror/utils';
12
- import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
13
2
  import { fg } from '@atlaskit/platform-feature-flags';
14
- import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
15
- // Typewriter animation timing constants
16
- var TYPEWRITER_TYPE_DELAY = 50; // Delay between typing each character
17
- var TYPEWRITER_PAUSE_BEFORE_ERASE = 2000; // Pause before starting to erase text
18
- var TYPEWRITER_ERASE_DELAY = 40; // Delay between erasing each character
19
- var TYPEWRITER_CYCLE_DELAY = 500; // Delay before starting next cycle
20
- var TYPEWRITER_TYPED_AND_DELETED_DELAY = 1500; // Delay before starting animation after user typed and deleted
21
-
3
+ import createPlugin from './pm-plugins/main';
4
+ import { placeholderPluginLegacy } from './pm-plugins/placeholderPluginLegacy';
22
5
  export var EMPTY_PARAGRAPH_TIMEOUT_DELAY = 2000; // Delay before showing placeholder on empty paragraph
23
6
 
24
7
  export var pluginKey = new PluginKey('placeholderPlugin');
25
- var placeholderTestId = 'placeholder-test-id';
26
- function getPlaceholderState(editorState) {
27
- return pluginKey.getState(editorState);
28
- }
29
- var nodeTypesWithLongPlaceholderText = ['expand', 'panel'];
30
- var nodeTypesWithShortPlaceholderText = ['tableCell', 'tableHeader'];
31
- var nodeTypesWithSyncBlockPlaceholderText = ['bodiedSyncBlock'];
32
- var createShortEmptyNodePlaceholderADF = function createShortEmptyNodePlaceholderADF(_ref) {
33
- var formatMessage = _ref.formatMessage;
34
- return {
35
- version: 1,
36
- type: 'doc',
37
- content: [{
38
- type: 'paragraph',
39
- content: [code(formatMessage(messages.shortEmptyNodePlaceholderADFSlashShortcut)), text(' '), text(formatMessage(messages.shortEmptyNodePlaceholderADFSuffix))]
40
- }]
41
- };
42
- };
43
- var createLongEmptyNodePlaceholderADF = function createLongEmptyNodePlaceholderADF(_ref2) {
44
- var formatMessage = _ref2.formatMessage;
45
- return {
46
- version: 1,
47
- type: 'doc',
48
- content: [{
49
- type: 'paragraph',
50
- content: [text(formatMessage(messages.longEmptyNodePlaceholderADFPrefix)), text(' '), code(formatMessage(messages.longEmptyNodePlaceholderADFSlashShortcut)), text(' '), text(formatMessage(messages.longEmptyNodePlaceholderADFSuffix))]
51
- }]
52
- };
53
- };
54
- var cycleThroughPlaceholderPrompts = function cycleThroughPlaceholderPrompts(placeholderPrompts, activeTypewriterTimeouts, placeholderNodeWithText) {
55
- var initialDelayWhenUserTypedAndDeleted = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
56
- var currentPromptIndex = 0;
57
- var displayedText = '';
58
- var animationTimeouts = [];
59
- var clearAllTimeouts = function clearAllTimeouts() {
60
- animationTimeouts.forEach(function (timeoutId) {
61
- return clearTimeout(timeoutId);
62
- });
63
- animationTimeouts = [];
64
- };
65
- var scheduleTimeout = function scheduleTimeout(callback, delay) {
66
- var timeoutId = setTimeout(callback, delay);
67
- animationTimeouts.push(timeoutId);
68
- return timeoutId;
69
- };
70
- var _startAnimationCycle = function startAnimationCycle() {
71
- var currentPrompt = placeholderPrompts[currentPromptIndex];
72
- var characterIndex = 0;
73
- var _typeNextCharacter = function typeNextCharacter() {
74
- if (characterIndex < currentPrompt.length) {
75
- displayedText = currentPrompt.substring(0, characterIndex + 1);
76
- placeholderNodeWithText.textContent = displayedText;
77
- characterIndex++;
78
- scheduleTimeout(_typeNextCharacter, TYPEWRITER_TYPE_DELAY);
79
- } else {
80
- scheduleTimeout(_eraseLastCharacter, TYPEWRITER_PAUSE_BEFORE_ERASE);
81
- }
82
- };
83
- var _eraseLastCharacter = function eraseLastCharacter() {
84
- if (displayedText.length > 1) {
85
- displayedText = displayedText.substring(0, displayedText.length - 1);
86
- placeholderNodeWithText.textContent = displayedText;
87
- scheduleTimeout(_eraseLastCharacter, TYPEWRITER_ERASE_DELAY);
88
- } else {
89
- displayedText = ' ';
90
- placeholderNodeWithText.textContent = displayedText;
91
- currentPromptIndex = (currentPromptIndex + 1) % placeholderPrompts.length;
92
- scheduleTimeout(_startAnimationCycle, TYPEWRITER_CYCLE_DELAY);
93
- }
94
- };
95
- _typeNextCharacter();
96
- };
97
- activeTypewriterTimeouts === null || activeTypewriterTimeouts === void 0 || activeTypewriterTimeouts.push(clearAllTimeouts);
98
- if (initialDelayWhenUserTypedAndDeleted > 0) {
99
- placeholderNodeWithText.textContent = ' ';
100
- scheduleTimeout(_startAnimationCycle, initialDelayWhenUserTypedAndDeleted);
101
- } else {
102
- _startAnimationCycle();
103
- }
104
- };
105
- export function createPlaceholderDecoration(editorState, placeholderText, placeholderPrompts, activeTypewriterTimeouts) {
106
- var pos = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
107
- var initialDelayWhenUserTypedAndDeleted = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
108
- var placeholderADF = arguments.length > 6 ? arguments[6] : undefined;
109
- var placeholderDecoration = document.createElement('span');
110
- var placeholderNodeWithText = placeholderDecoration;
111
- placeholderDecoration.setAttribute('data-testid', placeholderTestId);
112
- placeholderDecoration.className = 'placeholder-decoration';
113
- placeholderDecoration.setAttribute('aria-hidden', 'true');
114
-
115
- // PM sets contenteditable to false on Decorations so Firefox doesn't display the flashing cursor
116
- // So adding an extra span which will contain the placeholder text
117
- if (browser.gecko) {
118
- var placeholderNode = document.createElement('span');
119
- placeholderNode.setAttribute('contenteditable', 'true'); // explicitly overriding the default Decoration behaviour
120
- placeholderDecoration.appendChild(placeholderNode);
121
- placeholderNodeWithText = placeholderNode;
122
- }
123
- if (placeholderText) {
124
- placeholderNodeWithText.textContent = placeholderText || ' ';
125
- } else if (placeholderADF) {
126
- var serializer = DOMSerializer.fromSchema(editorState.schema);
127
- // Get a PMNode from docnode
128
- var docNode = processRawValue(editorState.schema, placeholderADF);
129
- if (docNode) {
130
- // Extract only the inline content from paragraphs, avoiding block-level elements
131
- // that can interfere with cursor rendering
132
- docNode.children.forEach(function (node) {
133
- // For paragraph nodes, serialize their content (inline elements) directly
134
- // without the wrapping <p> tag
135
- if (node.type.name === 'paragraph') {
136
- node.content.forEach(function (inlineNode) {
137
- var inlineDOM = serializer.serializeNode(inlineNode);
138
- placeholderNodeWithText.append(inlineDOM);
139
- });
140
- } else {
141
- // For non-paragraph nodes, serialize normally
142
- var nodeDOM = serializer.serializeNode(node);
143
- placeholderNodeWithText.append(nodeDOM);
144
- }
145
- });
146
- var markElements = placeholderNodeWithText.querySelectorAll('[data-prosemirror-content-type="mark"]');
147
- markElements.forEach(function (markEl) {
148
- if (markEl instanceof HTMLElement) {
149
- markEl.style.setProperty('color', "var(--ds-text-subtlest, #6B6E76)");
150
- }
151
- });
152
- // Ensure all child elements don't block pointer events or cursor
153
- var allElements = placeholderNodeWithText.querySelectorAll('*');
154
- allElements.forEach(function (el) {
155
- if (el instanceof HTMLElement) {
156
- el.style.pointerEvents = 'none';
157
- el.style.userSelect = 'none';
158
- }
159
- });
160
- }
161
- } else if (placeholderPrompts) {
162
- cycleThroughPlaceholderPrompts(placeholderPrompts, activeTypewriterTimeouts, placeholderNodeWithText, initialDelayWhenUserTypedAndDeleted);
163
- }
164
-
165
- // ME-2289 Tapping on backspace in empty editor hides and displays the keyboard
166
- // Add a editable buff node as the cursor moving forward is inevitable
167
- // when backspace in GBoard composition
168
- if (browser.android && browser.chrome) {
169
- var buffNode = document.createElement('span');
170
- buffNode.setAttribute('class', 'placeholder-android');
171
- buffNode.setAttribute('contenteditable', 'true');
172
- buffNode.textContent = ' ';
173
- placeholderDecoration.appendChild(buffNode);
174
- }
175
- var isTargetNested = editorState.doc.resolve(pos).depth > 1;
176
-
177
- // only truncate text for nested nodes, otherwise applying 'overflow: hidden;' to top level nodes
178
- // creates issues with quick insert button
179
- if (isTargetNested && editorExperiment('platform_editor_controls', 'variant1')) {
180
- placeholderDecoration.classList.add('placeholder-decoration-hide-overflow');
181
- }
182
- return DecorationSet.create(editorState.doc, [Decoration.widget(pos, placeholderDecoration, {
183
- side: 0,
184
- key: "placeholder ".concat(placeholderText)
185
- })]);
186
- }
187
- function setPlaceHolderState(_ref3) {
188
- var placeholderText = _ref3.placeholderText,
189
- pos = _ref3.pos,
190
- placeholderPrompts = _ref3.placeholderPrompts,
191
- typedAndDeleted = _ref3.typedAndDeleted,
192
- userHadTyped = _ref3.userHadTyped,
193
- canShowOnEmptyParagraph = _ref3.canShowOnEmptyParagraph,
194
- showOnEmptyParagraph = _ref3.showOnEmptyParagraph,
195
- contextPlaceholderADF = _ref3.contextPlaceholderADF;
196
- return {
197
- hasPlaceholder: true,
198
- placeholderText: placeholderText,
199
- placeholderPrompts: placeholderPrompts,
200
- contextPlaceholderADF: contextPlaceholderADF,
201
- pos: pos ? pos : 1,
202
- typedAndDeleted: typedAndDeleted,
203
- userHadTyped: userHadTyped,
204
- canShowOnEmptyParagraph: canShowOnEmptyParagraph,
205
- showOnEmptyParagraph: showOnEmptyParagraph
206
- };
207
- }
208
- var emptyPlaceholder = function emptyPlaceholder(_ref4) {
209
- var placeholderText = _ref4.placeholderText,
210
- placeholderPrompts = _ref4.placeholderPrompts,
211
- userHadTyped = _ref4.userHadTyped,
212
- pos = _ref4.pos,
213
- canShowOnEmptyParagraph = _ref4.canShowOnEmptyParagraph,
214
- showOnEmptyParagraph = _ref4.showOnEmptyParagraph;
215
- return {
216
- hasPlaceholder: false,
217
- placeholderText: placeholderText,
218
- placeholderPrompts: placeholderPrompts,
219
- userHadTyped: userHadTyped,
220
- typedAndDeleted: false,
221
- canShowOnEmptyParagraph: canShowOnEmptyParagraph,
222
- showOnEmptyParagraph: showOnEmptyParagraph,
223
- pos: pos
224
- };
225
- };
226
- function createPlaceHolderStateFrom(_ref5) {
227
- var isInitial = _ref5.isInitial,
228
- isEditorFocused = _ref5.isEditorFocused,
229
- editorState = _ref5.editorState,
230
- isTypeAheadOpen = _ref5.isTypeAheadOpen,
231
- defaultPlaceholderText = _ref5.defaultPlaceholderText,
232
- intl = _ref5.intl,
233
- bracketPlaceholderText = _ref5.bracketPlaceholderText,
234
- emptyLinePlaceholder = _ref5.emptyLinePlaceholder,
235
- placeholderADF = _ref5.placeholderADF,
236
- placeholderPrompts = _ref5.placeholderPrompts,
237
- typedAndDeleted = _ref5.typedAndDeleted,
238
- userHadTyped = _ref5.userHadTyped,
239
- isPlaceholderHidden = _ref5.isPlaceholderHidden,
240
- withEmptyParagraph = _ref5.withEmptyParagraph,
241
- showOnEmptyParagraph = _ref5.showOnEmptyParagraph;
242
- if (isPlaceholderHidden && fg('platform_editor_ai_aifc_patch_beta')) {
243
- return _objectSpread(_objectSpread({}, emptyPlaceholder({
244
- placeholderText: defaultPlaceholderText,
245
- placeholderPrompts: placeholderPrompts,
246
- userHadTyped: userHadTyped
247
- })), {}, {
248
- isPlaceholderHidden: isPlaceholderHidden
249
- });
250
- }
251
- if (isTypeAheadOpen !== null && isTypeAheadOpen !== void 0 && isTypeAheadOpen(editorState)) {
252
- return emptyPlaceholder({
253
- placeholderText: defaultPlaceholderText,
254
- placeholderPrompts: placeholderPrompts,
255
- userHadTyped: userHadTyped
256
- });
257
- }
258
- if ((defaultPlaceholderText || placeholderPrompts || placeholderADF) && isEmptyDocument(editorState.doc)) {
259
- return setPlaceHolderState({
260
- placeholderText: defaultPlaceholderText,
261
- pos: 1,
262
- placeholderPrompts: placeholderPrompts,
263
- typedAndDeleted: typedAndDeleted,
264
- userHadTyped: userHadTyped
265
- });
266
- }
267
- if (fg('platform_editor_ai_aifc_patch_beta_2') || fg('platform_editor_ai_aifc_patch_ga')) {
268
- var _editorState$selectio = editorState.selection,
269
- from = _editorState$selectio.from,
270
- to = _editorState$selectio.to,
271
- $to = _editorState$selectio.$to;
272
- if ((defaultPlaceholderText || placeholderADF) && withEmptyParagraph && isEditorFocused && !isInitial && !isEmptyDocument(editorState.doc) && from === to && isEmptyParagraph($to.parent) && hasDocAsParent($to)) {
273
- return showOnEmptyParagraph ? setPlaceHolderState({
274
- placeholderText: defaultPlaceholderText,
275
- pos: to,
276
- placeholderPrompts: placeholderPrompts,
277
- typedAndDeleted: typedAndDeleted,
278
- userHadTyped: userHadTyped,
279
- canShowOnEmptyParagraph: true,
280
- showOnEmptyParagraph: true
281
- }) : emptyPlaceholder({
282
- placeholderText: defaultPlaceholderText,
283
- placeholderPrompts: placeholderPrompts,
284
- userHadTyped: userHadTyped,
285
- canShowOnEmptyParagraph: true,
286
- showOnEmptyParagraph: false,
287
- pos: to
288
- });
289
- }
290
- }
291
- if (isEditorFocused && editorExperiment('platform_editor_controls', 'variant1')) {
292
- var _parentNode$firstChil, _parentNode$firstChil2;
293
- var _editorState$selectio2 = editorState.selection,
294
- $from = _editorState$selectio2.$from,
295
- _$to = _editorState$selectio2.$to;
296
- if ($from.pos !== _$to.pos) {
297
- return emptyPlaceholder({
298
- placeholderText: defaultPlaceholderText,
299
- placeholderPrompts: placeholderPrompts,
300
- userHadTyped: userHadTyped
301
- });
302
- }
303
- var parentNode = $from.node($from.depth - 1);
304
- var parentType = parentNode === null || parentNode === void 0 ? void 0 : parentNode.type.name;
305
- if (emptyLinePlaceholder && parentType === 'doc') {
306
- var isEmptyLine = isEmptyParagraph($from.parent);
307
- if (isEmptyLine) {
308
- return setPlaceHolderState({
309
- placeholderText: emptyLinePlaceholder,
310
- pos: $from.pos,
311
- placeholderPrompts: placeholderPrompts,
312
- typedAndDeleted: typedAndDeleted,
313
- userHadTyped: userHadTyped
314
- });
315
- }
316
- }
317
- var isEmptyNode = (parentNode === null || parentNode === void 0 ? void 0 : parentNode.childCount) === 1 && ((_parentNode$firstChil = parentNode.firstChild) === null || _parentNode$firstChil === void 0 ? void 0 : _parentNode$firstChil.content.size) === 0 && ((_parentNode$firstChil2 = parentNode.firstChild) === null || _parentNode$firstChil2 === void 0 ? void 0 : _parentNode$firstChil2.type.name) === 'paragraph';
318
- if (nodeTypesWithShortPlaceholderText.includes(parentType) && isEmptyNode) {
319
- var _table$node$firstChil;
320
- var table = findParentNode(function (node) {
321
- return node.type === editorState.schema.nodes.table;
322
- })(editorState.selection);
323
- if (!table) {
324
- return emptyPlaceholder({
325
- placeholderText: defaultPlaceholderText,
326
- placeholderPrompts: placeholderPrompts,
327
- userHadTyped: userHadTyped
328
- });
329
- }
330
- var isFirstCell = (table === null || table === void 0 || (_table$node$firstChil = table.node.firstChild) === null || _table$node$firstChil === void 0 ? void 0 : _table$node$firstChil.content.firstChild) === parentNode;
331
- if (isFirstCell) {
332
- return setPlaceHolderState({
333
- placeholderText: !fg('platform_editor_ai_aifc_patch_ga') ? intl.formatMessage(messages.shortEmptyNodePlaceholderText) : undefined,
334
- contextPlaceholderADF: fg('platform_editor_ai_aifc_patch_ga') ? createShortEmptyNodePlaceholderADF(intl) : undefined,
335
- pos: $from.pos,
336
- placeholderPrompts: placeholderPrompts,
337
- typedAndDeleted: typedAndDeleted,
338
- userHadTyped: userHadTyped
339
- });
340
- }
341
- }
342
- if (nodeTypesWithLongPlaceholderText.includes(parentType) && isEmptyNode) {
343
- return setPlaceHolderState({
344
- placeholderText: !fg('platform_editor_ai_aifc_patch_ga') ? intl.formatMessage(messages.longEmptyNodePlaceholderText) : undefined,
345
- contextPlaceholderADF: fg('platform_editor_ai_aifc_patch_ga') ? createLongEmptyNodePlaceholderADF(intl) : undefined,
346
- pos: $from.pos,
347
- placeholderPrompts: placeholderPrompts,
348
- typedAndDeleted: typedAndDeleted,
349
- userHadTyped: userHadTyped
350
- });
351
- }
352
- if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true)) {
353
- return setPlaceHolderState({
354
- placeholderText: intl.formatMessage(messages.syncBlockPlaceholderText),
355
- pos: $from.pos,
356
- placeholderPrompts: placeholderPrompts,
357
- typedAndDeleted: typedAndDeleted,
358
- userHadTyped: userHadTyped
359
- });
360
- }
361
- return emptyPlaceholder({
362
- placeholderText: defaultPlaceholderText,
363
- placeholderPrompts: placeholderPrompts,
364
- userHadTyped: userHadTyped
365
- });
366
- }
367
- if (bracketPlaceholderText && bracketTyped(editorState) && isEditorFocused) {
368
- var _$from = editorState.selection.$from;
369
- // Space is to account for positioning of the bracket
370
- var bracketHint = ' ' + bracketPlaceholderText;
371
- return setPlaceHolderState({
372
- placeholderText: bracketHint,
373
- pos: _$from.pos - 1,
374
- placeholderPrompts: placeholderPrompts,
375
- typedAndDeleted: typedAndDeleted,
376
- userHadTyped: userHadTyped
8
+ export var placeholderPlugin = function placeholderPlugin(_ref) {
9
+ var options = _ref.config,
10
+ api = _ref.api;
11
+ if (!fg('platform_editor_placeholder_plugin_tidying')) {
12
+ return placeholderPluginLegacy({
13
+ config: options,
14
+ api: api
377
15
  });
378
16
  }
379
- return emptyPlaceholder({
380
- placeholderText: defaultPlaceholderText,
381
- placeholderPrompts: placeholderPrompts,
382
- userHadTyped: userHadTyped
383
- });
384
- }
385
- function calculateUserInteractionState(_ref6) {
386
- var placeholderState = _ref6.placeholderState,
387
- oldEditorState = _ref6.oldEditorState,
388
- newEditorState = _ref6.newEditorState;
389
- var wasEmpty = oldEditorState ? isEmptyDocument(oldEditorState.doc) : true;
390
- var isEmpty = isEmptyDocument(newEditorState.doc);
391
- var hasEverTyped = Boolean(placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.userHadTyped) ||
392
- // Previously typed
393
- !wasEmpty ||
394
- // Had content before
395
- wasEmpty && !isEmpty; // Just added content
396
- var justDeletedAll = hasEverTyped && isEmpty && !wasEmpty;
397
- var isInTypedAndDeletedState = justDeletedAll || Boolean(placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.typedAndDeleted) && isEmpty;
398
- // Only reset user interaction tracking when editor is cleanly empty
399
- var shouldResetInteraction = isEmpty && !isInTypedAndDeletedState;
400
- return {
401
- userHadTyped: shouldResetInteraction ? false : hasEverTyped,
402
- typedAndDeleted: isInTypedAndDeletedState
403
- };
404
- }
405
- export function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, emptyLinePlaceholder, placeholderPrompts, withEmptyParagraph, placeholderADF, api) {
406
- if (!defaultPlaceholderText && !placeholderPrompts && !bracketPlaceholderText && !placeholderADF) {
407
- return;
408
- }
409
- var isDestroyed = false;
410
- var activeTypewriterTimeouts = [];
411
- var clearAllTypewriterTimeouts = function clearAllTypewriterTimeouts() {
412
- activeTypewriterTimeouts.forEach(function (clearFn) {
413
- return clearFn();
414
- });
415
- activeTypewriterTimeouts = [];
416
- };
417
- return new SafePlugin({
418
- key: pluginKey,
419
- state: {
420
- init: function init(_, state) {
421
- var _api$focus, _api$typeAhead;
422
- return createPlaceHolderStateFrom({
423
- isInitial: true,
424
- isEditorFocused: Boolean(api === null || api === void 0 || (_api$focus = api.focus) === null || _api$focus === void 0 || (_api$focus = _api$focus.sharedState.currentState()) === null || _api$focus === void 0 ? void 0 : _api$focus.hasFocus),
425
- editorState: state,
426
- isTypeAheadOpen: api === null || api === void 0 || (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.actions.isOpen,
427
- defaultPlaceholderText: defaultPlaceholderText,
428
- bracketPlaceholderText: bracketPlaceholderText,
429
- emptyLinePlaceholder: emptyLinePlaceholder,
430
- placeholderADF: placeholderADF,
431
- placeholderPrompts: placeholderPrompts,
432
- typedAndDeleted: false,
433
- userHadTyped: false,
434
- intl: intl
435
- });
436
- },
437
- apply: function apply(tr, placeholderState, _oldEditorState, newEditorState) {
438
- var _api$focus2, _placeholderState$isP, _api$typeAhead2, _ref7, _meta$placeholderText, _ref8, _meta$placeholderProm, _meta$showOnEmptyPara;
439
- var meta = tr.getMeta(pluginKey);
440
- var isEditorFocused = Boolean(api === null || api === void 0 || (_api$focus2 = api.focus) === null || _api$focus2 === void 0 || (_api$focus2 = _api$focus2.sharedState.currentState()) === null || _api$focus2 === void 0 ? void 0 : _api$focus2.hasFocus);
441
- var _calculateUserInterac = calculateUserInteractionState({
442
- placeholderState: placeholderState,
443
- oldEditorState: _oldEditorState,
444
- newEditorState: newEditorState
445
- }),
446
- userHadTyped = _calculateUserInterac.userHadTyped,
447
- typedAndDeleted = _calculateUserInterac.typedAndDeleted;
448
- var isPlaceholderHidden = (_placeholderState$isP = placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.isPlaceholderHidden) !== null && _placeholderState$isP !== void 0 ? _placeholderState$isP : false;
449
- if ((meta === null || meta === void 0 ? void 0 : meta.isPlaceholderHidden) !== undefined && fg('platform_editor_ai_aifc_patch_beta')) {
450
- isPlaceholderHidden = meta.isPlaceholderHidden;
451
- }
452
- if ((meta === null || meta === void 0 ? void 0 : meta.placeholderText) !== undefined && (fg('platform_editor_ai_aifc_patch_beta_2') || fg('platform_editor_ai_aifc_patch_ga'))) {
453
- // Only update defaultPlaceholderText from meta if we're not using ADF placeholder
454
- if (!(fg('platform_editor_ai_aifc_patch_ga') && placeholderADF)) {
455
- defaultPlaceholderText = meta.placeholderText;
456
- }
457
- }
458
- var newPlaceholderState = createPlaceHolderStateFrom({
459
- isEditorFocused: isEditorFocused,
460
- editorState: newEditorState,
461
- isTypeAheadOpen: api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.actions.isOpen,
462
- defaultPlaceholderText: fg('platform_editor_ai_aifc_patch_beta_2') || fg('platform_editor_ai_aifc_patch_ga') ? defaultPlaceholderText : (_ref7 = (_meta$placeholderText = meta === null || meta === void 0 ? void 0 : meta.placeholderText) !== null && _meta$placeholderText !== void 0 ? _meta$placeholderText : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderText) !== null && _ref7 !== void 0 ? _ref7 : defaultPlaceholderText,
463
- bracketPlaceholderText: bracketPlaceholderText,
464
- emptyLinePlaceholder: emptyLinePlaceholder,
465
- placeholderADF: placeholderADF,
466
- placeholderPrompts: (_ref8 = (_meta$placeholderProm = meta === null || meta === void 0 ? void 0 : meta.placeholderPrompts) !== null && _meta$placeholderProm !== void 0 ? _meta$placeholderProm : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderPrompts) !== null && _ref8 !== void 0 ? _ref8 : placeholderPrompts,
467
- typedAndDeleted: typedAndDeleted,
468
- userHadTyped: userHadTyped,
469
- intl: intl,
470
- isPlaceholderHidden: isPlaceholderHidden,
471
- withEmptyParagraph: withEmptyParagraph,
472
- showOnEmptyParagraph: (_meta$showOnEmptyPara = meta === null || meta === void 0 ? void 0 : meta.showOnEmptyParagraph) !== null && _meta$showOnEmptyPara !== void 0 ? _meta$showOnEmptyPara : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.showOnEmptyParagraph
473
- });
474
-
475
- // Clear timeouts when hasPlaceholder becomes false
476
- if (!newPlaceholderState.hasPlaceholder) {
477
- clearAllTypewriterTimeouts();
478
- }
479
- return newPlaceholderState;
480
- }
481
- },
482
- props: {
483
- decorations: function decorations(editorState) {
484
- var _api$composition, _api$showDiff;
485
- var _getPlaceholderState = getPlaceholderState(editorState),
486
- hasPlaceholder = _getPlaceholderState.hasPlaceholder,
487
- placeholderText = _getPlaceholderState.placeholderText,
488
- pos = _getPlaceholderState.pos,
489
- typedAndDeleted = _getPlaceholderState.typedAndDeleted,
490
- contextPlaceholderADF = _getPlaceholderState.contextPlaceholderADF;
491
-
492
- // Decorations is still called after plugin is destroyed
493
- // So we need to make sure decorations is not called if plugin has been destroyed to prevent the placeholder animations' setTimeouts called infinitely
494
- if (isDestroyed) {
495
- return;
496
- }
497
- var compositionPluginState = api === null || api === void 0 || (_api$composition = api.composition) === null || _api$composition === void 0 ? void 0 : _api$composition.sharedState.currentState();
498
- var isShowingDiff = Boolean(api === null || api === void 0 || (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 || (_api$showDiff = _api$showDiff.sharedState.currentState()) === null || _api$showDiff === void 0 ? void 0 : _api$showDiff.isDisplayingChanges);
499
- if (hasPlaceholder && ((placeholderText !== null && placeholderText !== void 0 ? placeholderText : '') || placeholderPrompts || placeholderADF || contextPlaceholderADF) && pos !== undefined && !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff) {
500
- var initialDelayWhenUserTypedAndDeleted = typedAndDeleted ? TYPEWRITER_TYPED_AND_DELETED_DELAY : 0;
501
- // contextPlaceholderADF takes precedence over the global placeholderADF
502
- var placeholderAdfToUse = contextPlaceholderADF || placeholderADF;
503
- return createPlaceholderDecoration(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse);
504
- }
505
- return;
506
- }
507
- },
508
- view: function view() {
509
- var timeoutId;
510
- function startEmptyParagraphTimeout(editorView) {
511
- if (timeoutId) {
512
- return;
513
- }
514
- timeoutId = setTimeout(function () {
515
- timeoutId = undefined;
516
- editorView.dispatch(editorView.state.tr.setMeta(pluginKey, {
517
- showOnEmptyParagraph: true
518
- }));
519
- }, EMPTY_PARAGRAPH_TIMEOUT_DELAY);
520
- }
521
- function destroyEmptyParagraphTimeout() {
522
- if (timeoutId) {
523
- clearTimeout(timeoutId);
524
- timeoutId = undefined;
525
- }
526
- }
527
- return {
528
- update: function update(editorView, prevState) {
529
- if (fg('platform_editor_ai_aifc_patch_beta_2') || fg('platform_editor_ai_aifc_patch_ga')) {
530
- var prevPluginState = getPlaceholderState(prevState);
531
- var newPluginState = getPlaceholderState(editorView.state);
532
-
533
- // user start typing after move to an empty paragraph, clear timeout
534
- if (!newPluginState.canShowOnEmptyParagraph && timeoutId) {
535
- destroyEmptyParagraphTimeout();
536
- }
537
- // user move to an empty paragraph again, reset state to hide placeholder, and restart timeout
538
- else if (prevPluginState.canShowOnEmptyParagraph && newPluginState.canShowOnEmptyParagraph && newPluginState.pos !== prevPluginState.pos) {
539
- editorView.dispatch(editorView.state.tr.setMeta(pluginKey, {
540
- showOnEmptyParagraph: false
541
- }));
542
- destroyEmptyParagraphTimeout();
543
- startEmptyParagraphTimeout(editorView);
544
- }
545
- // user move to an empty paragraph (by click enter or move to an empty paragraph), start timeout
546
- else if (!prevPluginState.canShowOnEmptyParagraph && newPluginState.canShowOnEmptyParagraph && !newPluginState.showOnEmptyParagraph && !timeoutId) {
547
- startEmptyParagraphTimeout(editorView);
548
- }
549
- }
550
- },
551
- destroy: function destroy() {
552
- clearAllTypewriterTimeouts();
553
- destroyEmptyParagraphTimeout();
554
- isDestroyed = true;
555
- }
556
- };
557
- }
558
- });
559
- }
560
- export var placeholderPlugin = function placeholderPlugin(_ref9) {
561
- var options = _ref9.config,
562
- api = _ref9.api;
563
17
  var currentPlaceholder = options === null || options === void 0 ? void 0 : options.placeholder;
564
18
  return {
565
19
  name: 'placeholder',
566
20
  commands: {
567
21
  setPlaceholder: function setPlaceholder(placeholderText) {
568
- return function (_ref0) {
569
- var tr = _ref0.tr;
22
+ return function (_ref2) {
23
+ var tr = _ref2.tr;
570
24
  if (currentPlaceholder !== placeholderText) {
571
25
  currentPlaceholder = placeholderText;
572
26
  return tr.setMeta(pluginKey, {
@@ -577,16 +31,16 @@ export var placeholderPlugin = function placeholderPlugin(_ref9) {
577
31
  };
578
32
  },
579
33
  setAnimatingPlaceholderPrompts: function setAnimatingPlaceholderPrompts(placeholderPrompts) {
580
- return function (_ref1) {
581
- var tr = _ref1.tr;
34
+ return function (_ref3) {
35
+ var tr = _ref3.tr;
582
36
  return tr.setMeta(pluginKey, {
583
37
  placeholderPrompts: placeholderPrompts
584
38
  });
585
39
  };
586
40
  },
587
41
  setPlaceholderHidden: function setPlaceholderHidden(isPlaceholderHidden) {
588
- return function (_ref10) {
589
- var tr = _ref10.tr;
42
+ return function (_ref4) {
43
+ var tr = _ref4.tr;
590
44
  return tr.setMeta(pluginKey, {
591
45
  isPlaceholderHidden: isPlaceholderHidden
592
46
  });
@@ -596,8 +50,8 @@ export var placeholderPlugin = function placeholderPlugin(_ref9) {
596
50
  pmPlugins: function pmPlugins() {
597
51
  return [{
598
52
  name: 'placeholder',
599
- plugin: function plugin(_ref11) {
600
- var getIntl = _ref11.getIntl;
53
+ plugin: function plugin(_ref5) {
54
+ var getIntl = _ref5.getIntl;
601
55
  return createPlugin(getIntl(), options && options.placeholder, options && options.placeholderBracketHint, options && options.emptyLinePlaceholder, options && options.placeholderPrompts, options === null || options === void 0 ? void 0 : options.withEmptyParagraph, options && options.placeholderADF, api);
602
56
  }
603
57
  }];
@@ -0,0 +1,24 @@
1
+ import { code, text } from '@atlaskit/adf-utils/builders';
2
+ import { placeholderTextMessages as messages } from '@atlaskit/editor-common/messages';
3
+ export var createShortEmptyNodePlaceholderADF = function createShortEmptyNodePlaceholderADF(_ref) {
4
+ var formatMessage = _ref.formatMessage;
5
+ return {
6
+ version: 1,
7
+ type: 'doc',
8
+ content: [{
9
+ type: 'paragraph',
10
+ content: [code(formatMessage(messages.shortEmptyNodePlaceholderADFSlashShortcut)), text(' '), text(formatMessage(messages.shortEmptyNodePlaceholderADFSuffix))]
11
+ }]
12
+ };
13
+ };
14
+ export var createLongEmptyNodePlaceholderADF = function createLongEmptyNodePlaceholderADF(_ref2) {
15
+ var formatMessage = _ref2.formatMessage;
16
+ return {
17
+ version: 1,
18
+ type: 'doc',
19
+ content: [{
20
+ type: 'paragraph',
21
+ content: [text(formatMessage(messages.longEmptyNodePlaceholderADFPrefix)), text(' '), code(formatMessage(messages.longEmptyNodePlaceholderADFSlashShortcut)), text(' '), text(formatMessage(messages.longEmptyNodePlaceholderADFSuffix))]
22
+ }]
23
+ };
24
+ };