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