@atlaskit/editor-core 188.8.0 → 188.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/composable-editor/editor-internal.js +2 -2
  3. package/dist/cjs/create-editor/ReactEditorView.js +796 -8
  4. package/dist/cjs/labs/next/presets/universal.js +7 -4
  5. package/dist/cjs/plugins/index.js +0 -21
  6. package/dist/cjs/version-wrapper.js +1 -1
  7. package/dist/es2019/composable-editor/editor-internal.js +1 -1
  8. package/dist/es2019/create-editor/ReactEditorView.js +753 -2
  9. package/dist/es2019/labs/next/presets/universal.js +4 -1
  10. package/dist/es2019/plugins/index.js +0 -3
  11. package/dist/es2019/version-wrapper.js +1 -1
  12. package/dist/esm/composable-editor/editor-internal.js +1 -1
  13. package/dist/esm/create-editor/ReactEditorView.js +797 -8
  14. package/dist/esm/labs/next/presets/universal.js +4 -1
  15. package/dist/esm/plugins/index.js +0 -3
  16. package/dist/esm/version-wrapper.js +1 -1
  17. package/dist/types/create-editor/ReactEditorView.d.ts +119 -5
  18. package/dist/types/plugins/index.d.ts +0 -3
  19. package/dist/types/plugins/insert-block/types.d.ts +1 -1
  20. package/dist/types/plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates.d.ts +1 -1
  21. package/dist/types-ts4.5/create-editor/ReactEditorView.d.ts +119 -5
  22. package/dist/types-ts4.5/plugins/index.d.ts +0 -3
  23. package/dist/types-ts4.5/plugins/insert-block/types.d.ts +1 -1
  24. package/dist/types-ts4.5/plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates.d.ts +1 -1
  25. package/package.json +5 -3
  26. package/dist/cjs/create-editor/ReactEditorViewInternal.js +0 -812
  27. package/dist/cjs/create-editor/ReactEditorViewNext.js +0 -15
  28. package/dist/cjs/plugins/save-on-enter/index.js +0 -70
  29. package/dist/cjs/plugins/scroll-into-view/index.js +0 -55
  30. package/dist/cjs/plugins/status/actions.js +0 -158
  31. package/dist/cjs/plugins/status/analytics.js +0 -31
  32. package/dist/cjs/plugins/status/index.js +0 -143
  33. package/dist/cjs/plugins/status/keymap.js +0 -22
  34. package/dist/cjs/plugins/status/nodeviews/status.js +0 -58
  35. package/dist/cjs/plugins/status/plugin-key.js +0 -9
  36. package/dist/cjs/plugins/status/plugin.js +0 -133
  37. package/dist/cjs/plugins/status/types.js +0 -5
  38. package/dist/cjs/plugins/status/ui/statusPicker.js +0 -314
  39. package/dist/cjs/plugins/status/utils.js +0 -22
  40. package/dist/es2019/create-editor/ReactEditorViewInternal.js +0 -753
  41. package/dist/es2019/create-editor/ReactEditorViewNext.js +0 -7
  42. package/dist/es2019/plugins/save-on-enter/index.js +0 -63
  43. package/dist/es2019/plugins/scroll-into-view/index.js +0 -44
  44. package/dist/es2019/plugins/status/actions.js +0 -144
  45. package/dist/es2019/plugins/status/analytics.js +0 -18
  46. package/dist/es2019/plugins/status/index.js +0 -135
  47. package/dist/es2019/plugins/status/keymap.js +0 -13
  48. package/dist/es2019/plugins/status/nodeviews/status.js +0 -60
  49. package/dist/es2019/plugins/status/plugin-key.js +0 -3
  50. package/dist/es2019/plugins/status/plugin.js +0 -113
  51. package/dist/es2019/plugins/status/types.js +0 -1
  52. package/dist/es2019/plugins/status/ui/statusPicker.js +0 -293
  53. package/dist/es2019/plugins/status/utils.js +0 -12
  54. package/dist/esm/create-editor/ReactEditorViewInternal.js +0 -806
  55. package/dist/esm/create-editor/ReactEditorViewNext.js +0 -7
  56. package/dist/esm/plugins/save-on-enter/index.js +0 -63
  57. package/dist/esm/plugins/scroll-into-view/index.js +0 -50
  58. package/dist/esm/plugins/status/actions.js +0 -151
  59. package/dist/esm/plugins/status/analytics.js +0 -24
  60. package/dist/esm/plugins/status/index.js +0 -136
  61. package/dist/esm/plugins/status/keymap.js +0 -15
  62. package/dist/esm/plugins/status/nodeviews/status.js +0 -51
  63. package/dist/esm/plugins/status/plugin-key.js +0 -3
  64. package/dist/esm/plugins/status/plugin.js +0 -115
  65. package/dist/esm/plugins/status/types.js +0 -1
  66. package/dist/esm/plugins/status/ui/statusPicker.js +0 -308
  67. package/dist/esm/plugins/status/utils.js +0 -16
  68. package/dist/types/create-editor/ReactEditorViewInternal.d.ts +0 -119
  69. package/dist/types/create-editor/ReactEditorViewNext.d.ts +0 -8
  70. package/dist/types/plugins/save-on-enter/index.d.ts +0 -10
  71. package/dist/types/plugins/scroll-into-view/index.d.ts +0 -14
  72. package/dist/types/plugins/status/actions.d.ts +0 -16
  73. package/dist/types/plugins/status/analytics.d.ts +0 -4
  74. package/dist/types/plugins/status/index.d.ts +0 -15
  75. package/dist/types/plugins/status/keymap.d.ts +0 -3
  76. package/dist/types/plugins/status/nodeviews/status.d.ts +0 -25
  77. package/dist/types/plugins/status/plugin-key.d.ts +0 -4
  78. package/dist/types/plugins/status/plugin.d.ts +0 -7
  79. package/dist/types/plugins/status/types.d.ts +0 -18
  80. package/dist/types/plugins/status/ui/statusPicker.d.ts +0 -63
  81. package/dist/types/plugins/status/utils.d.ts +0 -5
  82. package/dist/types-ts4.5/create-editor/ReactEditorViewInternal.d.ts +0 -119
  83. package/dist/types-ts4.5/create-editor/ReactEditorViewNext.d.ts +0 -8
  84. package/dist/types-ts4.5/plugins/save-on-enter/index.d.ts +0 -10
  85. package/dist/types-ts4.5/plugins/scroll-into-view/index.d.ts +0 -14
  86. package/dist/types-ts4.5/plugins/status/actions.d.ts +0 -16
  87. package/dist/types-ts4.5/plugins/status/analytics.d.ts +0 -4
  88. package/dist/types-ts4.5/plugins/status/index.d.ts +0 -17
  89. package/dist/types-ts4.5/plugins/status/keymap.d.ts +0 -3
  90. package/dist/types-ts4.5/plugins/status/nodeviews/status.d.ts +0 -25
  91. package/dist/types-ts4.5/plugins/status/plugin-key.d.ts +0 -4
  92. package/dist/types-ts4.5/plugins/status/plugin.d.ts +0 -7
  93. package/dist/types-ts4.5/plugins/status/types.d.ts +0 -18
  94. package/dist/types-ts4.5/plugins/status/ui/statusPicker.d.ts +0 -63
  95. package/dist/types-ts4.5/plugins/status/utils.d.ts +0 -5
@@ -1,753 +0,0 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import React from 'react';
3
- import PropTypes from 'prop-types';
4
- import { EditorState, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
5
- import { EditorView } from '@atlaskit/editor-prosemirror/view';
6
- import { editorMessages } from './messages';
7
- import { browser, getAnalyticsEventSeverity, getResponseEndTime, measureRender, startMeasure, stopMeasure, shouldForceTracking, processRawValue, analyticsEventKey } from '@atlaskit/editor-common/utils';
8
- import { ExperienceStore, EditorExperience, RELIABILITY_INTERVAL } from '@atlaskit/editor-common/ufo';
9
- import { createDispatch, EventDispatcher } from '../event-dispatcher';
10
- import { freezeUnsafeTransactionProperties } from '../utils/performance/safer-transactions';
11
- import { RenderTracking } from '../utils/performance/components/RenderTracking';
12
- import { findChangedNodesFromTransaction, validateNodes, validNode } from '../utils/nodes';
13
- import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, FULL_WIDTH_MODE, PLATFORMS, getAnalyticsEventsFromTransaction } from '@atlaskit/editor-common/analytics';
14
- import { createFeatureFlagsFromProps } from './feature-flags-from-props';
15
- import { getEnabledFeatureFlagKeys } from '@atlaskit/editor-common/normalize-feature-flags';
16
- import { createErrorReporter, createPMPlugins, processPluginsList } from './create-editor';
17
- import { getDocStructure } from '../utils/document-logger';
18
- import { isFullPage } from '../utils/is-full-page';
19
- import measurements from '../utils/performance/measure-enum';
20
- import { getNodesCount } from '../utils/document';
21
- import { createSchema } from './create-schema';
22
- import { PluginPerformanceObserver } from '../utils/performance/plugin-performance-observer';
23
- import { getParticipantsCount } from '../plugins/collab-edit/get-participants-count';
24
- import { EVENT_NAME_DISPATCH_TRANSACTION, EVENT_NAME_STATE_APPLY, EVENT_NAME_UPDATE_STATE, EVENT_NAME_VIEW_STATE_UPDATED, EVENT_NAME_ON_CHANGE, TransactionTracker } from '../utils/performance/track-transactions';
25
- import { countNodes } from '@atlaskit/editor-common/utils';
26
- import createPluginsList from './create-plugins-list';
27
- import { PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD, PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD, DEFAULT_SAMPLING_RATE_VALID_TRANSACTIONS } from './consts';
28
- import ReactEditorViewContext from './ReactEditorViewContext';
29
- import { EditorPluginInjectionAPI } from '@atlaskit/editor-common/preset';
30
- import { EDIT_AREA_ID } from '@atlaskit/editor-common/ui';
31
- function handleEditorFocus(view) {
32
- if (view.hasFocus()) {
33
- return;
34
- }
35
- return window.setTimeout(() => {
36
- if (view.hasFocus()) {
37
- return;
38
- }
39
- if (!window.getSelection) {
40
- view.focus();
41
- return;
42
- }
43
- const domSelection = window.getSelection();
44
- if (!domSelection || domSelection.rangeCount === 0) {
45
- view.focus();
46
- return;
47
- }
48
- const range = domSelection.getRangeAt(0);
49
- // if selection is outside editor focus and exit
50
- if (range.startContainer.contains(view.dom)) {
51
- view.focus();
52
- return;
53
- }
54
- // set cursor/selection and focus
55
- const anchor = view.posAtDOM(range.startContainer, range.startOffset);
56
- const head = view.posAtDOM(range.endContainer, range.endOffset);
57
- // if anchor or head < 0 focus and exit
58
- if (anchor < 0 || head < 0) {
59
- view.focus();
60
- return;
61
- }
62
- const selection = TextSelection.create(view.state.doc, anchor, head);
63
- const tr = view.state.tr.setSelection(selection);
64
- view.dispatch(tr);
65
- view.focus();
66
- }, 0);
67
- }
68
- export class ReactEditorView extends React.Component {
69
- get transactionTracking() {
70
- var _this$props$editorPro, _this$props$editorPro2;
71
- return (_this$props$editorPro = (_this$props$editorPro2 = this.props.editorProps.performanceTracking) === null || _this$props$editorPro2 === void 0 ? void 0 : _this$props$editorPro2.transactionTracking) !== null && _this$props$editorPro !== void 0 ? _this$props$editorPro : {
72
- enabled: false
73
- };
74
- }
75
- getPluginNames() {
76
- return this.editorState.plugins.map(p => p.key);
77
- }
78
- countNodes() {
79
- return countNodes(this.editorState);
80
- }
81
- isTransactionTrackingExplicitlyDisabled() {
82
- var _this$props$editorPro3, _this$props$editorPro4, _this$props$editorPro5;
83
- // ED-16320: Check for explicit disable so that by default
84
- // it will still be enabled as it currently is. Then we can
85
- // progressively opt out synthetic tenants.
86
- return ((_this$props$editorPro3 = this.props.editorProps) === null || _this$props$editorPro3 === void 0 ? void 0 : (_this$props$editorPro4 = _this$props$editorPro3.performanceTracking) === null || _this$props$editorPro4 === void 0 ? void 0 : (_this$props$editorPro5 = _this$props$editorPro4.transactionTracking) === null || _this$props$editorPro5 === void 0 ? void 0 : _this$props$editorPro5.enabled) === false;
87
- }
88
- constructor(props, context) {
89
- var _props$setEditorApi, _props$editorProps, _props$editorProps$pe, _props$editorProps$pe2;
90
- super(props, context);
91
- _defineProperty(this, "editorRef", /*#__PURE__*/React.createRef());
92
- // ProseMirror is instantiated prior to the initial React render cycle,
93
- // so we allow transactions by default, to avoid discarding the initial one.
94
- _defineProperty(this, "canDispatchTransactions", true);
95
- _defineProperty(this, "onPluginObservation", (report, editorState) => {
96
- this.dispatchAnalyticsEvent({
97
- action: ACTION.TRANSACTION_DISPATCHED,
98
- actionSubject: ACTION_SUBJECT.EDITOR,
99
- eventType: EVENT_TYPE.OPERATIONAL,
100
- attributes: {
101
- report,
102
- participants: getParticipantsCount(editorState)
103
- }
104
- });
105
- });
106
- _defineProperty(this, "getEditorState", () => {
107
- var _this$view;
108
- return (_this$view = this.view) === null || _this$view === void 0 ? void 0 : _this$view.state;
109
- });
110
- _defineProperty(this, "getEditorView", () => this.view);
111
- _defineProperty(this, "formatFullWidthAppearance", appearance => {
112
- if (appearance === 'full-width') {
113
- return FULL_WIDTH_MODE.FULL_WIDTH;
114
- }
115
- return FULL_WIDTH_MODE.FIXED_WIDTH;
116
- });
117
- _defineProperty(this, "resetEditorState", ({
118
- doc,
119
- shouldScrollToBottom
120
- }) => {
121
- var _this$props$editorPro6, _this$props$editorPro7;
122
- if (!this.view) {
123
- return;
124
- }
125
-
126
- // We cannot currently guarentee when all the portals will have re-rendered during a reconfigure
127
- // so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
128
- // nodes that haven't been re-rendered to the document yet.
129
- this.blur();
130
- this.featureFlags = createFeatureFlagsFromProps(this.props.editorProps);
131
- this.editorState = this.createEditorState({
132
- props: this.props,
133
- context: this.context,
134
- doc: doc,
135
- resetting: true,
136
- selectionAtStart: !shouldScrollToBottom
137
- });
138
- this.view.updateState(this.editorState);
139
- (_this$props$editorPro6 = (_this$props$editorPro7 = this.props.editorProps).onChange) === null || _this$props$editorPro6 === void 0 ? void 0 : _this$props$editorPro6.call(_this$props$editorPro7, this.view, {
140
- source: 'local'
141
- });
142
- });
143
- _defineProperty(this, "blur", () => {
144
- if (!this.view) {
145
- return;
146
- }
147
- if (this.view.dom instanceof HTMLElement && this.view.hasFocus()) {
148
- this.view.dom.blur();
149
- }
150
-
151
- // The selectionToDOM method uses the document selection to determine currently selected node
152
- // We need to mimic blurring this as it seems doing the above is not enough.
153
- // @ts-expect-error
154
- const sel = this.view.root.getSelection();
155
- if (sel) {
156
- sel.removeAllRanges();
157
- }
158
- });
159
- _defineProperty(this, "handleAnalyticsEvent", payload => {
160
- fireAnalyticsEvent(this.props.createAnalyticsEvent)(payload);
161
- });
162
- _defineProperty(this, "editorPlugins", []);
163
- _defineProperty(this, "createEditorState", options => {
164
- let schema;
165
- if (this.view) {
166
- if (options.resetting) {
167
- /**
168
- * ReactEditorView currently does NOT handle dynamic schema,
169
- * We are reusing the existing schema, and rely on #reconfigureState
170
- * to update `this.config`
171
- */
172
- schema = this.view.state.schema;
173
- } else {
174
- /**
175
- * There's presently a number of issues with changing the schema of a
176
- * editor inflight. A significant issue is that we lose the ability
177
- * to keep track of a user's history as the internal plugin state
178
- * keeps a list of Steps to undo/redo (which are tied to the schema).
179
- * Without a good way to do work around this, we prevent this for now.
180
- */
181
- // eslint-disable-next-line no-console
182
- console.warn('The editor does not support changing the schema dynamically.');
183
- return this.editorState;
184
- }
185
- } else {
186
- this.config = processPluginsList(this.getPlugins(options.props.preset));
187
- schema = createSchema(this.config);
188
- }
189
- const {
190
- contentTransformerProvider
191
- } = options.props.editorProps;
192
- const plugins = createPMPlugins({
193
- schema,
194
- dispatch: this.dispatch,
195
- errorReporter: this.errorReporter,
196
- editorConfig: this.config,
197
- eventDispatcher: this.eventDispatcher,
198
- providerFactory: options.props.providerFactory,
199
- portalProviderAPI: this.props.portalProviderAPI,
200
- reactContext: () => options.context,
201
- dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
202
- performanceTracking: this.props.editorProps.performanceTracking,
203
- transactionTracker: this.transactionTracker,
204
- featureFlags: this.featureFlags,
205
- getIntl: () => this.props.intl
206
- });
207
- this.contentTransformer = contentTransformerProvider ? contentTransformerProvider(schema) : undefined;
208
- let doc;
209
- if (options.doc) {
210
- doc = processRawValue(schema, options.doc, options.props.providerFactory, options.props.editorProps.sanitizePrivateContent, this.contentTransformer, this.dispatchAnalyticsEvent);
211
- }
212
- let selection;
213
- if (doc) {
214
- selection = options.selectionAtStart ? Selection.atStart(doc) : Selection.atEnd(doc);
215
- }
216
- // Workaround for ED-3507: When media node is the last element, scrollIntoView throws an error
217
- const patchedSelection = selection ? Selection.findFrom(selection.$head, -1, true) || undefined : undefined;
218
- return EditorState.create({
219
- schema,
220
- plugins: plugins,
221
- doc,
222
- selection: patchedSelection
223
- });
224
- });
225
- _defineProperty(this, "onEditorViewStateUpdated", ({
226
- originalTransaction,
227
- transactions,
228
- oldEditorState,
229
- newEditorState
230
- }) => {
231
- const {
232
- enabled: trackinEnabled
233
- } = this.transactionTracking;
234
- this.config.onEditorViewStateUpdatedCallbacks.forEach(entry => {
235
- trackinEnabled && startMeasure(`🦉 ${entry.pluginName}::onEditorViewStateUpdated`);
236
- entry.callback({
237
- originalTransaction,
238
- transactions,
239
- oldEditorState,
240
- newEditorState
241
- });
242
- trackinEnabled && stopMeasure(`🦉 ${entry.pluginName}::onEditorViewStateUpdated`);
243
- });
244
- });
245
- _defineProperty(this, "trackValidTransactions", () => {
246
- const {
247
- editorProps
248
- } = this.props;
249
- if (!this.isTransactionTrackingExplicitlyDisabled() && editorProps !== null && editorProps !== void 0 && editorProps.trackValidTransactions) {
250
- this.validTransactionCount++;
251
- const samplingRate = typeof editorProps.trackValidTransactions === 'object' && editorProps.trackValidTransactions.samplingRate || DEFAULT_SAMPLING_RATE_VALID_TRANSACTIONS;
252
- if (this.validTransactionCount >= samplingRate) {
253
- this.dispatchAnalyticsEvent({
254
- action: ACTION.DISPATCHED_VALID_TRANSACTION,
255
- actionSubject: ACTION_SUBJECT.EDITOR,
256
- eventType: EVENT_TYPE.OPERATIONAL
257
- });
258
- this.validTransactionCount = 0;
259
- }
260
- }
261
- });
262
- _defineProperty(this, "dispatchTransaction", unsafeTransaction => {
263
- if (!this.view) {
264
- return;
265
- }
266
- this.transactionTracker.bumpDispatchCounter(this.transactionTracking);
267
- const {
268
- startMeasure,
269
- stopMeasure
270
- } = this.transactionTracker.getMeasureHelpers(this.transactionTracking);
271
- startMeasure(EVENT_NAME_DISPATCH_TRANSACTION);
272
- if (this.transactionTracker.shouldTrackTransaction(this.transactionTracking)) {
273
- var _this$experienceStore;
274
- (_this$experienceStore = this.experienceStore) === null || _this$experienceStore === void 0 ? void 0 : _this$experienceStore.start(EditorExperience.interaction);
275
- }
276
- const nodes = findChangedNodesFromTransaction(unsafeTransaction);
277
- const changedNodesValid = validateNodes(nodes);
278
- const transaction = this.featureFlags.saferDispatchedTransactions || this.featureFlags.saferDispatchedTransactionsAnalyticsOnly ? new Proxy(unsafeTransaction, freezeUnsafeTransactionProperties({
279
- dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
280
- pluginKey: 'unknown-reacteditorview',
281
- analyticsOnly: this.featureFlags.saferDispatchedTransactionsAnalyticsOnly
282
- })) : unsafeTransaction;
283
- if (changedNodesValid) {
284
- const oldEditorState = this.view.state;
285
-
286
- // go ahead and update the state now we know the transaction is good
287
- startMeasure(EVENT_NAME_STATE_APPLY);
288
- const {
289
- state: editorState,
290
- transactions
291
- } = this.view.state.applyTransaction(transaction);
292
- stopMeasure(EVENT_NAME_STATE_APPLY, (duration, startTime) => {
293
- var _this$experienceStore2;
294
- (_this$experienceStore2 = this.experienceStore) === null || _this$experienceStore2 === void 0 ? void 0 : _this$experienceStore2.mark(EditorExperience.interaction, 'stateApply', startTime + duration);
295
- });
296
- this.trackValidTransactions();
297
- if (editorState === oldEditorState) {
298
- return;
299
- }
300
- startMeasure(EVENT_NAME_UPDATE_STATE);
301
- this.view.updateState(editorState);
302
- stopMeasure(EVENT_NAME_UPDATE_STATE, (duration, startTime) => {
303
- var _this$experienceStore3;
304
- (_this$experienceStore3 = this.experienceStore) === null || _this$experienceStore3 === void 0 ? void 0 : _this$experienceStore3.mark(EditorExperience.interaction, 'viewUpdateState', startTime + duration);
305
- });
306
- this.pluginInjectionAPI.onEditorViewUpdated({
307
- newEditorState: editorState,
308
- oldEditorState
309
- });
310
- startMeasure(EVENT_NAME_VIEW_STATE_UPDATED);
311
- this.onEditorViewStateUpdated({
312
- originalTransaction: transaction,
313
- transactions,
314
- oldEditorState,
315
- newEditorState: editorState
316
- });
317
- stopMeasure(EVENT_NAME_VIEW_STATE_UPDATED, (duration, startTime) => {
318
- var _this$experienceStore4;
319
- (_this$experienceStore4 = this.experienceStore) === null || _this$experienceStore4 === void 0 ? void 0 : _this$experienceStore4.mark(EditorExperience.interaction, 'onEditorViewStateUpdated', startTime + duration);
320
- });
321
- if (this.props.editorProps.onChange && transaction.docChanged) {
322
- const source = transaction.getMeta('isRemote') ? 'remote' : 'local';
323
- startMeasure(EVENT_NAME_ON_CHANGE);
324
- this.props.editorProps.onChange(this.view, {
325
- source
326
- });
327
- stopMeasure(EVENT_NAME_ON_CHANGE, (duration, startTime) => {
328
- var _this$experienceStore5, _this$props$editorPro8, _this$props$editorPro9;
329
- (_this$experienceStore5 = this.experienceStore) === null || _this$experienceStore5 === void 0 ? void 0 : _this$experienceStore5.mark(EditorExperience.interaction, 'onChange', startTime + duration);
330
- if (((_this$props$editorPro8 = this.props.editorProps.performanceTracking) === null || _this$props$editorPro8 === void 0 ? void 0 : (_this$props$editorPro9 = _this$props$editorPro8.onChangeCallbackTracking) === null || _this$props$editorPro9 === void 0 ? void 0 : _this$props$editorPro9.enabled) !== true) {
331
- return;
332
- }
333
- this.dispatchAnalyticsEvent({
334
- action: ACTION.ON_CHANGE_CALLBACK,
335
- actionSubject: ACTION_SUBJECT.EDITOR,
336
- eventType: EVENT_TYPE.OPERATIONAL,
337
- attributes: {
338
- duration,
339
- startTime
340
- }
341
- });
342
- });
343
- }
344
- this.editorState = editorState;
345
- stopMeasure(EVENT_NAME_DISPATCH_TRANSACTION, (duration, startTime) => {
346
- var _this$experienceStore6, _this$experienceStore7;
347
- (_this$experienceStore6 = this.experienceStore) === null || _this$experienceStore6 === void 0 ? void 0 : _this$experienceStore6.mark(EditorExperience.interaction, 'dispatchTransaction', startTime + duration);
348
- (_this$experienceStore7 = this.experienceStore) === null || _this$experienceStore7 === void 0 ? void 0 : _this$experienceStore7.success(EditorExperience.interaction);
349
- });
350
- } else {
351
- var _this$experienceStore8;
352
- const invalidNodes = nodes.filter(node => !validNode(node)).map(node => getDocStructure(node, {
353
- compact: true
354
- }));
355
- if (!this.isTransactionTrackingExplicitlyDisabled()) {
356
- this.dispatchAnalyticsEvent({
357
- action: ACTION.DISPATCHED_INVALID_TRANSACTION,
358
- actionSubject: ACTION_SUBJECT.EDITOR,
359
- eventType: EVENT_TYPE.OPERATIONAL,
360
- attributes: {
361
- analyticsEventPayloads: getAnalyticsEventsFromTransaction(transaction),
362
- invalidNodes
363
- }
364
- });
365
- }
366
- (_this$experienceStore8 = this.experienceStore) === null || _this$experienceStore8 === void 0 ? void 0 : _this$experienceStore8.fail(EditorExperience.interaction, {
367
- reason: 'invalid transaction',
368
- invalidNodes: invalidNodes.toString()
369
- });
370
- }
371
- });
372
- _defineProperty(this, "getDirectEditorProps", state => {
373
- return {
374
- state: state || this.editorState,
375
- dispatchTransaction: tr => {
376
- // Block stale transactions:
377
- // Prevent runtime exeptions from async transactions that would attempt to
378
- // update the DOM after React has unmounted the Editor.
379
- if (this.canDispatchTransactions) {
380
- this.dispatchTransaction(tr);
381
- }
382
- },
383
- // Disables the contentEditable attribute of the editor if the editor is disabled
384
- editable: _state => !this.props.editorProps.disabled,
385
- attributes: {
386
- 'data-gramm': 'false'
387
- }
388
- };
389
- });
390
- _defineProperty(this, "createEditorView", node => {
391
- measureRender(measurements.PROSEMIRROR_RENDERED, ({
392
- duration,
393
- startTime,
394
- distortedDuration
395
- }) => {
396
- var _this$props$editorPro10, _this$props$editorPro11, _proseMirrorRenderedT, _proseMirrorRenderedT2;
397
- const proseMirrorRenderedTracking = (_this$props$editorPro10 = this.props.editorProps) === null || _this$props$editorPro10 === void 0 ? void 0 : (_this$props$editorPro11 = _this$props$editorPro10.performanceTracking) === null || _this$props$editorPro11 === void 0 ? void 0 : _this$props$editorPro11.proseMirrorRenderedTracking;
398
- const forceSeverityTracking = typeof proseMirrorRenderedTracking === 'undefined' && shouldForceTracking();
399
- this.proseMirrorRenderedSeverity = !!forceSeverityTracking || proseMirrorRenderedTracking !== null && proseMirrorRenderedTracking !== void 0 && proseMirrorRenderedTracking.trackSeverity ? getAnalyticsEventSeverity(duration, (_proseMirrorRenderedT = proseMirrorRenderedTracking === null || proseMirrorRenderedTracking === void 0 ? void 0 : proseMirrorRenderedTracking.severityNormalThreshold) !== null && _proseMirrorRenderedT !== void 0 ? _proseMirrorRenderedT : PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD, (_proseMirrorRenderedT2 = proseMirrorRenderedTracking === null || proseMirrorRenderedTracking === void 0 ? void 0 : proseMirrorRenderedTracking.severityDegradedThreshold) !== null && _proseMirrorRenderedT2 !== void 0 ? _proseMirrorRenderedT2 : PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD) : undefined;
400
- if (this.view) {
401
- var _this$pluginInjection, _this$experienceStore10;
402
- const nodes = getNodesCount(this.view.state.doc);
403
- const ttfb = getResponseEndTime();
404
- const contextIdentifier = (_this$pluginInjection = this.pluginInjectionAPI.api().base) === null || _this$pluginInjection === void 0 ? void 0 : _this$pluginInjection.sharedState.currentState();
405
- this.dispatchAnalyticsEvent({
406
- action: ACTION.PROSEMIRROR_RENDERED,
407
- actionSubject: ACTION_SUBJECT.EDITOR,
408
- attributes: {
409
- duration,
410
- startTime,
411
- nodes,
412
- ttfb,
413
- severity: this.proseMirrorRenderedSeverity,
414
- objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
415
- distortedDuration
416
- },
417
- eventType: EVENT_TYPE.OPERATIONAL
418
- });
419
- if (!distortedDuration) {
420
- var _this$experienceStore9;
421
- (_this$experienceStore9 = this.experienceStore) === null || _this$experienceStore9 === void 0 ? void 0 : _this$experienceStore9.mark(EditorExperience.loadEditor, ACTION.PROSEMIRROR_RENDERED, startTime + duration);
422
- }
423
- (_this$experienceStore10 = this.experienceStore) === null || _this$experienceStore10 === void 0 ? void 0 : _this$experienceStore10.addMetadata(EditorExperience.loadEditor, {
424
- nodes,
425
- ttfb
426
- });
427
- }
428
- });
429
-
430
- // Creates the editor-view from this.editorState. If an editor has been mounted
431
- // previously, this will contain the previous state of the editor.
432
- this.view = new EditorView({
433
- mount: node
434
- }, this.getDirectEditorProps());
435
- this.pluginInjectionAPI.onEditorViewUpdated({
436
- newEditorState: this.view.state,
437
- oldEditorState: undefined
438
- });
439
- });
440
- _defineProperty(this, "handleEditorViewRef", node => {
441
- if (!this.view && node) {
442
- this.createEditorView(node);
443
- const view = this.view;
444
- this.props.onEditorCreated({
445
- view,
446
- config: this.config,
447
- eventDispatcher: this.eventDispatcher,
448
- transformer: this.contentTransformer
449
- });
450
- if (this.props.editorProps.shouldFocus && view.props.editable && view.props.editable(view.state)) {
451
- this.focusTimeoutId = handleEditorFocus(view);
452
- }
453
- if (this.featureFlags.ufo) {
454
- this.experienceStore = ExperienceStore.getInstance(view);
455
- this.experienceStore.start(EditorExperience.editSession);
456
- this.experienceStore.addMetadata(EditorExperience.editSession, {
457
- reliabilityInterval: RELIABILITY_INTERVAL
458
- });
459
- this.reliabilityInterval = window.setInterval(() => {
460
- var _this$experienceStore11, _this$experienceStore12;
461
- (_this$experienceStore11 = this.experienceStore) === null || _this$experienceStore11 === void 0 ? void 0 : (_this$experienceStore12 = _this$experienceStore11.success(EditorExperience.editSession)) === null || _this$experienceStore12 === void 0 ? void 0 : _this$experienceStore12.finally(() => {
462
- var _this$experienceStore13, _this$experienceStore14;
463
- (_this$experienceStore13 = this.experienceStore) === null || _this$experienceStore13 === void 0 ? void 0 : _this$experienceStore13.start(EditorExperience.editSession);
464
- (_this$experienceStore14 = this.experienceStore) === null || _this$experienceStore14 === void 0 ? void 0 : _this$experienceStore14.addMetadata(EditorExperience.editSession, {
465
- reliabilityInterval: RELIABILITY_INTERVAL
466
- });
467
- });
468
- const reliabilityEvent = {
469
- action: ACTION.UFO_SESSION_COMPLETE,
470
- actionSubject: ACTION_SUBJECT.EDITOR,
471
- attributes: {
472
- interval: RELIABILITY_INTERVAL
473
- },
474
- eventType: EVENT_TYPE.OPERATIONAL
475
- };
476
- this.dispatchAnalyticsEvent(reliabilityEvent);
477
- }, RELIABILITY_INTERVAL);
478
- }
479
-
480
- // Force React to re-render so consumers get a reference to the editor view
481
- this.forceUpdate();
482
- } else if (this.view && !node) {
483
- // When the appearance is changed, React will call handleEditorViewRef with node === null
484
- // to destroy the old EditorView, before calling this method again with node === div to
485
- // create the new EditorView
486
- this.props.onEditorDestroyed({
487
- view: this.view,
488
- config: this.config,
489
- eventDispatcher: this.eventDispatcher,
490
- transformer: this.contentTransformer
491
- });
492
-
493
- // Allows us to dispatch analytics within the plugin view.destory methods
494
- const analyticsConnected = this.eventDispatcher.has(analyticsEventKey, this.handleAnalyticsEvent);
495
- if (!analyticsConnected) {
496
- this.eventDispatcher.on(analyticsEventKey, this.handleAnalyticsEvent);
497
- }
498
- this.view.destroy(); // Destroys the dom node & all node views
499
-
500
- if (!analyticsConnected) {
501
- this.eventDispatcher.off(analyticsEventKey, this.handleAnalyticsEvent);
502
- }
503
- this.view = undefined;
504
- }
505
- });
506
- _defineProperty(this, "dispatchAnalyticsEvent", payload => {
507
- if (this.eventDispatcher) {
508
- const dispatch = createDispatch(this.eventDispatcher);
509
- dispatch(analyticsEventKey, {
510
- payload
511
- });
512
- }
513
- });
514
- _defineProperty(this, "createEditor", assistiveLabel => {
515
- return /*#__PURE__*/React.createElement("div", {
516
- className: getUAPrefix(),
517
- key: "ProseMirror",
518
- ref: this.handleEditorViewRef,
519
- "aria-label": assistiveLabel || this.props.intl.formatMessage(editorMessages.editorAssistiveLabel)
520
- // setting aria-multiline to true when not mobile appearance.
521
- // because somehow mobile tests are failing when it set.
522
- // don't know why that is happening.
523
- // Created https://product-fabric.atlassian.net/jira/servicedesk/projects/DTR/queues/issue/DTR-1675
524
- // to investigate further.
525
- ,
526
- "aria-multiline": this.props.editorProps.appearance !== 'mobile' ? true : false,
527
- role: "textbox",
528
- id: EDIT_AREA_ID
529
- });
530
- });
531
- _defineProperty(this, "editor", this.createEditor(this.props.editorProps.assistiveLabel));
532
- this.pluginInjectionAPI = new EditorPluginInjectionAPI({
533
- getEditorState: this.getEditorState,
534
- getEditorView: this.getEditorView
535
- });
536
- (_props$setEditorApi = props.setEditorApi) === null || _props$setEditorApi === void 0 ? void 0 : _props$setEditorApi.call(props, this.pluginInjectionAPI.api());
537
- this.eventDispatcher = new EventDispatcher();
538
- this.dispatch = createDispatch(this.eventDispatcher);
539
- this.errorReporter = createErrorReporter(props.editorProps.errorReporterHandler);
540
- this.transactionTracker = new TransactionTracker();
541
- this.pluginPerformanceObserver = new PluginPerformanceObserver(report => this.onPluginObservation(report, this.editorState)).withPlugins(() => this.getPluginNames()).withNodeCounts(() => this.countNodes()).withOptions(() => this.transactionTracking).withTransactionTracker(() => this.transactionTracker);
542
- this.validTransactionCount = 0;
543
- this.featureFlags = createFeatureFlagsFromProps(this.props.editorProps);
544
- const featureFlagsEnabled = this.featureFlags ? getEnabledFeatureFlagKeys(this.featureFlags) : [];
545
-
546
- // START TEMPORARY CODE ED-10584
547
- if (this.props.createAnalyticsEvent) {
548
- this.props.createAnalyticsEvent.__queueAnalytics = this.featureFlags.queueAnalytics;
549
- }
550
- // END TEMPORARY CODE ED-10584
551
-
552
- // This needs to be before initialising editorState because
553
- // we dispatch analytics events in plugin initialisation
554
- this.eventDispatcher.on(analyticsEventKey, this.handleAnalyticsEvent);
555
- this.eventDispatcher.on('resetEditorState', this.resetEditorState);
556
- this.editorState = this.createEditorState({
557
- props,
558
- context,
559
- doc: props.editorProps.defaultValue,
560
- // ED-4759: Don't set selection at end for full-page editor - should be at start.
561
- selectionAtStart: isFullPage(props.editorProps.appearance)
562
- });
563
-
564
- // ED-16320: Check for explicit disable so that by default
565
- // it will still be enabled as it currently is. Then we can
566
- // progressively opt out synthetic tenants.
567
- const isEditorStartedExplicitlyDisabled = ((_props$editorProps = props.editorProps) === null || _props$editorProps === void 0 ? void 0 : (_props$editorProps$pe = _props$editorProps.performanceTracking) === null || _props$editorProps$pe === void 0 ? void 0 : (_props$editorProps$pe2 = _props$editorProps$pe.startedTracking) === null || _props$editorProps$pe2 === void 0 ? void 0 : _props$editorProps$pe2.enabled) === false;
568
- if (!isEditorStartedExplicitlyDisabled) {
569
- this.dispatchAnalyticsEvent({
570
- action: ACTION.STARTED,
571
- actionSubject: ACTION_SUBJECT.EDITOR,
572
- attributes: {
573
- platform: PLATFORMS.WEB,
574
- featureFlags: featureFlagsEnabled
575
- },
576
- eventType: EVENT_TYPE.UI
577
- });
578
- }
579
- }
580
- UNSAFE_componentWillReceiveProps(nextProps) {
581
- // START TEMPORARY CODE ED-10584
582
- if (nextProps.createAnalyticsEvent && nextProps.createAnalyticsEvent !== this.props.createAnalyticsEvent) {
583
- const featureFlags = createFeatureFlagsFromProps(nextProps.editorProps);
584
- nextProps.createAnalyticsEvent.__queueAnalytics = featureFlags.queueAnalytics;
585
- }
586
- // END TEMPORARY CODE ED-10584
587
-
588
- if (this.view && this.props.editorProps.disabled !== nextProps.editorProps.disabled) {
589
- // Disables the contentEditable attribute of the editor if the editor is disabled
590
- this.view.setProps({
591
- editable: _state => !nextProps.editorProps.disabled
592
- });
593
- if (!nextProps.editorProps.disabled && nextProps.editorProps.shouldFocus) {
594
- this.focusTimeoutId = handleEditorFocus(this.view);
595
- }
596
- }
597
- const {
598
- appearance
599
- } = this.props.editorProps;
600
- const {
601
- appearance: nextAppearance
602
- } = nextProps.editorProps;
603
- if (this.props.preset !== nextProps.preset) {
604
- this.reconfigureState(nextProps);
605
- }
606
- if (nextAppearance !== appearance) {
607
- if (nextAppearance === 'full-width' || appearance === 'full-width') {
608
- this.dispatchAnalyticsEvent({
609
- action: ACTION.CHANGED_FULL_WIDTH_MODE,
610
- actionSubject: ACTION_SUBJECT.EDITOR,
611
- eventType: EVENT_TYPE.TRACK,
612
- attributes: {
613
- previousMode: this.formatFullWidthAppearance(appearance),
614
- newMode: this.formatFullWidthAppearance(nextAppearance)
615
- }
616
- });
617
- }
618
- }
619
- if (!this.transactionTracking.enabled) {
620
- this.pluginPerformanceObserver.disconnect();
621
- }
622
- if (nextProps.editorProps.assistiveLabel !== this.props.editorProps.assistiveLabel) {
623
- this.editor = this.createEditor(nextProps.editorProps.assistiveLabel);
624
- }
625
- }
626
- reconfigureState(props) {
627
- if (!this.view) {
628
- return;
629
- }
630
-
631
- // We cannot currently guarentee when all the portals will have re-rendered during a reconfigure
632
- // so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
633
- // nodes that haven't been re-rendered to the document yet.
634
- this.blur();
635
- const editorPlugins = this.getPlugins(props.preset);
636
- this.config = processPluginsList(editorPlugins);
637
- const state = this.editorState;
638
- const plugins = createPMPlugins({
639
- schema: state.schema,
640
- dispatch: this.dispatch,
641
- errorReporter: this.errorReporter,
642
- editorConfig: this.config,
643
- eventDispatcher: this.eventDispatcher,
644
- providerFactory: props.providerFactory,
645
- portalProviderAPI: props.portalProviderAPI,
646
- reactContext: () => this.context,
647
- dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
648
- performanceTracking: props.editorProps.performanceTracking,
649
- transactionTracker: this.transactionTracker,
650
- featureFlags: createFeatureFlagsFromProps(props.editorProps),
651
- getIntl: () => this.props.intl
652
- });
653
- const newState = state.reconfigure({
654
- plugins: plugins
655
- });
656
-
657
- // need to update the state first so when the view builds the nodeviews it is
658
- // using the latest plugins
659
- this.view.updateState(newState);
660
- return this.view.update({
661
- ...this.view.props,
662
- state: newState
663
- });
664
- }
665
- componentDidMount() {
666
- // Transaction dispatching is already enabled by default prior to
667
- // mounting, but we reset it here, just in case the editor view
668
- // instance is ever recycled (mounted again after unmounting) with
669
- // the same key.
670
- // Although storing mounted state is an anti-pattern in React,
671
- // we do so here so that we can intercept and abort asynchronous
672
- // ProseMirror transactions when a dismount is imminent.
673
- this.canDispatchTransactions = true;
674
- if (this.transactionTracking.enabled) {
675
- this.pluginPerformanceObserver.observe();
676
- }
677
- }
678
-
679
- /**
680
- * Clean up any non-PM resources when the editor is unmounted
681
- */
682
- componentWillUnmount() {
683
- // We can ignore any transactions from this point onwards.
684
- // This serves to avoid potential runtime exceptions which could arise
685
- // from an async dispatched transaction after it's unmounted.
686
- this.canDispatchTransactions = false;
687
- clearTimeout(this.focusTimeoutId);
688
- if (this.reliabilityInterval) {
689
- clearInterval(this.reliabilityInterval);
690
- }
691
- this.pluginPerformanceObserver.disconnect();
692
- if (this.view) {
693
- // Destroy the state if the Editor is being unmounted
694
- const editorState = this.view.state;
695
- editorState.plugins.forEach(plugin => {
696
- const state = plugin.getState(editorState);
697
- if (state && state.destroy) {
698
- state.destroy();
699
- }
700
- });
701
- }
702
- this.eventDispatcher.destroy();
703
- // this.view will be destroyed when React unmounts in handleEditorViewRef
704
- }
705
-
706
- // Helper to allow tests to inject plugins directly
707
- getPlugins(preset) {
708
- const plugins = createPluginsList(preset, this.props.editorProps, this.pluginInjectionAPI);
709
- this.editorPlugins = plugins;
710
- return this.editorPlugins;
711
- }
712
- render() {
713
- var _this$props$editorPro12, _this$props$editorPro13;
714
- const renderTracking = (_this$props$editorPro12 = this.props.editorProps.performanceTracking) === null || _this$props$editorPro12 === void 0 ? void 0 : (_this$props$editorPro13 = _this$props$editorPro12.renderTracking) === null || _this$props$editorPro13 === void 0 ? void 0 : _this$props$editorPro13.reactEditorView;
715
- const renderTrackingEnabled = renderTracking === null || renderTracking === void 0 ? void 0 : renderTracking.enabled;
716
- const useShallow = renderTracking === null || renderTracking === void 0 ? void 0 : renderTracking.useShallow;
717
- return /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
718
- value: {
719
- editorRef: this.editorRef,
720
- editorView: this.view
721
- }
722
- }, renderTrackingEnabled && /*#__PURE__*/React.createElement(RenderTracking, {
723
- componentProps: this.props,
724
- action: ACTION.RE_RENDERED,
725
- actionSubject: ACTION_SUBJECT.REACT_EDITOR_VIEW,
726
- handleAnalyticsEvent: this.handleAnalyticsEvent,
727
- useShallow: useShallow
728
- }), this.props.render ? this.props.render({
729
- editor: this.editor,
730
- view: this.view,
731
- config: this.config,
732
- eventDispatcher: this.eventDispatcher,
733
- transformer: this.contentTransformer,
734
- dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
735
- editorRef: this.editorRef
736
- }) : this.editor);
737
- }
738
- }
739
- _defineProperty(ReactEditorView, "contextTypes", {
740
- getAtlaskitAnalyticsEventHandlers: PropTypes.func
741
- });
742
- function getUAPrefix() {
743
- if (browser.chrome) {
744
- return 'ua-chrome';
745
- } else if (browser.ie) {
746
- return 'ua-ie';
747
- } else if (browser.gecko) {
748
- return 'ua-firefox';
749
- } else if (browser.safari) {
750
- return 'ua-safari';
751
- }
752
- return '';
753
- }