@atlaskit/editor-core 216.10.1 → 216.11.3

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 (34) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/afm-cc/tsconfig.json +0 -1
  3. package/afm-jira/tsconfig.json +0 -1
  4. package/afm-products/tsconfig.json +0 -1
  5. package/dist/cjs/composable-editor/editor-internal.js +1 -0
  6. package/dist/cjs/composable-editor/hooks/useMemoEditorProps.js +2 -1
  7. package/dist/cjs/create-editor/ReactEditorView.js +92 -21
  8. package/dist/cjs/ui/Appearance/FullPage/FullPage.js +10 -2
  9. package/dist/cjs/utils/getNodesCount.js +1 -0
  10. package/dist/cjs/utils/getNodesCountWithExtensionKeys.js +32 -0
  11. package/dist/cjs/version-wrapper.js +1 -1
  12. package/dist/es2019/composable-editor/editor-internal.js +1 -0
  13. package/dist/es2019/composable-editor/hooks/useMemoEditorProps.js +2 -1
  14. package/dist/es2019/create-editor/ReactEditorView.js +82 -17
  15. package/dist/es2019/ui/Appearance/FullPage/FullPage.js +10 -2
  16. package/dist/es2019/utils/getNodesCount.js +1 -0
  17. package/dist/es2019/utils/getNodesCountWithExtensionKeys.js +26 -0
  18. package/dist/es2019/version-wrapper.js +1 -1
  19. package/dist/esm/composable-editor/editor-internal.js +1 -0
  20. package/dist/esm/composable-editor/hooks/useMemoEditorProps.js +2 -1
  21. package/dist/esm/create-editor/ReactEditorView.js +93 -22
  22. package/dist/esm/ui/Appearance/FullPage/FullPage.js +10 -2
  23. package/dist/esm/utils/getNodesCount.js +1 -0
  24. package/dist/esm/utils/getNodesCountWithExtensionKeys.js +26 -0
  25. package/dist/esm/version-wrapper.js +1 -1
  26. package/dist/types/create-editor/ReactEditorView.d.ts +5 -0
  27. package/dist/types/types/editor-appearance-component.d.ts +5 -0
  28. package/dist/types/types/editor-props.d.ts +26 -0
  29. package/dist/types/utils/getNodesCountWithExtensionKeys.d.ts +12 -0
  30. package/dist/types-ts4.5/create-editor/ReactEditorView.d.ts +5 -0
  31. package/dist/types-ts4.5/types/editor-appearance-component.d.ts +5 -0
  32. package/dist/types-ts4.5/types/editor-props.d.ts +26 -0
  33. package/dist/types-ts4.5/utils/getNodesCountWithExtensionKeys.d.ts +12 -0
  34. package/package.json +6 -3
@@ -6,10 +6,12 @@ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, PLATFORMS } fro
6
6
  import { isSSR } from '@atlaskit/editor-common/core-utils';
7
7
  import { createDispatch, EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
8
8
  import { useConstructor, usePreviousState } from '@atlaskit/editor-common/hooks';
9
+ import { isPerformanceAPIAvailable } from '@atlaskit/editor-common/is-performance-api-available';
9
10
  import { nodeVisibilityManager } from '@atlaskit/editor-common/node-visibility';
10
11
  import { getEnabledFeatureFlagKeys } from '@atlaskit/editor-common/normalize-feature-flags';
11
12
  import { measureRender } from '@atlaskit/editor-common/performance/measure-render';
12
- import { getResponseEndTime } from '@atlaskit/editor-common/performance/navigation';
13
+ import { getRequestToResponseTime, getResponseEndTime } from '@atlaskit/editor-common/performance/navigation';
14
+ import { profileSSROperation, SSRRenderMeasure } from '@atlaskit/editor-common/performance/ssr-measures';
13
15
  import { EditorPluginInjectionAPI } from '@atlaskit/editor-common/preset';
14
16
  import { processRawValue, processRawValueWithoutValidation } from '@atlaskit/editor-common/process-raw-value';
15
17
  import { ReactEditorViewContext } from '@atlaskit/editor-common/ui-react';
@@ -19,12 +21,14 @@ import { EditorState, Selection, TextSelection } from '@atlaskit/editor-prosemir
19
21
  import { EditorView } from '@atlaskit/editor-prosemirror/view';
20
22
  import { EditorSSRRenderer } from '@atlaskit/editor-ssr-renderer';
21
23
  import { fg } from '@atlaskit/platform-feature-flags';
24
+ import { getInteractionId } from '@atlaskit/react-ufo/interaction-id-context';
22
25
  import { abortAll, getActiveInteraction } from '@atlaskit/react-ufo/interaction-metrics';
23
26
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
24
27
  import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
25
28
  import { useProviders } from '../composable-editor/hooks/useProviders';
26
29
  import { createFeatureFlagsFromProps } from '../utils/feature-flags-from-props';
27
30
  import { getNodesCount } from '../utils/getNodesCount';
31
+ import { getNodesCountWithExtensionKeys } from '../utils/getNodesCountWithExtensionKeys';
28
32
  import { getNodesVisibleInViewport } from '../utils/getNodesVisibleInViewport';
29
33
  import { isChromeless } from '../utils/is-chromeless';
30
34
  import { isFullPage } from '../utils/is-full-page';
@@ -41,11 +45,16 @@ import { handleEditorFocus } from './ReactEditorView/handleEditorFocus';
41
45
  import { useDispatchTransaction } from './ReactEditorView/useDispatchTransaction';
42
46
  import { useFireFullWidthEvent } from './ReactEditorView/useFireFullWidthEvent';
43
47
  const EDIT_AREA_ID = 'ak-editor-textarea';
48
+ const SSR_TRACE_SEGMENT_NAME = 'reactEditorView';
49
+ const bootStartTime = isPerformanceAPIAvailable() ? performance.now() : undefined;
44
50
  export function ReactEditorView(props) {
45
51
  var _pluginInjectionAPI$c, _pluginInjectionAPI$c2, _pluginInjectionAPI$c3, _media, _linking, _linking$smartLinks, _document$querySelect, _props$render, _props$render2;
52
+ // Should be always the first statement in the component
53
+ const firstRenderStartTimestampRef = useRef(performance.now());
46
54
  const {
47
55
  preset,
48
56
  editorProps: {
57
+ onSSRMeasure,
49
58
  appearance: nextAppearance,
50
59
  disabled,
51
60
  featureFlags: editorPropFeatureFlags,
@@ -440,9 +449,11 @@ export function ReactEditorView(props) {
440
449
  }) => {
441
450
  const proseMirrorRenderedSeverity = getAnalyticsEventSeverity(duration, PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD, PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD);
442
451
  if (viewRef.current) {
443
- var _pluginInjectionAPI$c4;
444
- const nodes = getNodesCount(viewRef.current.state.doc);
452
+ var _nodesAndExtensionKey, _pluginInjectionAPI$c4;
453
+ const nodesAndExtensionKeys = expValEquals('platform_editor_prosemirror_rendered_data', 'isEnabled', true) ? getNodesCountWithExtensionKeys(viewRef.current.state.doc) : undefined;
454
+ const nodes = (_nodesAndExtensionKey = nodesAndExtensionKeys === null || nodesAndExtensionKeys === void 0 ? void 0 : nodesAndExtensionKeys.nodes) !== null && _nodesAndExtensionKey !== void 0 ? _nodesAndExtensionKey : getNodesCount(viewRef.current.state.doc);
445
455
  const ttfb = getResponseEndTime();
456
+ const requestToResponseTime = getRequestToResponseTime();
446
457
  const contextIdentifier = (_pluginInjectionAPI$c4 = pluginInjectionAPI.current.api().base) === null || _pluginInjectionAPI$c4 === void 0 ? void 0 : _pluginInjectionAPI$c4.sharedState.currentState();
447
458
  const nodesInViewport = getNodesVisibleInViewport(viewRef.current.dom);
448
459
  const nodeSize = viewRef.current.state.doc.nodeSize;
@@ -469,10 +480,51 @@ export function ReactEditorView(props) {
469
480
  }
470
481
  })()
471
482
  } : {};
472
- dispatchAnalyticsEvent({
473
- action: ACTION.PROSEMIRROR_RENDERED,
474
- actionSubject: ACTION_SUBJECT.EDITOR,
475
- attributes: {
483
+ if (expValEquals('platform_editor_prosemirror_rendered_data', 'isEnabled', true)) {
484
+ var _nodesAndExtensionKey2;
485
+ const extensionKeys = (_nodesAndExtensionKey2 = nodesAndExtensionKeys === null || nodesAndExtensionKeys === void 0 ? void 0 : nodesAndExtensionKeys.extensionKeys) !== null && _nodesAndExtensionKey2 !== void 0 ? _nodesAndExtensionKey2 : {};
486
+ const interaction = getActiveInteraction();
487
+ const pageLoadType = interaction === null || interaction === void 0 ? void 0 : interaction.type;
488
+ const pageType = interaction === null || interaction === void 0 ? void 0 : interaction.routeName;
489
+ const timings = (() => {
490
+ if (requestToResponseTime === undefined && bootStartTime === undefined) {
491
+ return undefined;
492
+ }
493
+ const timingValues = {};
494
+ if (requestToResponseTime !== undefined) {
495
+ timingValues['requestStart->responseEnd'] = Math.round(requestToResponseTime);
496
+ }
497
+ if (bootStartTime !== undefined) {
498
+ timingValues.bootToRender = Math.round(startTime - bootStartTime);
499
+ }
500
+ return timingValues;
501
+ })();
502
+ const attributes = {
503
+ duration,
504
+ startTime,
505
+ nodes,
506
+ nodesInViewport,
507
+ nodeSize,
508
+ nodeSizeBucket,
509
+ totalNodes,
510
+ ttfb,
511
+ severity: proseMirrorRenderedSeverity,
512
+ objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
513
+ distortedDuration,
514
+ pageLoadType,
515
+ pageType,
516
+ timings,
517
+ extensionKeys,
518
+ ufoInteractionId: getInteractionId().current
519
+ };
520
+ dispatchAnalyticsEvent({
521
+ action: ACTION.PROSEMIRROR_RENDERED,
522
+ actionSubject: ACTION_SUBJECT.EDITOR,
523
+ attributes,
524
+ eventType: EVENT_TYPE.OPERATIONAL
525
+ });
526
+ } else {
527
+ const attributes = {
476
528
  duration,
477
529
  startTime,
478
530
  nodes,
@@ -484,9 +536,14 @@ export function ReactEditorView(props) {
484
536
  severity: proseMirrorRenderedSeverity,
485
537
  objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
486
538
  distortedDuration
487
- },
488
- eventType: EVENT_TYPE.OPERATIONAL
489
- });
539
+ };
540
+ dispatchAnalyticsEvent({
541
+ action: ACTION.PROSEMIRROR_RENDERED,
542
+ actionSubject: ACTION_SUBJECT.EDITOR,
543
+ attributes,
544
+ eventType: EVENT_TYPE.OPERATIONAL
545
+ });
546
+ }
490
547
  }
491
548
  });
492
549
  pluginInjectionAPI.current.onEditorViewUpdated({
@@ -728,20 +785,23 @@ export function ReactEditorView(props) {
728
785
  if (!isSSR() || !expValEquals('platform_editor_ssr_renderer', 'isEnabled', true)) {
729
786
  return null;
730
787
  }
731
- const plugins = createPluginsList(props.preset,
788
+ const doCreatePluginList = () => createPluginsList(props.preset,
732
789
  // Don't pass props.editorProps directly, because editoProps in the dependency will lead to
733
790
  // multiple repaints, because props.editorPros is not stable object.
734
791
  {
735
792
  allowBlockType
736
793
  }, pluginInjectionAPI.current);
737
- const schema = createSchema(processPluginsList(plugins));
738
- const doc = buildDoc(schema);
794
+ const plugins = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation(`${SSR_TRACE_SEGMENT_NAME}/createPluginsList`, doCreatePluginList, onSSRMeasure) : doCreatePluginList();
795
+ const doCreateSchema = () => createSchema(processPluginsList(plugins));
796
+ const schema = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation(`${SSR_TRACE_SEGMENT_NAME}/createSchema`, doCreateSchema, onSSRMeasure) : doCreateSchema();
797
+ const doBuildDoc = () => buildDoc(schema);
798
+ const doc = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation(`${SSR_TRACE_SEGMENT_NAME}/buildDoc`, doBuildDoc, onSSRMeasure) : doBuildDoc();
739
799
  return {
740
800
  plugins,
741
801
  schema,
742
802
  doc
743
803
  };
744
- }, [allowBlockType, buildDoc, props.preset]);
804
+ }, [allowBlockType, buildDoc, props.preset, onSSRMeasure]);
745
805
  const {
746
806
  assistiveLabel,
747
807
  assistiveDescribedBy
@@ -765,6 +825,7 @@ export function ReactEditorView(props) {
765
825
  id: EDIT_AREA_ID,
766
826
  "aria-describedby": assistiveDescribedBy,
767
827
  "data-editor-id": editorId.current,
828
+ onSSRMeasure: onSSRMeasure,
768
829
  onEditorStateChanged: state => {
769
830
  ssrEditorStateRef.current = state;
770
831
  // Notify listeners about the initial SSR state
@@ -774,7 +835,7 @@ export function ReactEditorView(props) {
774
835
  });
775
836
  }
776
837
  });
777
- }, [ssrDeps, props.intl, props.portalProviderAPI, assistiveLabel, assistiveDescribedBy, isPageAppearance]);
838
+ }, [ssrDeps, props.intl, props.portalProviderAPI, assistiveLabel, isPageAppearance, assistiveDescribedBy, onSSRMeasure]);
778
839
  const editor = useMemo(() => {
779
840
  // SSR editor will be available only in SSR environment,
780
841
  // in a browser `ssrEditor` will be `null`, and we will render a normal one ProseMirror.
@@ -791,7 +852,11 @@ export function ReactEditorView(props) {
791
852
  // 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
792
853
  // Also firing too many events for the legacy content macro, so disabling for now. See - https://product-fabric.atlassian.net/browse/ED-26650
793
854
  const renderTrackingEnabled = !fg('platform_editor_disable_rerender_tracking_jira') && !featureFlags.lcmPreventRenderTracking;
794
- return /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
855
+ return /*#__PURE__*/React.createElement(SSRRenderMeasure, {
856
+ segmentName: SSR_TRACE_SEGMENT_NAME,
857
+ startTimestampRef: firstRenderStartTimestampRef,
858
+ onSSRMeasure: fg('platform_editor_better_editor_ssr_spans') ? onSSRMeasure : undefined
859
+ }, /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
795
860
  value: {
796
861
  editorRef: editorRef,
797
862
  editorView: viewRef.current,
@@ -812,7 +877,7 @@ export function ReactEditorView(props) {
812
877
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
813
878
  editorRef: editorRef,
814
879
  editorAPI: expVal('platform_editor_no_state_plugin_injection_api', 'isEnabled', false) ? pluginInjectionAPI.current.api() : editorAPI
815
- })) !== null && _props$render !== void 0 ? _props$render : editor : editor);
880
+ })) !== null && _props$render !== void 0 ? _props$render : editor : editor));
816
881
  }
817
882
 
818
883
  // Preserving exact type generated by TypeScript
@@ -8,6 +8,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
8
8
  import { jsx } from '@emotion/react';
9
9
  import { browser as browserLegacy, getBrowserInfo } from '@atlaskit/editor-common/browser';
10
10
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
11
+ import { SSRRenderMeasure } from '@atlaskit/editor-common/performance/ssr-measures';
11
12
  import { ContextPanelWidthProvider } from '@atlaskit/editor-common/ui';
12
13
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
13
14
  import { FULL_PAGE_EDITOR_TOOLBAR_HEIGHT } from '@atlaskit/editor-shared-styles';
@@ -19,6 +20,7 @@ import { FullPageContentArea } from './FullPageContentArea';
19
20
  import { FullPageToolbar } from './FullPageToolbar';
20
21
  import { FullPageToolbarNext } from './FullPageToolbarNext';
21
22
  import { fullPageEditorWrapper } from './StyledComponents';
23
+ const SSR_TRACE_SEGMENT_NAME = 'reactEditorView/fullPageAppearance';
22
24
  const useShowKeyline = contentAreaRef => {
23
25
  const [showKeyline, setShowKeyline] = useState(false);
24
26
  useEffect(() => {
@@ -55,6 +57,8 @@ const hasCustomComponents = components => {
55
57
  };
56
58
  export const FullPageEditor = props => {
57
59
  var _scrollContentContain, _toolbarDockingPositi, _scrollContentContain2, _scrollContentContain3, _wrapperElementRef$cu;
60
+ // Should be always the first statement in the component
61
+ const firstRenderStartTimestampRef = useRef(performance.now());
58
62
  const wrapperElementRef = useMemo(() => props.innerRef, [props.innerRef]);
59
63
  const scrollContentContainerRef = useRef(null);
60
64
  const showKeyline = useShowKeyline(scrollContentContainerRef);
@@ -129,7 +133,11 @@ export const FullPageEditor = props => {
129
133
  }
130
134
  const isToolbarAIFCEnabled = Boolean(editorAPI === null || editorAPI === void 0 ? void 0 : editorAPI.toolbar);
131
135
  const popupsBoundariesElement = props.popupsBoundariesElement || (scrollContentContainerRef === null || scrollContentContainerRef === void 0 ? void 0 : (_scrollContentContain = scrollContentContainerRef.current) === null || _scrollContentContain === void 0 ? void 0 : _scrollContentContain.containerArea) || undefined;
132
- return jsx(ContextPanelWidthProvider, null, jsx("div", {
136
+ return jsx(SSRRenderMeasure, {
137
+ segmentName: SSR_TRACE_SEGMENT_NAME,
138
+ startTimestampRef: firstRenderStartTimestampRef,
139
+ onSSRMeasure: fg('platform_editor_better_editor_ssr_spans') ? props.onSSRMeasure : undefined
140
+ }, jsx(ContextPanelWidthProvider, null, jsx("div", {
133
141
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
134
142
  css: fullPageEditorWrapper
135
143
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -206,5 +214,5 @@ export const FullPageEditor = props => {
206
214
  viewMode: state.editorViewMode,
207
215
  hasHadInteraction: hasHadInteraction,
208
216
  contentMode: props.contentMode
209
- })));
217
+ }))));
210
218
  };
@@ -1,3 +1,4 @@
1
+ // When experiment platform_editor_prosemirror_rendered_data is removed, review whether this helper is still needed.
1
2
  export function getNodesCount(node) {
2
3
  const count = {};
3
4
  node.nodesBetween(0, node.nodeSize - 2, node => {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Counts node types and extension keys in a single traversal.
3
+ * We exclude the end-of-doc token by iterating to nodeSize - 2,
4
+ * which matches the typical ProseMirror pattern for traversing all child nodes.
5
+ */
6
+ export function getNodesCountWithExtensionKeys(node) {
7
+ const nodes = {};
8
+ const extensionKeys = {};
9
+ const extensionNodeNames = ['extension', 'bodiedExtension', 'inlineExtension', 'multiBodiedExtension'];
10
+ node.nodesBetween(0, node.nodeSize - 2, currentNode => {
11
+ var _currentNode$attrs;
12
+ nodes[currentNode.type.name] = (nodes[currentNode.type.name] || 0) + 1;
13
+ if (!extensionNodeNames.includes(currentNode.type.name)) {
14
+ return;
15
+ }
16
+ const extensionKey = (_currentNode$attrs = currentNode.attrs) === null || _currentNode$attrs === void 0 ? void 0 : _currentNode$attrs.extensionKey;
17
+ if (!extensionKey) {
18
+ return;
19
+ }
20
+ extensionKeys[extensionKey] = (extensionKeys[extensionKey] || 0) + 1;
21
+ });
22
+ return {
23
+ nodes,
24
+ extensionKeys
25
+ };
26
+ }
@@ -1,2 +1,2 @@
1
1
  export const name = "@atlaskit/editor-core";
2
- export const version = "216.10.0";
2
+ export const version = "216.11.2";
@@ -125,6 +125,7 @@ export var EditorInternal = /*#__PURE__*/memo(function (_ref) {
125
125
  minHeight: props.minHeight,
126
126
  onSave: props.onSave ? handleSave : undefined,
127
127
  onCancel: props.onCancel,
128
+ onSSRMeasure: props.onSSRMeasure,
128
129
  popupsMountPoint: props.popupsMountPoint,
129
130
  popupsBoundariesElement: props.popupsBoundariesElement,
130
131
  popupsScrollableElement: props.popupsScrollableElement,
@@ -87,6 +87,7 @@ export var useMemoEditorProps = function useMemoEditorProps(passedProps) {
87
87
  mention: passedProps.mention,
88
88
  mentionInsertDisplayName: passedProps.mentionInsertDisplayName,
89
89
  uploadErrorHandler: passedProps.uploadErrorHandler,
90
+ onSSRMeasure: passedProps.onSSRMeasure,
90
91
  waitForMediaUpload: passedProps.waitForMediaUpload,
91
92
  extensionHandlers: passedProps.extensionHandlers,
92
93
  allowTextColor: passedProps.allowTextColor,
@@ -111,7 +112,7 @@ export var useMemoEditorProps = function useMemoEditorProps(passedProps) {
111
112
  };
112
113
  var nextProps = _objectSpread(_objectSpread({}, defaultProps), allProps);
113
114
  return nextProps;
114
- }, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.performanceTracking, passedProps.inputSamplingLimit, passedProps.defaultValue, passedProps.assistiveLabel, passedProps.assistiveDescribedBy, passedProps.popupsMountPoint, passedProps.popupsBoundariesElement, passedProps.popupsScrollableElement, passedProps.editorActions, passedProps.onEditorReady, passedProps.onDestroy, passedProps.onChange, passedProps.onCancel, passedProps.extensionProviders, passedProps.UNSAFE_useAnalyticsContext, passedProps.useStickyToolbar, passedProps.featureFlags, passedProps.onSave, passedProps.sanitizePrivateContent, passedProps.media, passedProps.collabEdit, passedProps.primaryToolbarComponents, passedProps.allowUndoRedoButtons, passedProps.linking, passedProps.activityProvider, passedProps.searchProvider, passedProps.annotationProviders, passedProps.collabEditProvider, passedProps.presenceProvider, passedProps.emojiProvider, passedProps.taskDecisionProvider, passedProps.legacyImageUploadProvider, passedProps.mentionProvider, passedProps.autoformattingProvider, passedProps.macroProvider, passedProps.contextIdentifierProvider, passedProps.allowExpand, passedProps.allowNestedTasks, passedProps.allowBlockType, passedProps.allowTasksAndDecisions, passedProps.allowBreakout, passedProps.allowRule, passedProps.allowHelpDialog, passedProps.allowPanel, passedProps.allowExtension, passedProps.allowConfluenceInlineComment, passedProps.allowTemplatePlaceholders, passedProps.allowDate, passedProps.allowLayouts, passedProps.allowStatus, passedProps.allowTextAlignment, passedProps.allowIndentation, passedProps.showIndentationButtons, passedProps.allowFindReplace, passedProps.allowBorderMark, passedProps.allowFragmentMark, passedProps.autoScrollIntoView, passedProps.elementBrowser, passedProps.maxContentSize, passedProps.saveOnEnter, passedProps.feedbackInfo, passedProps.mention, passedProps.mentionInsertDisplayName, passedProps.uploadErrorHandler, passedProps.waitForMediaUpload, passedProps.extensionHandlers, passedProps.allowTextColor, passedProps.allowTables, passedProps.insertMenuItems, passedProps.UNSAFE_cards, passedProps.smartLinks, passedProps.allowAnalyticsGASV3, passedProps.codeBlock, passedProps.textFormatting, passedProps.__livePage, passedProps.AppearanceComponent, passedProps.skipValidation, passedProps.syncBlock, passedProps.syncedBlockProvider, passedProps.pasteWarningOptions]);
115
+ }, [passedProps.preset, passedProps.appearance, passedProps.contentMode, passedProps.contentComponents, passedProps.primaryToolbarIconBefore, passedProps.secondaryToolbarComponents, passedProps.persistScrollGutter, passedProps.quickInsert, passedProps.shouldFocus, passedProps.disabled, passedProps.contextPanel, passedProps.errorReporterHandler, passedProps.contentTransformerProvider, passedProps.maxHeight, passedProps.minHeight, passedProps.placeholder, passedProps.placeholderBracketHint, passedProps.performanceTracking, passedProps.inputSamplingLimit, passedProps.defaultValue, passedProps.assistiveLabel, passedProps.assistiveDescribedBy, passedProps.popupsMountPoint, passedProps.popupsBoundariesElement, passedProps.popupsScrollableElement, passedProps.editorActions, passedProps.onEditorReady, passedProps.onDestroy, passedProps.onChange, passedProps.onCancel, passedProps.onSSRMeasure, passedProps.extensionProviders, passedProps.UNSAFE_useAnalyticsContext, passedProps.useStickyToolbar, passedProps.featureFlags, passedProps.onSave, passedProps.sanitizePrivateContent, passedProps.media, passedProps.collabEdit, passedProps.primaryToolbarComponents, passedProps.allowUndoRedoButtons, passedProps.linking, passedProps.activityProvider, passedProps.searchProvider, passedProps.annotationProviders, passedProps.collabEditProvider, passedProps.presenceProvider, passedProps.emojiProvider, passedProps.taskDecisionProvider, passedProps.legacyImageUploadProvider, passedProps.mentionProvider, passedProps.autoformattingProvider, passedProps.macroProvider, passedProps.contextIdentifierProvider, passedProps.allowExpand, passedProps.allowNestedTasks, passedProps.allowBlockType, passedProps.allowTasksAndDecisions, passedProps.allowBreakout, passedProps.allowRule, passedProps.allowHelpDialog, passedProps.allowPanel, passedProps.allowExtension, passedProps.allowConfluenceInlineComment, passedProps.allowTemplatePlaceholders, passedProps.allowDate, passedProps.allowLayouts, passedProps.allowStatus, passedProps.allowTextAlignment, passedProps.allowIndentation, passedProps.showIndentationButtons, passedProps.allowFindReplace, passedProps.allowBorderMark, passedProps.allowFragmentMark, passedProps.autoScrollIntoView, passedProps.elementBrowser, passedProps.maxContentSize, passedProps.saveOnEnter, passedProps.feedbackInfo, passedProps.mention, passedProps.mentionInsertDisplayName, passedProps.uploadErrorHandler, passedProps.waitForMediaUpload, passedProps.extensionHandlers, passedProps.allowTextColor, passedProps.allowTables, passedProps.insertMenuItems, passedProps.UNSAFE_cards, passedProps.smartLinks, passedProps.allowAnalyticsGASV3, passedProps.codeBlock, passedProps.textFormatting, passedProps.__livePage, passedProps.AppearanceComponent, passedProps.skipValidation, passedProps.syncBlock, passedProps.syncedBlockProvider, passedProps.pasteWarningOptions]);
115
116
  return memodProps;
116
117
  };
117
118
  export default useMemoEditorProps;
@@ -14,10 +14,12 @@ import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, PLATFORMS } fro
14
14
  import { isSSR } from '@atlaskit/editor-common/core-utils';
15
15
  import { createDispatch, EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
16
16
  import { useConstructor, usePreviousState } from '@atlaskit/editor-common/hooks';
17
+ import { isPerformanceAPIAvailable } from '@atlaskit/editor-common/is-performance-api-available';
17
18
  import { nodeVisibilityManager } from '@atlaskit/editor-common/node-visibility';
18
19
  import { getEnabledFeatureFlagKeys } from '@atlaskit/editor-common/normalize-feature-flags';
19
20
  import { measureRender } from '@atlaskit/editor-common/performance/measure-render';
20
- import { getResponseEndTime } from '@atlaskit/editor-common/performance/navigation';
21
+ import { getRequestToResponseTime, getResponseEndTime } from '@atlaskit/editor-common/performance/navigation';
22
+ import { profileSSROperation, SSRRenderMeasure } from '@atlaskit/editor-common/performance/ssr-measures';
21
23
  import { EditorPluginInjectionAPI } from '@atlaskit/editor-common/preset';
22
24
  import { processRawValue, processRawValueWithoutValidation } from '@atlaskit/editor-common/process-raw-value';
23
25
  import { ReactEditorViewContext } from '@atlaskit/editor-common/ui-react';
@@ -27,12 +29,14 @@ import { EditorState, Selection, TextSelection } from '@atlaskit/editor-prosemir
27
29
  import { EditorView } from '@atlaskit/editor-prosemirror/view';
28
30
  import { EditorSSRRenderer } from '@atlaskit/editor-ssr-renderer';
29
31
  import { fg } from '@atlaskit/platform-feature-flags';
32
+ import { getInteractionId } from '@atlaskit/react-ufo/interaction-id-context';
30
33
  import { abortAll, getActiveInteraction } from '@atlaskit/react-ufo/interaction-metrics';
31
34
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
32
35
  import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
33
36
  import { useProviders } from '../composable-editor/hooks/useProviders';
34
37
  import { createFeatureFlagsFromProps } from '../utils/feature-flags-from-props';
35
38
  import { getNodesCount } from '../utils/getNodesCount';
39
+ import { getNodesCountWithExtensionKeys } from '../utils/getNodesCountWithExtensionKeys';
36
40
  import { getNodesVisibleInViewport } from '../utils/getNodesVisibleInViewport';
37
41
  import { isChromeless } from '../utils/is-chromeless';
38
42
  import { isFullPage } from '../utils/is-full-page';
@@ -49,10 +53,15 @@ import { handleEditorFocus } from './ReactEditorView/handleEditorFocus';
49
53
  import { useDispatchTransaction } from './ReactEditorView/useDispatchTransaction';
50
54
  import { useFireFullWidthEvent } from './ReactEditorView/useFireFullWidthEvent';
51
55
  var EDIT_AREA_ID = 'ak-editor-textarea';
56
+ var SSR_TRACE_SEGMENT_NAME = 'reactEditorView';
57
+ var bootStartTime = isPerformanceAPIAvailable() ? performance.now() : undefined;
52
58
  export function ReactEditorView(props) {
53
59
  var _pluginInjectionAPI$c, _media, _linking, _document$querySelect, _props$render, _props$render2;
60
+ // Should be always the first statement in the component
61
+ var firstRenderStartTimestampRef = useRef(performance.now());
54
62
  var preset = props.preset,
55
63
  _props$editorProps = props.editorProps,
64
+ onSSRMeasure = _props$editorProps.onSSRMeasure,
56
65
  nextAppearance = _props$editorProps.appearance,
57
66
  disabled = _props$editorProps.disabled,
58
67
  editorPropFeatureFlags = _props$editorProps.featureFlags,
@@ -458,9 +467,11 @@ export function ReactEditorView(props) {
458
467
  distortedDuration = _ref3.distortedDuration;
459
468
  var proseMirrorRenderedSeverity = getAnalyticsEventSeverity(duration, PROSEMIRROR_RENDERED_NORMAL_SEVERITY_THRESHOLD, PROSEMIRROR_RENDERED_DEGRADED_SEVERITY_THRESHOLD);
460
469
  if (viewRef.current) {
461
- var _pluginInjectionAPI$c2;
462
- var nodes = getNodesCount(viewRef.current.state.doc);
470
+ var _nodesAndExtensionKey, _pluginInjectionAPI$c2;
471
+ var nodesAndExtensionKeys = expValEquals('platform_editor_prosemirror_rendered_data', 'isEnabled', true) ? getNodesCountWithExtensionKeys(viewRef.current.state.doc) : undefined;
472
+ var nodes = (_nodesAndExtensionKey = nodesAndExtensionKeys === null || nodesAndExtensionKeys === void 0 ? void 0 : nodesAndExtensionKeys.nodes) !== null && _nodesAndExtensionKey !== void 0 ? _nodesAndExtensionKey : getNodesCount(viewRef.current.state.doc);
463
473
  var ttfb = getResponseEndTime();
474
+ var requestToResponseTime = getRequestToResponseTime();
464
475
  var contextIdentifier = (_pluginInjectionAPI$c2 = pluginInjectionAPI.current.api().base) === null || _pluginInjectionAPI$c2 === void 0 ? void 0 : _pluginInjectionAPI$c2.sharedState.currentState();
465
476
  var nodesInViewport = getNodesVisibleInViewport(viewRef.current.dom);
466
477
  var nodeSize = viewRef.current.state.doc.nodeSize;
@@ -488,10 +499,51 @@ export function ReactEditorView(props) {
488
499
  } : {},
489
500
  totalNodes = _ref4.totalNodes,
490
501
  nodeSizeBucket = _ref4.nodeSizeBucket;
491
- dispatchAnalyticsEvent({
492
- action: ACTION.PROSEMIRROR_RENDERED,
493
- actionSubject: ACTION_SUBJECT.EDITOR,
494
- attributes: {
502
+ if (expValEquals('platform_editor_prosemirror_rendered_data', 'isEnabled', true)) {
503
+ var _nodesAndExtensionKey2;
504
+ var extensionKeys = (_nodesAndExtensionKey2 = nodesAndExtensionKeys === null || nodesAndExtensionKeys === void 0 ? void 0 : nodesAndExtensionKeys.extensionKeys) !== null && _nodesAndExtensionKey2 !== void 0 ? _nodesAndExtensionKey2 : {};
505
+ var interaction = getActiveInteraction();
506
+ var pageLoadType = interaction === null || interaction === void 0 ? void 0 : interaction.type;
507
+ var pageType = interaction === null || interaction === void 0 ? void 0 : interaction.routeName;
508
+ var timings = function () {
509
+ if (requestToResponseTime === undefined && bootStartTime === undefined) {
510
+ return undefined;
511
+ }
512
+ var timingValues = {};
513
+ if (requestToResponseTime !== undefined) {
514
+ timingValues['requestStart->responseEnd'] = Math.round(requestToResponseTime);
515
+ }
516
+ if (bootStartTime !== undefined) {
517
+ timingValues.bootToRender = Math.round(startTime - bootStartTime);
518
+ }
519
+ return timingValues;
520
+ }();
521
+ var attributes = {
522
+ duration: duration,
523
+ startTime: startTime,
524
+ nodes: nodes,
525
+ nodesInViewport: nodesInViewport,
526
+ nodeSize: nodeSize,
527
+ nodeSizeBucket: nodeSizeBucket,
528
+ totalNodes: totalNodes,
529
+ ttfb: ttfb,
530
+ severity: proseMirrorRenderedSeverity,
531
+ objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
532
+ distortedDuration: distortedDuration,
533
+ pageLoadType: pageLoadType,
534
+ pageType: pageType,
535
+ timings: timings,
536
+ extensionKeys: extensionKeys,
537
+ ufoInteractionId: getInteractionId().current
538
+ };
539
+ dispatchAnalyticsEvent({
540
+ action: ACTION.PROSEMIRROR_RENDERED,
541
+ actionSubject: ACTION_SUBJECT.EDITOR,
542
+ attributes: attributes,
543
+ eventType: EVENT_TYPE.OPERATIONAL
544
+ });
545
+ } else {
546
+ var _attributes = {
495
547
  duration: duration,
496
548
  startTime: startTime,
497
549
  nodes: nodes,
@@ -503,9 +555,14 @@ export function ReactEditorView(props) {
503
555
  severity: proseMirrorRenderedSeverity,
504
556
  objectId: contextIdentifier === null || contextIdentifier === void 0 ? void 0 : contextIdentifier.objectId,
505
557
  distortedDuration: distortedDuration
506
- },
507
- eventType: EVENT_TYPE.OPERATIONAL
508
- });
558
+ };
559
+ dispatchAnalyticsEvent({
560
+ action: ACTION.PROSEMIRROR_RENDERED,
561
+ actionSubject: ACTION_SUBJECT.EDITOR,
562
+ attributes: _attributes,
563
+ eventType: EVENT_TYPE.OPERATIONAL
564
+ });
565
+ }
509
566
  }
510
567
  });
511
568
  pluginInjectionAPI.current.onEditorViewUpdated({
@@ -769,20 +826,29 @@ export function ReactEditorView(props) {
769
826
  if (!isSSR() || !expValEquals('platform_editor_ssr_renderer', 'isEnabled', true)) {
770
827
  return null;
771
828
  }
772
- var plugins = createPluginsList(props.preset,
773
- // Don't pass props.editorProps directly, because editoProps in the dependency will lead to
774
- // multiple repaints, because props.editorPros is not stable object.
775
- {
776
- allowBlockType: allowBlockType
777
- }, pluginInjectionAPI.current);
778
- var schema = createSchema(processPluginsList(plugins));
779
- var doc = buildDoc(schema);
829
+ var doCreatePluginList = function doCreatePluginList() {
830
+ return createPluginsList(props.preset,
831
+ // Don't pass props.editorProps directly, because editoProps in the dependency will lead to
832
+ // multiple repaints, because props.editorPros is not stable object.
833
+ {
834
+ allowBlockType: allowBlockType
835
+ }, pluginInjectionAPI.current);
836
+ };
837
+ var plugins = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation("".concat(SSR_TRACE_SEGMENT_NAME, "/createPluginsList"), doCreatePluginList, onSSRMeasure) : doCreatePluginList();
838
+ var doCreateSchema = function doCreateSchema() {
839
+ return createSchema(processPluginsList(plugins));
840
+ };
841
+ var schema = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation("".concat(SSR_TRACE_SEGMENT_NAME, "/createSchema"), doCreateSchema, onSSRMeasure) : doCreateSchema();
842
+ var doBuildDoc = function doBuildDoc() {
843
+ return buildDoc(schema);
844
+ };
845
+ var doc = fg('platform_editor_better_editor_ssr_spans') ? profileSSROperation("".concat(SSR_TRACE_SEGMENT_NAME, "/buildDoc"), doBuildDoc, onSSRMeasure) : doBuildDoc();
780
846
  return {
781
847
  plugins: plugins,
782
848
  schema: schema,
783
849
  doc: doc
784
850
  };
785
- }, [allowBlockType, buildDoc, props.preset]);
851
+ }, [allowBlockType, buildDoc, props.preset, onSSRMeasure]);
786
852
  var _props$editorProps3 = props.editorProps,
787
853
  assistiveLabel = _props$editorProps3.assistiveLabel,
788
854
  assistiveDescribedBy = _props$editorProps3.assistiveDescribedBy;
@@ -805,6 +871,7 @@ export function ReactEditorView(props) {
805
871
  id: EDIT_AREA_ID,
806
872
  "aria-describedby": assistiveDescribedBy,
807
873
  "data-editor-id": editorId.current,
874
+ onSSRMeasure: onSSRMeasure,
808
875
  onEditorStateChanged: function onEditorStateChanged(state) {
809
876
  ssrEditorStateRef.current = state;
810
877
  // Notify listeners about the initial SSR state
@@ -814,7 +881,7 @@ export function ReactEditorView(props) {
814
881
  });
815
882
  }
816
883
  });
817
- }, [ssrDeps, props.intl, props.portalProviderAPI, assistiveLabel, assistiveDescribedBy, isPageAppearance]);
884
+ }, [ssrDeps, props.intl, props.portalProviderAPI, assistiveLabel, isPageAppearance, assistiveDescribedBy, onSSRMeasure]);
818
885
  var editor = useMemo(function () {
819
886
  // SSR editor will be available only in SSR environment,
820
887
  // in a browser `ssrEditor` will be `null`, and we will render a normal one ProseMirror.
@@ -831,7 +898,11 @@ export function ReactEditorView(props) {
831
898
  // 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
832
899
  // Also firing too many events for the legacy content macro, so disabling for now. See - https://product-fabric.atlassian.net/browse/ED-26650
833
900
  var renderTrackingEnabled = !fg('platform_editor_disable_rerender_tracking_jira') && !featureFlags.lcmPreventRenderTracking;
834
- return /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
901
+ return /*#__PURE__*/React.createElement(SSRRenderMeasure, {
902
+ segmentName: SSR_TRACE_SEGMENT_NAME,
903
+ startTimestampRef: firstRenderStartTimestampRef,
904
+ onSSRMeasure: fg('platform_editor_better_editor_ssr_spans') ? onSSRMeasure : undefined
905
+ }, /*#__PURE__*/React.createElement(ReactEditorViewContext.Provider, {
835
906
  value: {
836
907
  editorRef: editorRef,
837
908
  editorView: viewRef.current,
@@ -852,7 +923,7 @@ export function ReactEditorView(props) {
852
923
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
853
924
  editorRef: editorRef,
854
925
  editorAPI: expVal('platform_editor_no_state_plugin_injection_api', 'isEnabled', false) ? pluginInjectionAPI.current.api() : editorAPI
855
- })) !== null && _props$render !== void 0 ? _props$render : editor : editor);
926
+ })) !== null && _props$render !== void 0 ? _props$render : editor : editor));
856
927
  }
857
928
 
858
929
  // Preserving exact type generated by TypeScript
@@ -9,6 +9,7 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
9
9
  import { jsx } from '@emotion/react';
10
10
  import { browser as browserLegacy, getBrowserInfo } from '@atlaskit/editor-common/browser';
11
11
  import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
12
+ import { SSRRenderMeasure } from '@atlaskit/editor-common/performance/ssr-measures';
12
13
  import { ContextPanelWidthProvider } from '@atlaskit/editor-common/ui';
13
14
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
14
15
  import { FULL_PAGE_EDITOR_TOOLBAR_HEIGHT } from '@atlaskit/editor-shared-styles';
@@ -20,6 +21,7 @@ import { FullPageContentArea } from './FullPageContentArea';
20
21
  import { FullPageToolbar } from './FullPageToolbar';
21
22
  import { FullPageToolbarNext } from './FullPageToolbarNext';
22
23
  import { fullPageEditorWrapper } from './StyledComponents';
24
+ var SSR_TRACE_SEGMENT_NAME = 'reactEditorView/fullPageAppearance';
23
25
  var useShowKeyline = function useShowKeyline(contentAreaRef) {
24
26
  var _useState = useState(false),
25
27
  _useState2 = _slicedToArray(_useState, 2),
@@ -61,6 +63,8 @@ var hasCustomComponents = function hasCustomComponents(components) {
61
63
  };
62
64
  export var FullPageEditor = function FullPageEditor(props) {
63
65
  var _scrollContentContain, _scrollContentContain2, _scrollContentContain3, _wrapperElementRef$cu;
66
+ // Should be always the first statement in the component
67
+ var firstRenderStartTimestampRef = useRef(performance.now());
64
68
  var wrapperElementRef = useMemo(function () {
65
69
  return props.innerRef;
66
70
  }, [props.innerRef]);
@@ -134,7 +138,11 @@ export var FullPageEditor = function FullPageEditor(props) {
134
138
  }
135
139
  var isToolbarAIFCEnabled = Boolean(editorAPI === null || editorAPI === void 0 ? void 0 : editorAPI.toolbar);
136
140
  var popupsBoundariesElement = props.popupsBoundariesElement || (scrollContentContainerRef === null || scrollContentContainerRef === void 0 || (_scrollContentContain = scrollContentContainerRef.current) === null || _scrollContentContain === void 0 ? void 0 : _scrollContentContain.containerArea) || undefined;
137
- return jsx(ContextPanelWidthProvider, null, jsx("div", {
141
+ return jsx(SSRRenderMeasure, {
142
+ segmentName: SSR_TRACE_SEGMENT_NAME,
143
+ startTimestampRef: firstRenderStartTimestampRef,
144
+ onSSRMeasure: fg('platform_editor_better_editor_ssr_spans') ? props.onSSRMeasure : undefined
145
+ }, jsx(ContextPanelWidthProvider, null, jsx("div", {
138
146
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
139
147
  css: fullPageEditorWrapper
140
148
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -211,5 +219,5 @@ export var FullPageEditor = function FullPageEditor(props) {
211
219
  viewMode: state.editorViewMode,
212
220
  hasHadInteraction: hasHadInteraction,
213
221
  contentMode: props.contentMode
214
- })));
222
+ }))));
215
223
  };
@@ -1,3 +1,4 @@
1
+ // When experiment platform_editor_prosemirror_rendered_data is removed, review whether this helper is still needed.
1
2
  export function getNodesCount(node) {
2
3
  var count = {};
3
4
  node.nodesBetween(0, node.nodeSize - 2, function (node) {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Counts node types and extension keys in a single traversal.
3
+ * We exclude the end-of-doc token by iterating to nodeSize - 2,
4
+ * which matches the typical ProseMirror pattern for traversing all child nodes.
5
+ */
6
+ export function getNodesCountWithExtensionKeys(node) {
7
+ var nodes = {};
8
+ var extensionKeys = {};
9
+ var extensionNodeNames = ['extension', 'bodiedExtension', 'inlineExtension', 'multiBodiedExtension'];
10
+ node.nodesBetween(0, node.nodeSize - 2, function (currentNode) {
11
+ var _currentNode$attrs;
12
+ nodes[currentNode.type.name] = (nodes[currentNode.type.name] || 0) + 1;
13
+ if (!extensionNodeNames.includes(currentNode.type.name)) {
14
+ return;
15
+ }
16
+ var extensionKey = (_currentNode$attrs = currentNode.attrs) === null || _currentNode$attrs === void 0 ? void 0 : _currentNode$attrs.extensionKey;
17
+ if (!extensionKey) {
18
+ return;
19
+ }
20
+ extensionKeys[extensionKey] = (extensionKeys[extensionKey] || 0) + 1;
21
+ });
22
+ return {
23
+ nodes: nodes,
24
+ extensionKeys: extensionKeys
25
+ };
26
+ }
@@ -1,2 +1,2 @@
1
1
  export var name = "@atlaskit/editor-core";
2
- export var version = "216.10.0";
2
+ export var version = "216.11.2";
@@ -29,6 +29,11 @@ export interface EditorViewProps extends WrappedComponentProps {
29
29
  transformer?: Transformer<string>;
30
30
  view: EditorView;
31
31
  }) => void;
32
+ onSSRMeasure?: (measure: {
33
+ endTimestamp: number;
34
+ segmentName: string;
35
+ startTimestamp: number;
36
+ }) => void;
32
37
  portalProviderAPI: PortalProviderAPI;
33
38
  preset: EditorPresetBuilder<string[], AllEditorPresetPluginTypes[]>;
34
39
  providerFactory: ProviderFactory;
@@ -37,6 +37,11 @@ export interface EditorAppearanceComponentProps<Plugins extends NextEditorPlugin
37
37
  minHeight?: number;
38
38
  onCancel?: (editorView: EditorView) => void;
39
39
  onSave?: (editorView: EditorView) => void;
40
+ onSSRMeasure?: (measure: {
41
+ endTimestamp: number;
42
+ segmentName: string;
43
+ startTimestamp: number;
44
+ }) => void;
40
45
  persistScrollGutter?: boolean;
41
46
  pluginHooks?: ReactHookFactory[];
42
47
  popupsBoundariesElement?: HTMLElement;