@atlaskit/editor-core 201.2.0 → 201.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/cjs/composable-editor/core-editor.js +8 -6
- package/dist/cjs/composable-editor/editor-internal.js +1 -1
- package/dist/cjs/create-editor/ReactEditorView/useDispatchTransaction.js +0 -1
- package/dist/cjs/create-editor/ReactEditorView/usePluginPerformanceObserver.js +7 -6
- package/dist/cjs/create-editor/ReactEditorView.js +3 -3
- package/dist/cjs/create-editor/ReactEditorViewNext.js +56 -45
- package/dist/cjs/create-editor/create-plugins-list.js +1 -1
- package/dist/cjs/create-editor/create-universal-preset.js +1 -1
- package/dist/cjs/create-editor/feature-flags-from-props.js +9 -11
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/composable-editor/core-editor.js +5 -1
- package/dist/es2019/composable-editor/editor-internal.js +1 -1
- package/dist/es2019/create-editor/ReactEditorView/useDispatchTransaction.js +0 -1
- package/dist/es2019/create-editor/ReactEditorView/usePluginPerformanceObserver.js +11 -8
- package/dist/es2019/create-editor/ReactEditorView.js +3 -3
- package/dist/es2019/create-editor/ReactEditorViewNext.js +47 -42
- package/dist/es2019/create-editor/create-plugins-list.js +1 -1
- package/dist/es2019/create-editor/create-universal-preset.js +1 -1
- package/dist/es2019/create-editor/feature-flags-from-props.js +9 -11
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/composable-editor/core-editor.js +7 -1
- package/dist/esm/composable-editor/editor-internal.js +1 -1
- package/dist/esm/create-editor/ReactEditorView/useDispatchTransaction.js +0 -1
- package/dist/esm/create-editor/ReactEditorView/usePluginPerformanceObserver.js +7 -6
- package/dist/esm/create-editor/ReactEditorView.js +3 -3
- package/dist/esm/create-editor/ReactEditorViewNext.js +56 -45
- package/dist/esm/create-editor/create-plugins-list.js +1 -1
- package/dist/esm/create-editor/create-universal-preset.js +1 -1
- package/dist/esm/create-editor/feature-flags-from-props.js +9 -11
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/create-editor/ReactEditorView/useDispatchTransaction.d.ts +2 -2
- package/dist/types/create-editor/ReactEditorView/usePluginPerformanceObserver.d.ts +1 -1
- package/dist/types/create-editor/feature-flags-from-props.d.ts +1 -1
- package/dist/types-ts4.5/create-editor/ReactEditorView/useDispatchTransaction.d.ts +2 -2
- package/dist/types-ts4.5/create-editor/ReactEditorView/usePluginPerformanceObserver.d.ts +1 -1
- package/dist/types-ts4.5/create-editor/feature-flags-from-props.d.ts +1 -1
- package/package.json +7 -3
|
@@ -37,7 +37,10 @@ function ReactEditorView(props) {
|
|
|
37
37
|
preset,
|
|
38
38
|
editorProps: {
|
|
39
39
|
appearance: nextAppearance,
|
|
40
|
-
disabled
|
|
40
|
+
disabled,
|
|
41
|
+
featureFlags: editorPropFeatureFlags,
|
|
42
|
+
errorReporterHandler,
|
|
43
|
+
defaultValue
|
|
41
44
|
}
|
|
42
45
|
} = props;
|
|
43
46
|
const [editorAPI, setEditorAPI] = useState(undefined);
|
|
@@ -60,14 +63,14 @@ function ReactEditorView(props) {
|
|
|
60
63
|
onEditorViewStateUpdatedCallbacks: []
|
|
61
64
|
});
|
|
62
65
|
const contentTransformer = useRef(undefined);
|
|
63
|
-
const featureFlags =
|
|
66
|
+
const featureFlags = useMemo(() => createFeatureFlagsFromProps(editorPropFeatureFlags), [editorPropFeatureFlags]);
|
|
64
67
|
const getEditorState = useCallback(() => {
|
|
65
68
|
var _viewRef$current;
|
|
66
69
|
return (_viewRef$current = viewRef.current) === null || _viewRef$current === void 0 ? void 0 : _viewRef$current.state;
|
|
67
70
|
}, []);
|
|
68
71
|
const getEditorView = useCallback(() => viewRef.current, []);
|
|
69
72
|
const dispatch = useMemo(() => createDispatch(eventDispatcher), [eventDispatcher]);
|
|
70
|
-
const errorReporter =
|
|
73
|
+
const errorReporter = useMemo(() => createErrorReporter(errorReporterHandler), [errorReporterHandler]);
|
|
71
74
|
const handleAnalyticsEvent = useCallback(payload => {
|
|
72
75
|
fireAnalyticsEvent(props.createAnalyticsEvent)(payload);
|
|
73
76
|
}, [props.createAnalyticsEvent]);
|
|
@@ -84,22 +87,6 @@ function ReactEditorView(props) {
|
|
|
84
87
|
useLayoutEffect(() => {
|
|
85
88
|
setEditorAPI(pluginInjectionAPI.current.api());
|
|
86
89
|
}, []);
|
|
87
|
-
const blur = useCallback(() => {
|
|
88
|
-
if (!viewRef.current) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (viewRef.current.dom instanceof HTMLElement && viewRef.current.hasFocus()) {
|
|
92
|
-
viewRef.current.dom.blur();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// The selectionToDOM method uses the document selection to determine currently selected node
|
|
96
|
-
// We need to mimic blurring this as it seems doing the above is not enough.
|
|
97
|
-
// @ts-expect-error
|
|
98
|
-
const sel = viewRef.current.root.getSelection();
|
|
99
|
-
if (sel) {
|
|
100
|
-
sel.removeAllRanges();
|
|
101
|
-
}
|
|
102
|
-
}, []);
|
|
103
90
|
const createEditorState = useCallback(options => {
|
|
104
91
|
var _api$editorViewMode;
|
|
105
92
|
let schema;
|
|
@@ -133,14 +120,14 @@ function ReactEditorView(props) {
|
|
|
133
120
|
const plugins = createPMPlugins({
|
|
134
121
|
schema,
|
|
135
122
|
dispatch: dispatch,
|
|
136
|
-
errorReporter: errorReporter
|
|
123
|
+
errorReporter: errorReporter,
|
|
137
124
|
editorConfig: config.current,
|
|
138
125
|
eventDispatcher: eventDispatcher,
|
|
139
126
|
providerFactory: options.props.providerFactory,
|
|
140
127
|
portalProviderAPI: props.portalProviderAPI,
|
|
141
128
|
nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
|
|
142
129
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
143
|
-
featureFlags
|
|
130
|
+
featureFlags,
|
|
144
131
|
getIntl: () => props.intl
|
|
145
132
|
});
|
|
146
133
|
contentTransformer.current = contentTransformerProvider ? contentTransformerProvider(schema) : undefined;
|
|
@@ -180,7 +167,36 @@ function ReactEditorView(props) {
|
|
|
180
167
|
doc,
|
|
181
168
|
selection: patchedSelection
|
|
182
169
|
});
|
|
183
|
-
}, [props.intl, props.portalProviderAPI, props.nodeViewPortalProviderAPI, props.editorProps, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
170
|
+
}, [errorReporter, featureFlags, props.intl, props.portalProviderAPI, props.nodeViewPortalProviderAPI, props.editorProps, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
171
|
+
const initialEditorState = useMemo(() => createEditorState({
|
|
172
|
+
props,
|
|
173
|
+
doc: defaultValue,
|
|
174
|
+
// ED-4759: Don't set selection at end for full-page editor - should be at start.
|
|
175
|
+
selectionAtStart: isFullPage(nextAppearance)
|
|
176
|
+
}),
|
|
177
|
+
// This is only used for the initial state - afterwards we will have `viewRef` available for use
|
|
178
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
179
|
+
[]);
|
|
180
|
+
const getCurrentEditorState = useCallback(() => {
|
|
181
|
+
var _viewRef$current$stat, _viewRef$current2;
|
|
182
|
+
return (_viewRef$current$stat = (_viewRef$current2 = viewRef.current) === null || _viewRef$current2 === void 0 ? void 0 : _viewRef$current2.state) !== null && _viewRef$current$stat !== void 0 ? _viewRef$current$stat : initialEditorState;
|
|
183
|
+
}, [initialEditorState]);
|
|
184
|
+
const blur = useCallback(() => {
|
|
185
|
+
if (!viewRef.current) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (viewRef.current.dom instanceof HTMLElement && viewRef.current.hasFocus()) {
|
|
189
|
+
viewRef.current.dom.blur();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// The selectionToDOM method uses the document selection to determine currently selected node
|
|
193
|
+
// We need to mimic blurring this as it seems doing the above is not enough.
|
|
194
|
+
// @ts-expect-error
|
|
195
|
+
const sel = viewRef.current.root.getSelection();
|
|
196
|
+
if (sel) {
|
|
197
|
+
sel.removeAllRanges();
|
|
198
|
+
}
|
|
199
|
+
}, []);
|
|
184
200
|
const resetEditorState = useCallback(({
|
|
185
201
|
doc,
|
|
186
202
|
shouldScrollToBottom
|
|
@@ -194,14 +210,12 @@ function ReactEditorView(props) {
|
|
|
194
210
|
// so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
|
|
195
211
|
// nodes that haven't been re-rendered to the document yet.
|
|
196
212
|
blur();
|
|
197
|
-
featureFlags.current = createFeatureFlagsFromProps(props.editorProps);
|
|
198
213
|
const newEditorState = createEditorState({
|
|
199
214
|
props: props,
|
|
200
215
|
doc: doc,
|
|
201
216
|
resetting: true,
|
|
202
217
|
selectionAtStart: !shouldScrollToBottom
|
|
203
218
|
});
|
|
204
|
-
editorState.current = newEditorState;
|
|
205
219
|
viewRef.current.updateState(newEditorState);
|
|
206
220
|
(_props$editorProps$on = (_props$editorProps = props.editorProps).onChange) === null || _props$editorProps$on === void 0 ? void 0 : _props$editorProps$on.call(_props$editorProps, viewRef.current, {
|
|
207
221
|
source: 'local'
|
|
@@ -216,7 +230,7 @@ function ReactEditorView(props) {
|
|
|
216
230
|
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
217
231
|
attributes: {
|
|
218
232
|
platform: PLATFORMS.WEB,
|
|
219
|
-
featureFlags: featureFlags
|
|
233
|
+
featureFlags: featureFlags ? getEnabledFeatureFlagKeys(featureFlags) : []
|
|
220
234
|
},
|
|
221
235
|
eventType: EVENT_TYPE.UI
|
|
222
236
|
});
|
|
@@ -266,18 +280,18 @@ function ReactEditorView(props) {
|
|
|
266
280
|
blur();
|
|
267
281
|
const editorPlugins = createPluginsList(props.preset, props.editorProps, pluginInjectionAPI.current);
|
|
268
282
|
config.current = processPluginsList(editorPlugins);
|
|
269
|
-
const state =
|
|
283
|
+
const state = viewRef.current.state;
|
|
270
284
|
const plugins = createPMPlugins({
|
|
271
285
|
schema: state.schema,
|
|
272
286
|
dispatch: dispatch,
|
|
273
|
-
errorReporter: errorReporter
|
|
287
|
+
errorReporter: errorReporter,
|
|
274
288
|
editorConfig: config.current,
|
|
275
289
|
eventDispatcher: eventDispatcher,
|
|
276
290
|
providerFactory: props.providerFactory,
|
|
277
291
|
portalProviderAPI: props.portalProviderAPI,
|
|
278
292
|
nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
|
|
279
293
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
280
|
-
featureFlags
|
|
294
|
+
featureFlags,
|
|
281
295
|
getIntl: () => props.intl
|
|
282
296
|
});
|
|
283
297
|
const newState = state.reconfigure({
|
|
@@ -291,7 +305,7 @@ function ReactEditorView(props) {
|
|
|
291
305
|
...viewRef.current.props,
|
|
292
306
|
state: newState
|
|
293
307
|
});
|
|
294
|
-
}, [blur, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
308
|
+
}, [blur, dispatchAnalyticsEvent, eventDispatcher, dispatch, errorReporter, featureFlags]);
|
|
295
309
|
const onEditorViewUpdated = useCallback(({
|
|
296
310
|
originalTransaction,
|
|
297
311
|
transactions,
|
|
@@ -334,16 +348,13 @@ function ReactEditorView(props) {
|
|
|
334
348
|
});
|
|
335
349
|
const getDirectEditorProps = useCallback(state => {
|
|
336
350
|
return {
|
|
337
|
-
state: state
|
|
351
|
+
state: state !== null && state !== void 0 ? state : getCurrentEditorState(),
|
|
338
352
|
dispatchTransaction: tr => {
|
|
339
353
|
// Block stale transactions:
|
|
340
354
|
// Prevent runtime exeptions from async transactions that would attempt to
|
|
341
355
|
// update the DOM after React has unmounted the Editor.
|
|
342
356
|
if (canDispatchTransactions.current) {
|
|
343
|
-
|
|
344
|
-
if (newState) {
|
|
345
|
-
editorState.current = newState;
|
|
346
|
-
}
|
|
357
|
+
dispatchTransaction(viewRef.current, tr);
|
|
347
358
|
}
|
|
348
359
|
},
|
|
349
360
|
// Disables the contentEditable attribute of the editor if the editor is disabled
|
|
@@ -352,7 +363,7 @@ function ReactEditorView(props) {
|
|
|
352
363
|
'data-gramm': 'false'
|
|
353
364
|
}
|
|
354
365
|
};
|
|
355
|
-
}, [dispatchTransaction, disabled]);
|
|
366
|
+
}, [dispatchTransaction, disabled, getCurrentEditorState]);
|
|
356
367
|
const createEditorView = useCallback(node => {
|
|
357
368
|
measureRender(measurements.PROSEMIRROR_RENDERED, ({
|
|
358
369
|
duration,
|
|
@@ -479,13 +490,7 @@ function ReactEditorView(props) {
|
|
|
479
490
|
}
|
|
480
491
|
}, [disabled, shouldFocus, previousDisabledState]);
|
|
481
492
|
useFireFullWidthEvent(nextAppearance, dispatchAnalyticsEvent);
|
|
482
|
-
|
|
483
|
-
props,
|
|
484
|
-
doc: props.editorProps.defaultValue,
|
|
485
|
-
// ED-4759: Don't set selection at end for full-page editor - should be at start.
|
|
486
|
-
selectionAtStart: isFullPage(props.editorProps.appearance)
|
|
487
|
-
}));
|
|
488
|
-
usePluginPerformanceObserver(editorState, pluginInjectionAPI, dispatchAnalyticsEvent);
|
|
493
|
+
usePluginPerformanceObserver(getCurrentEditorState, pluginInjectionAPI, dispatchAnalyticsEvent);
|
|
489
494
|
const editor = useMemo(() => createEditor(props.editorProps.assistiveLabel, props.editorProps.assistiveDescribedBy),
|
|
490
495
|
// `createEditor` changes a little too frequently - we don't want to recreate the editor view in this case
|
|
491
496
|
// We should follow-up
|
|
@@ -28,7 +28,7 @@ export function getDefaultPresetOptionsFromEditorProps(props, createAnalyticsEve
|
|
|
28
28
|
typeAhead: {
|
|
29
29
|
isMobile: false
|
|
30
30
|
},
|
|
31
|
-
featureFlags: createFeatureFlagsFromProps(props),
|
|
31
|
+
featureFlags: createFeatureFlagsFromProps(props.featureFlags),
|
|
32
32
|
paste: {
|
|
33
33
|
cardOptions,
|
|
34
34
|
sanitizePrivateContent: props.sanitizePrivateContent
|
|
@@ -14,7 +14,7 @@ export function createUniversalPreset({
|
|
|
14
14
|
appearance: props.appearance,
|
|
15
15
|
props: getDefaultPresetOptionsFromEditorProps(props),
|
|
16
16
|
initialPluginConfiguration: initialPluginConfiguration,
|
|
17
|
-
featureFlags: createFeatureFlagsFromProps(props),
|
|
17
|
+
featureFlags: createFeatureFlagsFromProps(props.featureFlags),
|
|
18
18
|
prevAppearance: prevProps === null || prevProps === void 0 ? void 0 : prevProps.appearance
|
|
19
19
|
});
|
|
20
20
|
return withDangerouslyAppendPlugins(preset)((_props$dangerouslyApp = props.dangerouslyAppendPlugins) === null || _props$dangerouslyApp === void 0 ? void 0 : _props$dangerouslyApp.__plugins);
|
|
@@ -20,19 +20,17 @@ function getSpellCheck(featureFlags) {
|
|
|
20
20
|
* Transforms EditorProps to an FeatureFlags object,
|
|
21
21
|
* which is used by both current and archv3 editors.
|
|
22
22
|
*/
|
|
23
|
-
export function createFeatureFlagsFromProps(
|
|
24
|
-
|
|
25
|
-
const normalizedFeatureFlags = normalizeFeatureFlags(props.featureFlags);
|
|
23
|
+
export function createFeatureFlagsFromProps(featureFlags) {
|
|
24
|
+
const normalizedFeatureFlags = normalizeFeatureFlags(featureFlags);
|
|
26
25
|
return {
|
|
27
26
|
...normalizedFeatureFlags,
|
|
28
27
|
catchAllTracking: false,
|
|
29
|
-
showAvatarGroupAsPlugin: Boolean(typeof (
|
|
30
|
-
errorBoundaryDocStructure: Boolean(typeof (
|
|
31
|
-
synchronyErrorDocStructure: Boolean(typeof (
|
|
32
|
-
enableViewUpdateSubscription: Boolean(typeof (
|
|
33
|
-
collabAvatarScroll: Boolean(typeof (
|
|
34
|
-
twoLineEditorToolbar: Boolean(typeof (
|
|
35
|
-
|
|
36
|
-
disableSpellcheckByBrowser: getSpellCheck(props.featureFlags)
|
|
28
|
+
showAvatarGroupAsPlugin: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.showAvatarGroupAsPlugin) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.showAvatarGroupAsPlugin) : false),
|
|
29
|
+
errorBoundaryDocStructure: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.useErrorBoundaryDocStructure) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.useErrorBoundaryDocStructure) : false),
|
|
30
|
+
synchronyErrorDocStructure: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.synchronyErrorDocStructure) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.synchronyErrorDocStructure) : false),
|
|
31
|
+
enableViewUpdateSubscription: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.enableViewUpdateSubscription) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.enableViewUpdateSubscription) : false),
|
|
32
|
+
collabAvatarScroll: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.collabAvatarScroll) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.collabAvatarScroll) : false),
|
|
33
|
+
twoLineEditorToolbar: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.twoLineEditorToolbar) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.twoLineEditorToolbar) : false),
|
|
34
|
+
disableSpellcheckByBrowser: getSpellCheck(featureFlags)
|
|
37
35
|
};
|
|
38
36
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = "@atlaskit/editor-core";
|
|
2
|
-
export const version = "201.2.
|
|
2
|
+
export const version = "201.2.1";
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
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; }
|
|
2
5
|
/**
|
|
3
6
|
* @jsxRuntime classic
|
|
4
7
|
* @jsx jsx
|
|
@@ -45,7 +48,10 @@ function Editor(passedProps) {
|
|
|
45
48
|
fireAnalyticsEvent(createAnalyticsEvent)(data);
|
|
46
49
|
}, [createAnalyticsEvent]);
|
|
47
50
|
var getFeatureFlagsFromRef = useCallback(function () {
|
|
48
|
-
|
|
51
|
+
var _propsRef$current$col, _propsRef$current$col2;
|
|
52
|
+
return _objectSpread(_objectSpread({}, createFeatureFlagsFromProps(propsRef.current.featureFlags)), {}, {
|
|
53
|
+
useNativeCollabPlugin: Boolean(typeof ((_propsRef$current$col = propsRef.current.collabEdit) === null || _propsRef$current$col === void 0 ? void 0 : _propsRef$current$col.useNativePlugin) === 'boolean' ? !!((_propsRef$current$col2 = propsRef.current.collabEdit) !== null && _propsRef$current$col2 !== void 0 && _propsRef$current$col2.useNativePlugin) : false)
|
|
54
|
+
});
|
|
49
55
|
}, []);
|
|
50
56
|
var onEditorCreated = useCallback(function (instance) {
|
|
51
57
|
var _propsRef$current = propsRef.current,
|
|
@@ -51,7 +51,7 @@ export var EditorInternal = /*#__PURE__*/memo(function (_ref) {
|
|
|
51
51
|
// noop all analytic events, even if a handler is still passed.
|
|
52
52
|
analyticsHandler: undefined
|
|
53
53
|
});
|
|
54
|
-
var featureFlags = createFeatureFlagsFromProps(props);
|
|
54
|
+
var featureFlags = createFeatureFlagsFromProps(props.featureFlags);
|
|
55
55
|
|
|
56
56
|
// 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
|
|
57
57
|
var renderTrackingEnabled = !fg('platform_editor_disable_rerender_tracking_jira');
|
|
@@ -2,7 +2,7 @@ import { useCallback, useLayoutEffect, useMemo } from 'react';
|
|
|
2
2
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
3
3
|
import { countNodes } from '@atlaskit/editor-common/count-nodes';
|
|
4
4
|
import { PluginPerformanceObserver } from '../../utils/performance/plugin-performance-observer';
|
|
5
|
-
export var usePluginPerformanceObserver = function usePluginPerformanceObserver(
|
|
5
|
+
export var usePluginPerformanceObserver = function usePluginPerformanceObserver(getEditorState, pluginInjectionAPI, dispatchAnalyticsEvent) {
|
|
6
6
|
var onPluginObservation = useCallback(function (report) {
|
|
7
7
|
var _pluginInjectionAPI$c;
|
|
8
8
|
dispatchAnalyticsEvent({
|
|
@@ -16,24 +16,25 @@ export var usePluginPerformanceObserver = function usePluginPerformanceObserver(
|
|
|
16
16
|
});
|
|
17
17
|
}, [dispatchAnalyticsEvent, pluginInjectionAPI]);
|
|
18
18
|
var getPluginNames = useCallback(function () {
|
|
19
|
-
var
|
|
19
|
+
var _getEditorState;
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
return (
|
|
21
|
+
return (_getEditorState = getEditorState()) === null || _getEditorState === void 0 ? void 0 : _getEditorState.plugins.map(function (p) {
|
|
22
22
|
return p.key;
|
|
23
23
|
});
|
|
24
|
-
}, [
|
|
24
|
+
}, [getEditorState]);
|
|
25
25
|
var pluginPerformanceObserver = useMemo(function () {
|
|
26
|
+
var state = getEditorState();
|
|
26
27
|
return new PluginPerformanceObserver(function (report) {
|
|
27
28
|
return onPluginObservation(report);
|
|
28
29
|
}).withPlugins(function () {
|
|
29
30
|
return getPluginNames();
|
|
30
31
|
}).withNodeCounts(function () {
|
|
31
|
-
return
|
|
32
|
+
return state ? countNodes(state) : {
|
|
32
33
|
nodeCount: {},
|
|
33
34
|
extensionNodeCount: {}
|
|
34
35
|
};
|
|
35
36
|
});
|
|
36
|
-
}, [onPluginObservation, getPluginNames,
|
|
37
|
+
}, [onPluginObservation, getPluginNames, getEditorState]);
|
|
37
38
|
useLayoutEffect(function () {
|
|
38
39
|
return function () {
|
|
39
40
|
pluginPerformanceObserver.disconnect();
|
|
@@ -130,7 +130,7 @@ export var ReactEditorView = /*#__PURE__*/function (_React$Component) {
|
|
|
130
130
|
// so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
|
|
131
131
|
// nodes that haven't been re-rendered to the document yet.
|
|
132
132
|
_this.blur();
|
|
133
|
-
_this.featureFlags = createFeatureFlagsFromProps(_this.props.editorProps);
|
|
133
|
+
_this.featureFlags = createFeatureFlagsFromProps(_this.props.editorProps.featureFlags);
|
|
134
134
|
_this.editorState = _this.createEditorState({
|
|
135
135
|
props: _this.props,
|
|
136
136
|
doc: doc,
|
|
@@ -470,7 +470,7 @@ export var ReactEditorView = /*#__PURE__*/function (_React$Component) {
|
|
|
470
470
|
}).withNodeCounts(function () {
|
|
471
471
|
return _this.countNodes();
|
|
472
472
|
});
|
|
473
|
-
_this.featureFlags = createFeatureFlagsFromProps(_this.props.editorProps);
|
|
473
|
+
_this.featureFlags = createFeatureFlagsFromProps(_this.props.editorProps.featureFlags);
|
|
474
474
|
var featureFlagsEnabled = _this.featureFlags ? getEnabledFeatureFlagKeys(_this.featureFlags) : [];
|
|
475
475
|
|
|
476
476
|
// This needs to be before initialising editorState because
|
|
@@ -579,7 +579,7 @@ export var ReactEditorView = /*#__PURE__*/function (_React$Component) {
|
|
|
579
579
|
portalProviderAPI: props.portalProviderAPI,
|
|
580
580
|
nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
|
|
581
581
|
dispatchAnalyticsEvent: this.dispatchAnalyticsEvent,
|
|
582
|
-
featureFlags: createFeatureFlagsFromProps(props.editorProps),
|
|
582
|
+
featureFlags: createFeatureFlagsFromProps(props.editorProps.featureFlags),
|
|
583
583
|
getIntl: function getIntl() {
|
|
584
584
|
return _this2.props.intl;
|
|
585
585
|
}
|
|
@@ -40,7 +40,10 @@ function ReactEditorView(props) {
|
|
|
40
40
|
var preset = props.preset,
|
|
41
41
|
_props$editorProps = props.editorProps,
|
|
42
42
|
nextAppearance = _props$editorProps.appearance,
|
|
43
|
-
disabled = _props$editorProps.disabled
|
|
43
|
+
disabled = _props$editorProps.disabled,
|
|
44
|
+
editorPropFeatureFlags = _props$editorProps.featureFlags,
|
|
45
|
+
errorReporterHandler = _props$editorProps.errorReporterHandler,
|
|
46
|
+
defaultValue = _props$editorProps.defaultValue;
|
|
44
47
|
var _useState = useState(undefined),
|
|
45
48
|
_useState2 = _slicedToArray(_useState, 2),
|
|
46
49
|
editorAPI = _useState2[0],
|
|
@@ -66,7 +69,9 @@ function ReactEditorView(props) {
|
|
|
66
69
|
onEditorViewStateUpdatedCallbacks: []
|
|
67
70
|
});
|
|
68
71
|
var contentTransformer = useRef(undefined);
|
|
69
|
-
var featureFlags =
|
|
72
|
+
var featureFlags = useMemo(function () {
|
|
73
|
+
return createFeatureFlagsFromProps(editorPropFeatureFlags);
|
|
74
|
+
}, [editorPropFeatureFlags]);
|
|
70
75
|
var getEditorState = useCallback(function () {
|
|
71
76
|
var _viewRef$current;
|
|
72
77
|
return (_viewRef$current = viewRef.current) === null || _viewRef$current === void 0 ? void 0 : _viewRef$current.state;
|
|
@@ -77,7 +82,9 @@ function ReactEditorView(props) {
|
|
|
77
82
|
var dispatch = useMemo(function () {
|
|
78
83
|
return createDispatch(eventDispatcher);
|
|
79
84
|
}, [eventDispatcher]);
|
|
80
|
-
var errorReporter =
|
|
85
|
+
var errorReporter = useMemo(function () {
|
|
86
|
+
return createErrorReporter(errorReporterHandler);
|
|
87
|
+
}, [errorReporterHandler]);
|
|
81
88
|
var handleAnalyticsEvent = useCallback(function (payload) {
|
|
82
89
|
fireAnalyticsEvent(props.createAnalyticsEvent)(payload);
|
|
83
90
|
}, [props.createAnalyticsEvent]);
|
|
@@ -94,22 +101,6 @@ function ReactEditorView(props) {
|
|
|
94
101
|
useLayoutEffect(function () {
|
|
95
102
|
setEditorAPI(pluginInjectionAPI.current.api());
|
|
96
103
|
}, []);
|
|
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
104
|
var createEditorState = useCallback(function (options) {
|
|
114
105
|
var _api$editorViewMode;
|
|
115
106
|
var schema;
|
|
@@ -141,14 +132,14 @@ function ReactEditorView(props) {
|
|
|
141
132
|
var plugins = createPMPlugins({
|
|
142
133
|
schema: schema,
|
|
143
134
|
dispatch: dispatch,
|
|
144
|
-
errorReporter: errorReporter
|
|
135
|
+
errorReporter: errorReporter,
|
|
145
136
|
editorConfig: config.current,
|
|
146
137
|
eventDispatcher: eventDispatcher,
|
|
147
138
|
providerFactory: options.props.providerFactory,
|
|
148
139
|
portalProviderAPI: props.portalProviderAPI,
|
|
149
140
|
nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
|
|
150
141
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
151
|
-
featureFlags: featureFlags
|
|
142
|
+
featureFlags: featureFlags,
|
|
152
143
|
getIntl: function getIntl() {
|
|
153
144
|
return props.intl;
|
|
154
145
|
}
|
|
@@ -190,7 +181,38 @@ function ReactEditorView(props) {
|
|
|
190
181
|
doc: doc,
|
|
191
182
|
selection: patchedSelection
|
|
192
183
|
});
|
|
193
|
-
}, [props.intl, props.portalProviderAPI, props.nodeViewPortalProviderAPI, props.editorProps, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
184
|
+
}, [errorReporter, featureFlags, props.intl, props.portalProviderAPI, props.nodeViewPortalProviderAPI, props.editorProps, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
185
|
+
var initialEditorState = useMemo(function () {
|
|
186
|
+
return createEditorState({
|
|
187
|
+
props: props,
|
|
188
|
+
doc: defaultValue,
|
|
189
|
+
// ED-4759: Don't set selection at end for full-page editor - should be at start.
|
|
190
|
+
selectionAtStart: isFullPage(nextAppearance)
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
// This is only used for the initial state - afterwards we will have `viewRef` available for use
|
|
194
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
195
|
+
[]);
|
|
196
|
+
var getCurrentEditorState = useCallback(function () {
|
|
197
|
+
var _viewRef$current$stat, _viewRef$current2;
|
|
198
|
+
return (_viewRef$current$stat = (_viewRef$current2 = viewRef.current) === null || _viewRef$current2 === void 0 ? void 0 : _viewRef$current2.state) !== null && _viewRef$current$stat !== void 0 ? _viewRef$current$stat : initialEditorState;
|
|
199
|
+
}, [initialEditorState]);
|
|
200
|
+
var blur = useCallback(function () {
|
|
201
|
+
if (!viewRef.current) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (viewRef.current.dom instanceof HTMLElement && viewRef.current.hasFocus()) {
|
|
205
|
+
viewRef.current.dom.blur();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// The selectionToDOM method uses the document selection to determine currently selected node
|
|
209
|
+
// We need to mimic blurring this as it seems doing the above is not enough.
|
|
210
|
+
// @ts-expect-error
|
|
211
|
+
var sel = viewRef.current.root.getSelection();
|
|
212
|
+
if (sel) {
|
|
213
|
+
sel.removeAllRanges();
|
|
214
|
+
}
|
|
215
|
+
}, []);
|
|
194
216
|
var resetEditorState = useCallback(function (_ref) {
|
|
195
217
|
var _props$editorProps$on, _props$editorProps2;
|
|
196
218
|
var doc = _ref.doc,
|
|
@@ -203,14 +225,12 @@ function ReactEditorView(props) {
|
|
|
203
225
|
// so we blur here to stop ProseMirror from trying to apply selection to detached nodes or
|
|
204
226
|
// nodes that haven't been re-rendered to the document yet.
|
|
205
227
|
blur();
|
|
206
|
-
featureFlags.current = createFeatureFlagsFromProps(props.editorProps);
|
|
207
228
|
var newEditorState = createEditorState({
|
|
208
229
|
props: props,
|
|
209
230
|
doc: doc,
|
|
210
231
|
resetting: true,
|
|
211
232
|
selectionAtStart: !shouldScrollToBottom
|
|
212
233
|
});
|
|
213
|
-
editorState.current = newEditorState;
|
|
214
234
|
viewRef.current.updateState(newEditorState);
|
|
215
235
|
(_props$editorProps$on = (_props$editorProps2 = props.editorProps).onChange) === null || _props$editorProps$on === void 0 || _props$editorProps$on.call(_props$editorProps2, viewRef.current, {
|
|
216
236
|
source: 'local'
|
|
@@ -225,7 +245,7 @@ function ReactEditorView(props) {
|
|
|
225
245
|
actionSubject: ACTION_SUBJECT.EDITOR,
|
|
226
246
|
attributes: {
|
|
227
247
|
platform: PLATFORMS.WEB,
|
|
228
|
-
featureFlags: featureFlags
|
|
248
|
+
featureFlags: featureFlags ? getEnabledFeatureFlagKeys(featureFlags) : []
|
|
229
249
|
},
|
|
230
250
|
eventType: EVENT_TYPE.UI
|
|
231
251
|
});
|
|
@@ -252,9 +272,9 @@ function ReactEditorView(props) {
|
|
|
252
272
|
}
|
|
253
273
|
if (viewRef.current) {
|
|
254
274
|
// Destroy the state if the Editor is being unmounted
|
|
255
|
-
var
|
|
256
|
-
|
|
257
|
-
var state = plugin.getState(
|
|
275
|
+
var editorState = viewRef.current.state;
|
|
276
|
+
editorState.plugins.forEach(function (plugin) {
|
|
277
|
+
var state = plugin.getState(editorState);
|
|
258
278
|
if (state && state.destroy) {
|
|
259
279
|
state.destroy();
|
|
260
280
|
}
|
|
@@ -275,18 +295,18 @@ function ReactEditorView(props) {
|
|
|
275
295
|
blur();
|
|
276
296
|
var editorPlugins = createPluginsList(props.preset, props.editorProps, pluginInjectionAPI.current);
|
|
277
297
|
config.current = processPluginsList(editorPlugins);
|
|
278
|
-
var state =
|
|
298
|
+
var state = viewRef.current.state;
|
|
279
299
|
var plugins = createPMPlugins({
|
|
280
300
|
schema: state.schema,
|
|
281
301
|
dispatch: dispatch,
|
|
282
|
-
errorReporter: errorReporter
|
|
302
|
+
errorReporter: errorReporter,
|
|
283
303
|
editorConfig: config.current,
|
|
284
304
|
eventDispatcher: eventDispatcher,
|
|
285
305
|
providerFactory: props.providerFactory,
|
|
286
306
|
portalProviderAPI: props.portalProviderAPI,
|
|
287
307
|
nodeViewPortalProviderAPI: props.nodeViewPortalProviderAPI,
|
|
288
308
|
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
|
|
289
|
-
featureFlags:
|
|
309
|
+
featureFlags: featureFlags,
|
|
290
310
|
getIntl: function getIntl() {
|
|
291
311
|
return props.intl;
|
|
292
312
|
}
|
|
@@ -301,7 +321,7 @@ function ReactEditorView(props) {
|
|
|
301
321
|
return viewRef.current.update(_objectSpread(_objectSpread({}, viewRef.current.props), {}, {
|
|
302
322
|
state: newState
|
|
303
323
|
}));
|
|
304
|
-
}, [blur, dispatchAnalyticsEvent, eventDispatcher, dispatch]);
|
|
324
|
+
}, [blur, dispatchAnalyticsEvent, eventDispatcher, dispatch, errorReporter, featureFlags]);
|
|
305
325
|
var onEditorViewUpdated = useCallback(function (_ref2) {
|
|
306
326
|
var _config$current;
|
|
307
327
|
var originalTransaction = _ref2.originalTransaction,
|
|
@@ -343,16 +363,13 @@ function ReactEditorView(props) {
|
|
|
343
363
|
});
|
|
344
364
|
var getDirectEditorProps = useCallback(function (state) {
|
|
345
365
|
return {
|
|
346
|
-
state: state
|
|
366
|
+
state: state !== null && state !== void 0 ? state : getCurrentEditorState(),
|
|
347
367
|
dispatchTransaction: function dispatchTransaction(tr) {
|
|
348
368
|
// Block stale transactions:
|
|
349
369
|
// Prevent runtime exeptions from async transactions that would attempt to
|
|
350
370
|
// update the DOM after React has unmounted the Editor.
|
|
351
371
|
if (canDispatchTransactions.current) {
|
|
352
|
-
|
|
353
|
-
if (newState) {
|
|
354
|
-
editorState.current = newState;
|
|
355
|
-
}
|
|
372
|
+
_dispatchTransaction(viewRef.current, tr);
|
|
356
373
|
}
|
|
357
374
|
},
|
|
358
375
|
// Disables the contentEditable attribute of the editor if the editor is disabled
|
|
@@ -363,7 +380,7 @@ function ReactEditorView(props) {
|
|
|
363
380
|
'data-gramm': 'false'
|
|
364
381
|
}
|
|
365
382
|
};
|
|
366
|
-
}, [_dispatchTransaction, disabled]);
|
|
383
|
+
}, [_dispatchTransaction, disabled, getCurrentEditorState]);
|
|
367
384
|
var createEditorView = useCallback(function (node) {
|
|
368
385
|
measureRender(measurements.PROSEMIRROR_RENDERED, function (_ref3) {
|
|
369
386
|
var duration = _ref3.duration,
|
|
@@ -490,13 +507,7 @@ function ReactEditorView(props) {
|
|
|
490
507
|
}
|
|
491
508
|
}, [disabled, shouldFocus, previousDisabledState]);
|
|
492
509
|
useFireFullWidthEvent(nextAppearance, dispatchAnalyticsEvent);
|
|
493
|
-
|
|
494
|
-
props: props,
|
|
495
|
-
doc: props.editorProps.defaultValue,
|
|
496
|
-
// ED-4759: Don't set selection at end for full-page editor - should be at start.
|
|
497
|
-
selectionAtStart: isFullPage(props.editorProps.appearance)
|
|
498
|
-
}));
|
|
499
|
-
usePluginPerformanceObserver(editorState, pluginInjectionAPI, dispatchAnalyticsEvent);
|
|
510
|
+
usePluginPerformanceObserver(getCurrentEditorState, pluginInjectionAPI, dispatchAnalyticsEvent);
|
|
500
511
|
var editor = useMemo(function () {
|
|
501
512
|
return createEditor(props.editorProps.assistiveLabel, props.editorProps.assistiveDescribedBy);
|
|
502
513
|
},
|
|
@@ -30,7 +30,7 @@ export function getDefaultPresetOptionsFromEditorProps(props, createAnalyticsEve
|
|
|
30
30
|
typeAhead: {
|
|
31
31
|
isMobile: false
|
|
32
32
|
},
|
|
33
|
-
featureFlags: createFeatureFlagsFromProps(props),
|
|
33
|
+
featureFlags: createFeatureFlagsFromProps(props.featureFlags),
|
|
34
34
|
paste: {
|
|
35
35
|
cardOptions: cardOptions,
|
|
36
36
|
sanitizePrivateContent: props.sanitizePrivateContent
|
|
@@ -13,7 +13,7 @@ export function createUniversalPreset(_ref) {
|
|
|
13
13
|
appearance: props.appearance,
|
|
14
14
|
props: getDefaultPresetOptionsFromEditorProps(props),
|
|
15
15
|
initialPluginConfiguration: initialPluginConfiguration,
|
|
16
|
-
featureFlags: createFeatureFlagsFromProps(props),
|
|
16
|
+
featureFlags: createFeatureFlagsFromProps(props.featureFlags),
|
|
17
17
|
prevAppearance: prevProps === null || prevProps === void 0 ? void 0 : prevProps.appearance
|
|
18
18
|
});
|
|
19
19
|
return withDangerouslyAppendPlugins(preset)((_props$dangerouslyApp = props.dangerouslyAppendPlugins) === null || _props$dangerouslyApp === void 0 ? void 0 : _props$dangerouslyApp.__plugins);
|
|
@@ -24,18 +24,16 @@ function getSpellCheck(featureFlags) {
|
|
|
24
24
|
* Transforms EditorProps to an FeatureFlags object,
|
|
25
25
|
* which is used by both current and archv3 editors.
|
|
26
26
|
*/
|
|
27
|
-
export function createFeatureFlagsFromProps(
|
|
28
|
-
var
|
|
29
|
-
var normalizedFeatureFlags = normalizeFeatureFlags(props.featureFlags);
|
|
27
|
+
export function createFeatureFlagsFromProps(featureFlags) {
|
|
28
|
+
var normalizedFeatureFlags = normalizeFeatureFlags(featureFlags);
|
|
30
29
|
return _objectSpread(_objectSpread({}, normalizedFeatureFlags), {}, {
|
|
31
30
|
catchAllTracking: false,
|
|
32
|
-
showAvatarGroupAsPlugin: Boolean(typeof (
|
|
33
|
-
errorBoundaryDocStructure: Boolean(typeof (
|
|
34
|
-
synchronyErrorDocStructure: Boolean(typeof (
|
|
35
|
-
enableViewUpdateSubscription: Boolean(typeof (
|
|
36
|
-
collabAvatarScroll: Boolean(typeof (
|
|
37
|
-
twoLineEditorToolbar: Boolean(typeof (
|
|
38
|
-
|
|
39
|
-
disableSpellcheckByBrowser: getSpellCheck(props.featureFlags)
|
|
31
|
+
showAvatarGroupAsPlugin: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.showAvatarGroupAsPlugin) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.showAvatarGroupAsPlugin) : false),
|
|
32
|
+
errorBoundaryDocStructure: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.useErrorBoundaryDocStructure) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.useErrorBoundaryDocStructure) : false),
|
|
33
|
+
synchronyErrorDocStructure: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.synchronyErrorDocStructure) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.synchronyErrorDocStructure) : false),
|
|
34
|
+
enableViewUpdateSubscription: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.enableViewUpdateSubscription) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.enableViewUpdateSubscription) : false),
|
|
35
|
+
collabAvatarScroll: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.collabAvatarScroll) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.collabAvatarScroll) : false),
|
|
36
|
+
twoLineEditorToolbar: Boolean(typeof (featureFlags === null || featureFlags === void 0 ? void 0 : featureFlags.twoLineEditorToolbar) === 'boolean' ? !!(featureFlags !== null && featureFlags !== void 0 && featureFlags.twoLineEditorToolbar) : false),
|
|
37
|
+
disableSpellcheckByBrowser: getSpellCheck(featureFlags)
|
|
40
38
|
});
|
|
41
39
|
}
|