@atlaskit/editor-core 201.1.5 → 201.1.7

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 (57) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/composable-editor/editor-internal.js +60 -2
  3. package/dist/cjs/create-editor/ReactEditorView/formatFullWidthAppearance.js +13 -0
  4. package/dist/cjs/create-editor/ReactEditorView/getUAPrefix.js +19 -0
  5. package/dist/cjs/create-editor/ReactEditorView/handleEditorFocus.js +44 -0
  6. package/dist/cjs/create-editor/ReactEditorView/useDispatchTransaction.js +90 -0
  7. package/dist/cjs/create-editor/ReactEditorView/useFireFullWidthEvent.js +28 -0
  8. package/dist/cjs/create-editor/ReactEditorView/usePluginPerformanceObserver.js +48 -0
  9. package/dist/cjs/create-editor/ReactEditorView.js +2 -1
  10. package/dist/cjs/create-editor/ReactEditorViewNext.js +538 -0
  11. package/dist/cjs/presets/universal.js +2 -1
  12. package/dist/cjs/version-wrapper.js +1 -1
  13. package/dist/es2019/composable-editor/editor-internal.js +61 -2
  14. package/dist/es2019/create-editor/ReactEditorView/formatFullWidthAppearance.js +7 -0
  15. package/dist/es2019/create-editor/ReactEditorView/getUAPrefix.js +13 -0
  16. package/dist/es2019/create-editor/ReactEditorView/handleEditorFocus.js +38 -0
  17. package/dist/es2019/create-editor/ReactEditorView/useDispatchTransaction.js +82 -0
  18. package/dist/es2019/create-editor/ReactEditorView/useFireFullWidthEvent.js +22 -0
  19. package/dist/es2019/create-editor/ReactEditorView/usePluginPerformanceObserver.js +32 -0
  20. package/dist/es2019/create-editor/ReactEditorView.js +2 -1
  21. package/dist/es2019/create-editor/ReactEditorViewNext.js +515 -0
  22. package/dist/es2019/presets/universal.js +2 -1
  23. package/dist/es2019/version-wrapper.js +1 -1
  24. package/dist/esm/composable-editor/editor-internal.js +60 -2
  25. package/dist/esm/create-editor/ReactEditorView/formatFullWidthAppearance.js +7 -0
  26. package/dist/esm/create-editor/ReactEditorView/getUAPrefix.js +13 -0
  27. package/dist/esm/create-editor/ReactEditorView/handleEditorFocus.js +38 -0
  28. package/dist/esm/create-editor/ReactEditorView/useDispatchTransaction.js +84 -0
  29. package/dist/esm/create-editor/ReactEditorView/useFireFullWidthEvent.js +22 -0
  30. package/dist/esm/create-editor/ReactEditorView/usePluginPerformanceObserver.js +42 -0
  31. package/dist/esm/create-editor/ReactEditorView.js +2 -1
  32. package/dist/esm/create-editor/ReactEditorViewNext.js +528 -0
  33. package/dist/esm/presets/universal.js +2 -1
  34. package/dist/esm/version-wrapper.js +1 -1
  35. package/dist/types/create-editor/ReactEditorView/formatFullWidthAppearance.d.ts +3 -0
  36. package/dist/types/create-editor/ReactEditorView/getUAPrefix.d.ts +1 -0
  37. package/dist/types/create-editor/ReactEditorView/handleEditorFocus.d.ts +2 -0
  38. package/dist/types/create-editor/ReactEditorView/useDispatchTransaction.d.ts +12 -0
  39. package/dist/types/create-editor/ReactEditorView/useFireFullWidthEvent.d.ts +3 -0
  40. package/dist/types/create-editor/ReactEditorView/usePluginPerformanceObserver.d.ts +5 -0
  41. package/dist/types/create-editor/ReactEditorViewNext.d.ts +48 -0
  42. package/dist/types/create-editor/create-universal-preset.d.ts +8 -2
  43. package/dist/types/presets/universal.d.ts +8 -2
  44. package/dist/types/presets/useUniversalPreset.d.ts +8 -2
  45. package/dist/types/types/editor-config.d.ts +1 -2
  46. package/dist/types-ts4.5/create-editor/ReactEditorView/formatFullWidthAppearance.d.ts +3 -0
  47. package/dist/types-ts4.5/create-editor/ReactEditorView/getUAPrefix.d.ts +1 -0
  48. package/dist/types-ts4.5/create-editor/ReactEditorView/handleEditorFocus.d.ts +2 -0
  49. package/dist/types-ts4.5/create-editor/ReactEditorView/useDispatchTransaction.d.ts +12 -0
  50. package/dist/types-ts4.5/create-editor/ReactEditorView/useFireFullWidthEvent.d.ts +3 -0
  51. package/dist/types-ts4.5/create-editor/ReactEditorView/usePluginPerformanceObserver.d.ts +5 -0
  52. package/dist/types-ts4.5/create-editor/ReactEditorViewNext.d.ts +48 -0
  53. package/dist/types-ts4.5/create-editor/create-universal-preset.d.ts +11 -2
  54. package/dist/types-ts4.5/presets/universal.d.ts +11 -2
  55. package/dist/types-ts4.5/presets/useUniversalPreset.d.ts +11 -2
  56. package/dist/types-ts4.5/types/editor-config.d.ts +1 -2
  57. package/package.json +14 -4
@@ -0,0 +1,528 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ 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; }
4
+ 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; }
5
+ import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
6
+ import { injectIntl } from 'react-intl-next';
7
+ import uuid from 'uuid/v4';
8
+ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, PLATFORMS } from '@atlaskit/editor-common/analytics';
9
+ import { useConstructor, usePreviousState } from '@atlaskit/editor-common/hooks';
10
+ import { getEnabledFeatureFlagKeys } from '@atlaskit/editor-common/normalize-feature-flags';
11
+ import { measureRender } from '@atlaskit/editor-common/performance/measure-render';
12
+ import { getResponseEndTime } from '@atlaskit/editor-common/performance/navigation';
13
+ import { EditorPluginInjectionAPI } from '@atlaskit/editor-common/preset';
14
+ import { processRawValue, processRawValueWithoutTransformation } from '@atlaskit/editor-common/process-raw-value';
15
+ import { analyticsEventKey, getAnalyticsEventSeverity } from '@atlaskit/editor-common/utils/analytics';
16
+ import { EditorState, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
17
+ import { EditorView } from '@atlaskit/editor-prosemirror/view';
18
+ import { fg } from '@atlaskit/platform-feature-flags';
19
+ import { useProviders } from '../composable-editor/hooks/useProviders';
20
+ import { createDispatch, EventDispatcher } from '../event-dispatcher';
21
+ import { getNodesCount } from '../utils/getNodesCount';
22
+ import { isFullPage } from '../utils/is-full-page';
23
+ import { RenderTracking } from '../utils/performance/components/RenderTracking';
24
+ import measurements from '../utils/performance/measure-enum';
25
+ import { PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD, PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD } from './consts';
26
+ import { createErrorReporter, createPMPlugins, processPluginsList } from './create-editor';
27
+ import createPluginsList from './create-plugins-list';
28
+ import { createSchema } from './create-schema';
29
+ import { createFeatureFlagsFromProps } from './feature-flags-from-props';
30
+ import { editorMessages } from './messages';
31
+ import { getUAPrefix } from './ReactEditorView/getUAPrefix';
32
+ import { handleEditorFocus } from './ReactEditorView/handleEditorFocus';
33
+ import { useDispatchTransaction } from './ReactEditorView/useDispatchTransaction';
34
+ import { useFireFullWidthEvent } from './ReactEditorView/useFireFullWidthEvent';
35
+ import { usePluginPerformanceObserver } from './ReactEditorView/usePluginPerformanceObserver';
36
+ import ReactEditorViewContext from './ReactEditorViewContext';
37
+ var EDIT_AREA_ID = 'ak-editor-textarea';
38
+ function ReactEditorView(props) {
39
+ var _media, _linking, _props$render, _props$render2;
40
+ var preset = props.preset,
41
+ _props$editorProps = props.editorProps,
42
+ nextAppearance = _props$editorProps.appearance,
43
+ disabled = _props$editorProps.disabled;
44
+ var _useState = useState(undefined),
45
+ _useState2 = _slicedToArray(_useState, 2),
46
+ editorAPI = _useState2[0],
47
+ setEditorAPI = _useState2[1];
48
+ var editorRef = useRef(null);
49
+ var viewRef = useRef();
50
+ var focusTimeoutId = useRef();
51
+ // ProseMirror is instantiated prior to the initial React render cycle,
52
+ // so we allow transactions by default, to avoid discarding the initial one.
53
+ var canDispatchTransactions = useRef(true);
54
+ var editorId = useRef(uuid());
55
+ var eventDispatcher = useMemo(function () {
56
+ return new EventDispatcher();
57
+ }, []);
58
+ var config = useRef({
59
+ nodes: [],
60
+ marks: [],
61
+ pmPlugins: [],
62
+ contentComponents: [],
63
+ pluginHooks: [],
64
+ primaryToolbarComponents: [],
65
+ secondaryToolbarComponents: [],
66
+ onEditorViewStateUpdatedCallbacks: []
67
+ });
68
+ var contentTransformer = useRef(undefined);
69
+ var featureFlags = useRef(createFeatureFlagsFromProps(props.editorProps));
70
+ var getEditorState = useCallback(function () {
71
+ var _viewRef$current;
72
+ return (_viewRef$current = viewRef.current) === null || _viewRef$current === void 0 ? void 0 : _viewRef$current.state;
73
+ }, []);
74
+ var getEditorView = useCallback(function () {
75
+ return viewRef.current;
76
+ }, []);
77
+ var dispatch = useMemo(function () {
78
+ return createDispatch(eventDispatcher);
79
+ }, [eventDispatcher]);
80
+ var errorReporter = useRef(createErrorReporter(props.editorProps.errorReporterHandler));
81
+ var handleAnalyticsEvent = useCallback(function (payload) {
82
+ fireAnalyticsEvent(props.createAnalyticsEvent)(payload);
83
+ }, [props.createAnalyticsEvent]);
84
+ var dispatchAnalyticsEvent = useCallback(function (payload) {
85
+ var dispatch = createDispatch(eventDispatcher);
86
+ dispatch(analyticsEventKey, {
87
+ payload: payload
88
+ });
89
+ }, [eventDispatcher]);
90
+ var pluginInjectionAPI = useRef(new EditorPluginInjectionAPI({
91
+ getEditorState: getEditorState,
92
+ getEditorView: getEditorView
93
+ }));
94
+ useLayoutEffect(function () {
95
+ setEditorAPI(pluginInjectionAPI.current.api());
96
+ }, []);
97
+ var blur = useCallback(function () {
98
+ if (!viewRef.current) {
99
+ return;
100
+ }
101
+ if (viewRef.current.dom instanceof HTMLElement && viewRef.current.hasFocus()) {
102
+ viewRef.current.dom.blur();
103
+ }
104
+
105
+ // The selectionToDOM method uses the document selection to determine currently selected node
106
+ // We need to mimic blurring this as it seems doing the above is not enough.
107
+ // @ts-expect-error
108
+ var sel = viewRef.current.root.getSelection();
109
+ if (sel) {
110
+ sel.removeAllRanges();
111
+ }
112
+ }, []);
113
+ var createEditorState = useCallback(function (options) {
114
+ var _api$editorViewMode;
115
+ var schema;
116
+ if (viewRef.current) {
117
+ if (options.resetting) {
118
+ /**
119
+ * ReactEditorView currently does NOT handle dynamic schema,
120
+ * We are reusing the existing schema, and rely on #reconfigureState
121
+ * to update `this.config`
122
+ */
123
+ schema = viewRef.current.state.schema;
124
+ } else {
125
+ /**
126
+ * There's presently a number of issues with changing the schema of a
127
+ * editor inflight. A significant issue is that we lose the ability
128
+ * to keep track of a user's history as the internal plugin state
129
+ * keeps a list of Steps to undo/redo (which are tied to the schema).
130
+ * Without a good way to do work around this, we prevent this for now.
131
+ */
132
+ // eslint-disable-next-line no-console
133
+ console.warn('The editor does not support changing the schema dynamically.');
134
+ return viewRef.current.state;
135
+ }
136
+ } else {
137
+ config.current = processPluginsList(createPluginsList(options.props.preset, props.editorProps, pluginInjectionAPI.current));
138
+ schema = createSchema(config.current);
139
+ }
140
+ var contentTransformerProvider = options.props.editorProps.contentTransformerProvider;
141
+ var plugins = createPMPlugins({
142
+ schema: schema,
143
+ dispatch: dispatch,
144
+ errorReporter: errorReporter.current,
145
+ editorConfig: config.current,
146
+ eventDispatcher: eventDispatcher,
147
+ providerFactory: options.props.providerFactory,
148
+ portalProviderAPI: props.portalProviderAPI,
149
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
150
+ featureFlags: featureFlags.current,
151
+ getIntl: function getIntl() {
152
+ return props.intl;
153
+ }
154
+ });
155
+ contentTransformer.current = contentTransformerProvider ? contentTransformerProvider(schema) : undefined;
156
+ var api = pluginInjectionAPI.current.api();
157
+
158
+ // If we have a doc prop, we need to process it into a PMNode
159
+ var doc;
160
+ if (options.doc) {
161
+ // if the collabEdit API is set, skip this validation due to potential pm validation errors
162
+ // from docs that end up with invalid marks after processing (See #hot-111702 for more details)
163
+ if ((api === null || api === void 0 ? void 0 : api.collabEdit) !== undefined && fg('editor_load_conf_collab_docs_without_checks')) {
164
+ doc = processRawValueWithoutTransformation(schema, options.doc);
165
+ } else {
166
+ doc = processRawValue(schema, options.doc, options.props.providerFactory, options.props.editorProps.sanitizePrivateContent, contentTransformer.current, dispatchAnalyticsEvent);
167
+ }
168
+ }
169
+ var isViewMode = (api === null || api === void 0 || (_api$editorViewMode = api.editorViewMode) === null || _api$editorViewMode === void 0 ? void 0 : _api$editorViewMode.sharedState.currentState().mode) === 'view';
170
+ var selection;
171
+ if (doc) {
172
+ if (isViewMode) {
173
+ var emptySelection = new TextSelection(doc.resolve(0));
174
+ return EditorState.create({
175
+ schema: schema,
176
+ plugins: plugins,
177
+ doc: doc,
178
+ selection: emptySelection
179
+ });
180
+ } else {
181
+ selection = options.selectionAtStart ? Selection.atStart(doc) : Selection.atEnd(doc);
182
+ }
183
+ }
184
+ // Workaround for ED-3507: When media node is the last element, scrollIntoView throws an error
185
+ var patchedSelection = selection ? Selection.findFrom(selection.$head, -1, true) || undefined : undefined;
186
+ return EditorState.create({
187
+ schema: schema,
188
+ plugins: plugins,
189
+ doc: doc,
190
+ selection: patchedSelection
191
+ });
192
+ }, [props.intl, props.portalProviderAPI, props.editorProps, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
193
+ var resetEditorState = useCallback(function (_ref) {
194
+ var _props$editorProps$on, _props$editorProps2;
195
+ var doc = _ref.doc,
196
+ shouldScrollToBottom = _ref.shouldScrollToBottom;
197
+ if (!viewRef.current) {
198
+ return;
199
+ }
200
+
201
+ // We cannot currently guarentee when all the portals will have re-rendered during a reconfigure
202
+ // so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
203
+ // nodes that haven't been re-rendered to the document yet.
204
+ blur();
205
+ featureFlags.current = createFeatureFlagsFromProps(props.editorProps);
206
+ var newEditorState = createEditorState({
207
+ props: props,
208
+ doc: doc,
209
+ resetting: true,
210
+ selectionAtStart: !shouldScrollToBottom
211
+ });
212
+ editorState.current = newEditorState;
213
+ viewRef.current.updateState(newEditorState);
214
+ (_props$editorProps$on = (_props$editorProps2 = props.editorProps).onChange) === null || _props$editorProps$on === void 0 || _props$editorProps$on.call(_props$editorProps2, viewRef.current, {
215
+ source: 'local'
216
+ });
217
+ }, [blur, createEditorState, props]);
218
+
219
+ // Initialise phase
220
+ // Using constructor hook so we setup and dispatch analytics before anything else
221
+ useConstructor(function () {
222
+ dispatchAnalyticsEvent({
223
+ action: ACTION.STARTED,
224
+ actionSubject: ACTION_SUBJECT.EDITOR,
225
+ attributes: {
226
+ platform: PLATFORMS.WEB,
227
+ featureFlags: featureFlags.current ? getEnabledFeatureFlagKeys(featureFlags.current) : []
228
+ },
229
+ eventType: EVENT_TYPE.UI
230
+ });
231
+ // Transaction dispatching is already enabled by default prior to
232
+ // mounting, but we reset it here, just in case the editor view
233
+ // instance is ever recycled (mounted again after unmounting) with
234
+ // the same key.
235
+ // Although storing mounted state is an anti-pattern in React,
236
+ // we do so here so that we can intercept and abort asynchronous
237
+ // ProseMirror transactions when a dismount is imminent.
238
+ canDispatchTransactions.current = true;
239
+ // This needs to be before initialising editorState because
240
+ // we dispatch analytics events in plugin initialisation
241
+ eventDispatcher.on(analyticsEventKey, handleAnalyticsEvent);
242
+ eventDispatcher.on('resetEditorState', resetEditorState);
243
+ });
244
+
245
+ // Cleanup
246
+ useLayoutEffect(function () {
247
+ return function () {
248
+ var focusTimeoutIdCurrent = focusTimeoutId.current;
249
+ if (focusTimeoutIdCurrent) {
250
+ clearTimeout(focusTimeoutIdCurrent);
251
+ }
252
+ if (viewRef.current) {
253
+ // Destroy the state if the Editor is being unmounted
254
+ var _editorState = viewRef.current.state;
255
+ _editorState.plugins.forEach(function (plugin) {
256
+ var state = plugin.getState(_editorState);
257
+ if (state && state.destroy) {
258
+ state.destroy();
259
+ }
260
+ });
261
+ }
262
+ eventDispatcher.destroy();
263
+ // this.view will be destroyed when React unmounts in handleEditorViewRef
264
+ };
265
+ }, [eventDispatcher]);
266
+ var reconfigureState = useCallback(function (props) {
267
+ if (!viewRef.current) {
268
+ return;
269
+ }
270
+
271
+ // We cannot currently guarentee when all the portals will have re-rendered during a reconfigure
272
+ // so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
273
+ // nodes that haven't been re-rendered to the document yet.
274
+ blur();
275
+ var editorPlugins = createPluginsList(props.preset, props.editorProps, pluginInjectionAPI.current);
276
+ config.current = processPluginsList(editorPlugins);
277
+ var state = editorState.current;
278
+ var plugins = createPMPlugins({
279
+ schema: state.schema,
280
+ dispatch: dispatch,
281
+ errorReporter: errorReporter.current,
282
+ editorConfig: config.current,
283
+ eventDispatcher: eventDispatcher,
284
+ providerFactory: props.providerFactory,
285
+ portalProviderAPI: props.portalProviderAPI,
286
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
287
+ featureFlags: createFeatureFlagsFromProps(props.editorProps),
288
+ getIntl: function getIntl() {
289
+ return props.intl;
290
+ }
291
+ });
292
+ var newState = state.reconfigure({
293
+ plugins: plugins
294
+ });
295
+
296
+ // need to update the state first so when the view builds the nodeviews it is
297
+ // using the latest plugins
298
+ viewRef.current.updateState(newState);
299
+ return viewRef.current.update(_objectSpread(_objectSpread({}, viewRef.current.props), {}, {
300
+ state: newState
301
+ }));
302
+ }, [blur, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
303
+ var onEditorViewUpdated = useCallback(function (_ref2) {
304
+ var _config$current;
305
+ var originalTransaction = _ref2.originalTransaction,
306
+ transactions = _ref2.transactions,
307
+ oldEditorState = _ref2.oldEditorState,
308
+ newEditorState = _ref2.newEditorState;
309
+ pluginInjectionAPI.current.onEditorViewUpdated({
310
+ newEditorState: newEditorState,
311
+ oldEditorState: oldEditorState
312
+ });
313
+ (_config$current = config.current) === null || _config$current === void 0 || _config$current.onEditorViewStateUpdatedCallbacks.forEach(function (entry) {
314
+ entry.callback({
315
+ originalTransaction: originalTransaction,
316
+ transactions: transactions,
317
+ oldEditorState: oldEditorState,
318
+ newEditorState: newEditorState
319
+ });
320
+ });
321
+ }, []);
322
+ var _dispatchTransaction = useDispatchTransaction({
323
+ onChange: props.editorProps.onChange,
324
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
325
+ onEditorViewUpdated: onEditorViewUpdated
326
+ });
327
+
328
+ // TODO: Remove these when we deprecate these props from editor-props - smartLinks is unfortunately still used in some places, we can sidestep this problem if we move everyone across to ComposableEditor and deprecate Editor
329
+ var UNSAFE_cards = props.editorProps.UNSAFE_cards;
330
+ var smartLinks = props.editorProps.smartLinks;
331
+
332
+ // Temporary to replace provider factory while migration to `ComposableEditor` occurs
333
+ useProviders({
334
+ editorApi: editorAPI,
335
+ contextIdentifierProvider: props.editorProps.contextIdentifierProvider,
336
+ mediaProvider: (_media = props.editorProps.media) === null || _media === void 0 ? void 0 : _media.provider,
337
+ cardProvider: ((_linking = props.editorProps.linking) === null || _linking === void 0 || (_linking = _linking.smartLinks) === null || _linking === void 0 ? void 0 : _linking.provider) || smartLinks && smartLinks.provider || UNSAFE_cards && UNSAFE_cards.provider,
338
+ emojiProvider: props.editorProps.emojiProvider,
339
+ autoformattingProvider: props.editorProps.autoformattingProvider,
340
+ taskDecisionProvider: props.editorProps.taskDecisionProvider
341
+ });
342
+ var getDirectEditorProps = useCallback(function (state) {
343
+ return {
344
+ state: state || editorState.current,
345
+ dispatchTransaction: function dispatchTransaction(tr) {
346
+ // Block stale transactions:
347
+ // Prevent runtime exeptions from async transactions that would attempt to
348
+ // update the DOM after React has unmounted the Editor.
349
+ if (canDispatchTransactions.current) {
350
+ var newState = _dispatchTransaction(viewRef.current, tr);
351
+ if (newState) {
352
+ editorState.current = newState;
353
+ }
354
+ }
355
+ },
356
+ // Disables the contentEditable attribute of the editor if the editor is disabled
357
+ editable: function editable(_state) {
358
+ return !disabled;
359
+ },
360
+ attributes: {
361
+ 'data-gramm': 'false'
362
+ }
363
+ };
364
+ }, [_dispatchTransaction, disabled]);
365
+ var createEditorView = useCallback(function (node) {
366
+ measureRender(measurements.PROSEMIRROR_RENDERED, function (_ref3) {
367
+ var duration = _ref3.duration,
368
+ startTime = _ref3.startTime,
369
+ distortedDuration = _ref3.distortedDuration;
370
+ var proseMirrorRenderedSeverity = getAnalyticsEventSeverity(duration, PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD, PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD);
371
+ if (viewRef.current) {
372
+ var _pluginInjectionAPI$c;
373
+ var nodes = getNodesCount(viewRef.current.state.doc);
374
+ var ttfb = getResponseEndTime();
375
+ var contextIdentifier = (_pluginInjectionAPI$c = pluginInjectionAPI.current.api().base) === null || _pluginInjectionAPI$c === void 0 ? void 0 : _pluginInjectionAPI$c.sharedState.currentState();
376
+ dispatchAnalyticsEvent({
377
+ action: ACTION.PROSEMIRROR_RENDERED,
378
+ actionSubject: ACTION_SUBJECT.EDITOR,
379
+ attributes: {
380
+ duration: duration,
381
+ startTime: startTime,
382
+ nodes: nodes,
383
+ ttfb: ttfb,
384
+ severity: proseMirrorRenderedSeverity,
385
+ objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
386
+ distortedDuration: distortedDuration
387
+ },
388
+ eventType: EVENT_TYPE.OPERATIONAL
389
+ });
390
+ }
391
+ });
392
+
393
+ // Creates the editor-view from this.editorState. If an editor has been mounted
394
+ // previously, this will contain the previous state of the editor.
395
+ var view = new EditorView({
396
+ mount: node
397
+ }, getDirectEditorProps());
398
+ viewRef.current = view;
399
+ pluginInjectionAPI.current.onEditorViewUpdated({
400
+ newEditorState: viewRef.current.state,
401
+ oldEditorState: undefined
402
+ });
403
+ return view;
404
+ }, [getDirectEditorProps, dispatchAnalyticsEvent]);
405
+ var _useState3 = useState(undefined),
406
+ _useState4 = _slicedToArray(_useState3, 2),
407
+ _ = _useState4[0],
408
+ setEditorView = _useState4[1];
409
+ var onEditorCreated = props.onEditorCreated,
410
+ onEditorDestroyed = props.onEditorDestroyed,
411
+ shouldFocus = props.editorProps.shouldFocus;
412
+ var handleEditorViewRef = useCallback(function (node) {
413
+ if (!viewRef.current && node) {
414
+ var view = createEditorView(node);
415
+ onEditorCreated({
416
+ view: view,
417
+ config: config.current,
418
+ eventDispatcher: eventDispatcher,
419
+ transformer: contentTransformer.current
420
+ });
421
+ if (shouldFocus && view.props.editable && view.props.editable(view.state)) {
422
+ focusTimeoutId.current = handleEditorFocus(view);
423
+ }
424
+
425
+ // Force React to re-render so consumers get a reference to the editor view
426
+ setEditorView(view);
427
+ } else if (viewRef.current && !node) {
428
+ // When the appearance is changed, React will call handleEditorViewRef with node === null
429
+ // to destroy the old EditorView, before calling this method again with node === div to
430
+ // create the new EditorView
431
+ onEditorDestroyed({
432
+ view: viewRef.current,
433
+ config: config.current,
434
+ eventDispatcher: eventDispatcher,
435
+ transformer: contentTransformer.current
436
+ });
437
+ var wasAnalyticsDisconnected = !eventDispatcher.has(analyticsEventKey, handleAnalyticsEvent);
438
+ // If we disabled event listening for some reason we should re-enable it temporarily while we destroy
439
+ // the view for any analytics that occur there.
440
+ if (wasAnalyticsDisconnected) {
441
+ eventDispatcher.on(analyticsEventKey, handleAnalyticsEvent);
442
+ viewRef.current.destroy(); // Destroys the dom node & all node views
443
+ eventDispatcher.off(analyticsEventKey, handleAnalyticsEvent);
444
+ } else {
445
+ viewRef.current.destroy(); // Destroys the dom node & all node views
446
+ }
447
+ viewRef.current = undefined;
448
+ }
449
+ }, [createEditorView, handleAnalyticsEvent, onEditorDestroyed, onEditorCreated, shouldFocus, eventDispatcher]);
450
+ var createEditor = useCallback(function (assistiveLabel, assistiveDescribedBy) {
451
+ return /*#__PURE__*/React.createElement("div", {
452
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
453
+ className: getUAPrefix(),
454
+ key: "ProseMirror",
455
+ ref: handleEditorViewRef,
456
+ "aria-label": assistiveLabel || props.intl.formatMessage(editorMessages.editorAssistiveLabel)
457
+ // setting aria-multiline to true when not mobile appearance.
458
+ // because somehow mobile tests are failing when it set.
459
+ // don't know why that is happening.
460
+ // Created https://product-fabric.atlassian.net/jira/servicedesk/projects/DTR/queues/issue/DTR-1675
461
+ // to investigate further.
462
+ ,
463
+ "aria-multiline": true,
464
+ role: "textbox",
465
+ id: EDIT_AREA_ID,
466
+ "aria-describedby": assistiveDescribedBy,
467
+ "data-editor-id": editorId.current
468
+ });
469
+ }, [handleEditorViewRef, props.intl]);
470
+ var previousPreset = usePreviousState(preset);
471
+ useLayoutEffect(function () {
472
+ if (previousPreset && previousPreset !== preset) {
473
+ reconfigureState(props);
474
+ }
475
+ }, [reconfigureState, previousPreset, preset, props]);
476
+ var previousDisabledState = usePreviousState(disabled);
477
+ useLayoutEffect(function () {
478
+ if (viewRef.current && previousDisabledState !== disabled) {
479
+ // Disables the contentEditable attribute of the editor if the editor is disabled
480
+ viewRef.current.setProps({
481
+ editable: function editable(_state) {
482
+ return !disabled;
483
+ }
484
+ });
485
+ if (!disabled && shouldFocus) {
486
+ focusTimeoutId.current = handleEditorFocus(viewRef.current);
487
+ }
488
+ }
489
+ }, [disabled, shouldFocus, previousDisabledState]);
490
+ useFireFullWidthEvent(nextAppearance, dispatchAnalyticsEvent);
491
+ var editorState = useRef(createEditorState({
492
+ props: props,
493
+ doc: props.editorProps.defaultValue,
494
+ // ED-4759: Don't set selection at end for full-page editor - should be at start.
495
+ selectionAtStart: isFullPage(props.editorProps.appearance)
496
+ }));
497
+ usePluginPerformanceObserver(editorState, pluginInjectionAPI, dispatchAnalyticsEvent);
498
+ var editor = useMemo(function () {
499
+ return createEditor(props.editorProps.assistiveLabel, props.editorProps.assistiveDescribedBy);
500
+ },
501
+ // `createEditor` changes a little too frequently - we don't want to recreate the editor view in this case
502
+ // We should follow-up
503
+ // eslint-disable-next-line react-hooks/exhaustive-deps
504
+ [props.editorProps.assistiveLabel, props.editorProps.assistiveDescribedBy]);
505
+ return /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
506
+ value: {
507
+ editorRef: editorRef,
508
+ editorView: viewRef.current,
509
+ popupsMountPoint: props.editorProps.popupsMountPoint
510
+ }
511
+ }, /*#__PURE__*/React.createElement(RenderTracking, {
512
+ componentProps: props,
513
+ action: ACTION.RE_RENDERED,
514
+ actionSubject: ACTION_SUBJECT.REACT_EDITOR_VIEW,
515
+ handleAnalyticsEvent: handleAnalyticsEvent,
516
+ useShallow: true
517
+ }), props.render ? (_props$render = (_props$render2 = props.render) === null || _props$render2 === void 0 ? void 0 : _props$render2.call(props, {
518
+ editor: editor,
519
+ view: viewRef.current,
520
+ config: config.current,
521
+ eventDispatcher: eventDispatcher,
522
+ transformer: contentTransformer.current,
523
+ dispatchAnalyticsEvent: dispatchAnalyticsEvent,
524
+ editorRef: editorRef,
525
+ editorAPI: editorAPI
526
+ })) !== null && _props$render !== void 0 ? _props$render : editor : editor);
527
+ }
528
+ export default injectIntl(ReactEditorView);
@@ -200,7 +200,8 @@ export default function createUniversalPresetInternal(_ref) {
200
200
  // @ts-expect-error 2322: Type 'false | PlaceholderTextOptions | undefined'
201
201
  props.allowTemplatePlaceholders !== true ? props.allowTemplatePlaceholders : {}], Boolean(props.allowTemplatePlaceholders)).maybeAdd([layoutPlugin, _objectSpread(_objectSpread({}, _typeof(props.allowLayouts) === 'object' ? props.allowLayouts : {}), {}, {
202
202
  useLongPressSelection: false,
203
- UNSAFE_allowSingleColumnLayout: _typeof(props.allowLayouts) === 'object' ? props.allowLayouts.UNSAFE_allowSingleColumnLayout : undefined
203
+ UNSAFE_allowSingleColumnLayout: _typeof(props.allowLayouts) === 'object' ? props.allowLayouts.UNSAFE_allowSingleColumnLayout : undefined,
204
+ editorAppearance: appearance
204
205
  })], Boolean(props.allowLayouts)).maybeAdd([cardPlugin, _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, props.UNSAFE_cards), props.smartLinks), (_props$linking = props.linking) === null || _props$linking === void 0 ? void 0 : _props$linking.smartLinks), {}, {
205
206
  fullWidthMode: appearance === 'full-width',
206
207
  linkPicker: (_props$linking2 = props.linking) === null || _props$linking2 === void 0 ? void 0 : _props$linking2.linkPicker,
@@ -1,2 +1,2 @@
1
1
  export var name = "@atlaskit/editor-core";
2
- export var version = "201.1.5";
2
+ export var version = "201.1.7";
@@ -0,0 +1,3 @@
1
+ import { FULL_WIDTH_MODE } from '@atlaskit/editor-common/analytics';
2
+ import type { EditorAppearance } from '../../types';
3
+ export declare const formatFullWidthAppearance: (appearance: EditorAppearance | undefined) => FULL_WIDTH_MODE;
@@ -0,0 +1 @@
1
+ export declare function getUAPrefix(): "" | "ua-chrome" | "ua-ie" | "ua-firefox" | "ua-safari";
@@ -0,0 +1,2 @@
1
+ import { type EditorView } from '@atlaskit/editor-prosemirror/view';
2
+ export declare function handleEditorFocus(view: EditorView): number | undefined;
@@ -0,0 +1,12 @@
1
+ import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
2
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import type { EditorView } from '@atlaskit/editor-prosemirror/view';
4
+ import type { EditorViewStateUpdatedCallbackProps } from '../../types/editor-config';
5
+ import type { EditorOnChangeHandler } from '../../types/editor-onchange';
6
+ type DispatchTransaction = (view: EditorView | undefined, tr: Transaction) => EditorState | undefined;
7
+ export declare const useDispatchTransaction: ({ onChange, dispatchAnalyticsEvent, onEditorViewUpdated, }: {
8
+ onChange: EditorOnChangeHandler | undefined;
9
+ dispatchAnalyticsEvent: (payload: AnalyticsEventPayload) => void;
10
+ onEditorViewUpdated: (params: EditorViewStateUpdatedCallbackProps) => void;
11
+ }) => DispatchTransaction;
12
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
2
+ import type { EditorAppearance } from '@atlaskit/editor-common/types';
3
+ export declare const useFireFullWidthEvent: (appearance: EditorAppearance | undefined, dispatchAnalyticsEvent: (payload: AnalyticsEventPayload) => void) => void;
@@ -0,0 +1,5 @@
1
+ import type React from 'react';
2
+ import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
3
+ import { type EditorPluginInjectionAPI } from '@atlaskit/editor-common/preset';
4
+ import { type EditorState } from '@atlaskit/editor-prosemirror/state';
5
+ export declare const usePluginPerformanceObserver: (editorState: React.MutableRefObject<EditorState>, pluginInjectionAPI: React.MutableRefObject<EditorPluginInjectionAPI>, dispatchAnalyticsEvent: (payload: AnalyticsEventPayload) => void) => void;
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import type { WrappedComponentProps } from 'react-intl-next';
3
+ import type { CreateUIAnalyticsEvent } from '@atlaskit/analytics-next/types';
4
+ import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
5
+ import type { AllEditorPresetPluginTypes, EditorPresetBuilder } from '@atlaskit/editor-common/preset';
6
+ import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
7
+ import type { PortalProviderAPI } from '@atlaskit/editor-common/src/portal';
8
+ import type { PublicPluginAPI, Transformer } from '@atlaskit/editor-common/types';
9
+ import { EditorView } from '@atlaskit/editor-prosemirror/view';
10
+ import { EventDispatcher } from '../event-dispatcher';
11
+ import type { EditorConfig, EditorProps } from '../types';
12
+ import type { EditorNextProps } from '../types/editor-props';
13
+ export interface EditorViewProps extends WrappedComponentProps {
14
+ editorProps: (EditorProps | EditorNextProps) & {
15
+ preset?: EditorNextProps['preset'];
16
+ };
17
+ createAnalyticsEvent?: CreateUIAnalyticsEvent;
18
+ providerFactory: ProviderFactory;
19
+ portalProviderAPI: PortalProviderAPI;
20
+ disabled?: boolean;
21
+ render?: (props: {
22
+ editor: JSX.Element;
23
+ view?: EditorView;
24
+ config: EditorConfig;
25
+ eventDispatcher: EventDispatcher;
26
+ transformer?: Transformer<string>;
27
+ dispatchAnalyticsEvent: DispatchAnalyticsEvent;
28
+ editorRef: React.RefObject<HTMLDivElement>;
29
+ editorAPI: PublicPluginAPI<any> | undefined;
30
+ }) => JSX.Element;
31
+ onEditorCreated: (instance: {
32
+ view: EditorView;
33
+ config: EditorConfig;
34
+ eventDispatcher: EventDispatcher;
35
+ transformer?: Transformer<string>;
36
+ }) => void;
37
+ onEditorDestroyed: (instance: {
38
+ view: EditorView;
39
+ config: EditorConfig;
40
+ eventDispatcher: EventDispatcher;
41
+ transformer?: Transformer<string>;
42
+ }) => void;
43
+ preset: EditorPresetBuilder<string[], AllEditorPresetPluginTypes[]>;
44
+ }
45
+ declare const _default: React.FC<import("react-intl-next").WithIntlProps<EditorViewProps>> & {
46
+ WrappedComponent: React.ComponentType<EditorViewProps>;
47
+ };
48
+ export default _default;
@@ -1834,7 +1834,11 @@ export declare function createUniversalPreset({ props, prevProps, initialPluginC
1834
1834
  sharedState: import("@atlaskit/editor-common/types").FeatureFlags;
1835
1835
  }, import("@atlaskit/editor-common/types").FeatureFlags>>];
1836
1836
  actions: import("@atlaskit/editor-common/analytics").EditorAnalyticsAPI;
1837
- }, import("@atlaskit/editor-plugin-analytics").AnalyticsPluginOptions>>];
1837
+ }, import("@atlaskit/editor-plugin-analytics").AnalyticsPluginOptions>>, import("@atlaskit/editor-common/types").OptionalPlugin<import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"width", {
1838
+ sharedState: import("@atlaskit/editor-common/types").EditorContainerWidth | undefined;
1839
+ }, undefined>>, import("@atlaskit/editor-common/types").OptionalPlugin<import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"editorDisabled", {
1840
+ sharedState: import("@atlaskit/editor-plugin-editor-disabled").EditorDisabledPluginState;
1841
+ }, undefined>>];
1838
1842
  actions: {
1839
1843
  insertLayoutColumns: (inputMethod: import("@atlaskit/editor-common/types").TOOLBAR_MENU_TYPE, formatMessage?: {
1840
1844
  (descriptor: import("react-intl-next").MessageDescriptor, values?: Record<string, import("intl-messageformat").PrimitiveType | import("intl-messageformat").FormatXMLElementFn<string, string>> | undefined, opts?: import("intl-messageformat").Options | undefined): string;
@@ -4434,7 +4438,9 @@ export declare function createUniversalPreset({ props, prevProps, initialPluginC
4434
4438
  };
4435
4439
  }, {
4436
4440
  mode?: import("@atlaskit/editor-plugin-editor-viewmode").ViewMode | undefined;
4437
- } | undefined>>];
4441
+ } | undefined>>, import("@atlaskit/editor-common/types").OptionalPlugin<import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"editorDisabled", {
4442
+ sharedState: import("@atlaskit/editor-plugin-editor-disabled").EditorDisabledPluginState;
4443
+ }, undefined>>];
4438
4444
  sharedState: Partial<import("@atlaskit/editor-plugin-breakout").BreakoutPluginState>;
4439
4445
  }, import("@atlaskit/editor-plugin-breakout").BreakoutPluginOptions | undefined> | undefined, import("@atlaskit/editor-common/types").NextEditorPluginFunctionOptionalConfigDefinition<"batchAttributeUpdates", {
4440
4446
  actions: {