@atlaskit/renderer 148.1.0 → 149.0.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 (53) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cjs/actions/index.js +35 -3
  3. package/dist/cjs/react/index.js +8 -0
  4. package/dist/cjs/react/marks/annotation.js +3 -1
  5. package/dist/cjs/react/nodes/extension-comments.compiled.css +4 -0
  6. package/dist/cjs/react/nodes/extension-comments.js +144 -0
  7. package/dist/cjs/react/nodes/extension.js +86 -11
  8. package/dist/cjs/steps/index.js +23 -0
  9. package/dist/cjs/ui/Renderer/index.js +1 -1
  10. package/dist/cjs/ui/annotations/contexts/AnnotationRangeContext.js +29 -11
  11. package/dist/cjs/ui/annotations/element/extension.compiled.css +6 -0
  12. package/dist/cjs/ui/annotations/element/extension.js +34 -0
  13. package/dist/cjs/ui/annotations/element/index.js +4 -2
  14. package/dist/cjs/ui/annotations/element/mark.js +11 -1
  15. package/dist/cjs/ui/annotations/index.js +2 -1
  16. package/dist/es2019/actions/index.js +33 -3
  17. package/dist/es2019/react/index.js +8 -0
  18. package/dist/es2019/react/marks/annotation.js +3 -1
  19. package/dist/es2019/react/nodes/extension-comments.compiled.css +4 -0
  20. package/dist/es2019/react/nodes/extension-comments.js +115 -0
  21. package/dist/es2019/react/nodes/extension.js +83 -7
  22. package/dist/es2019/steps/index.js +25 -0
  23. package/dist/es2019/ui/Renderer/index.js +1 -1
  24. package/dist/es2019/ui/annotations/contexts/AnnotationRangeContext.js +28 -12
  25. package/dist/es2019/ui/annotations/element/extension.compiled.css +6 -0
  26. package/dist/es2019/ui/annotations/element/extension.js +26 -0
  27. package/dist/es2019/ui/annotations/element/index.js +4 -2
  28. package/dist/es2019/ui/annotations/element/mark.js +11 -1
  29. package/dist/es2019/ui/annotations/index.js +2 -1
  30. package/dist/esm/actions/index.js +35 -3
  31. package/dist/esm/react/index.js +8 -0
  32. package/dist/esm/react/marks/annotation.js +3 -1
  33. package/dist/esm/react/nodes/extension-comments.compiled.css +4 -0
  34. package/dist/esm/react/nodes/extension-comments.js +135 -0
  35. package/dist/esm/react/nodes/extension.js +86 -7
  36. package/dist/esm/steps/index.js +23 -0
  37. package/dist/esm/ui/Renderer/index.js +1 -1
  38. package/dist/esm/ui/annotations/contexts/AnnotationRangeContext.js +30 -12
  39. package/dist/esm/ui/annotations/element/extension.compiled.css +6 -0
  40. package/dist/esm/ui/annotations/element/extension.js +27 -0
  41. package/dist/esm/ui/annotations/element/index.js +4 -2
  42. package/dist/esm/ui/annotations/element/mark.js +11 -1
  43. package/dist/esm/ui/annotations/index.js +2 -1
  44. package/dist/types/actions/index.d.ts +13 -0
  45. package/dist/types/react/marks/annotation.d.ts +1 -1
  46. package/dist/types/react/nodes/extension-comments.d.ts +17 -0
  47. package/dist/types/react/nodes/extension.d.ts +12 -0
  48. package/dist/types/react/types.d.ts +1 -0
  49. package/dist/types/ui/annotations/contexts/AnnotationRangeContext.d.ts +4 -2
  50. package/dist/types/ui/annotations/element/extension.d.ts +17 -0
  51. package/dist/types/ui/annotations/element/index.d.ts +2 -1
  52. package/dist/types/ui/annotations/element/mark.d.ts +3 -107
  53. package/package.json +4 -4
@@ -12,6 +12,7 @@ import { AnnotationMarkStates } from '@atlaskit/adf-schema/annotation';
12
12
  import { fg } from '@atlaskit/platform-feature-flags/fg';
13
13
  import { inlineCommentMessages } from '../../../messages';
14
14
  import { useAnnotationManagerDispatch, useAnnotationManagerState } from '../contexts/AnnotationManagerContext';
15
+ import { ExtensionAnnotation } from './extension';
15
16
  const markStyles = css({
16
17
  color: 'inherit',
17
18
  backgroundColor: 'unset',
@@ -130,7 +131,8 @@ export const MarkComponent = ({
130
131
  hasFocus,
131
132
  isHovered,
132
133
  onClick,
133
- useBlockLevel
134
+ useBlockLevel,
135
+ isExtension
134
136
  }) => {
135
137
  const intl = useIntl();
136
138
  const annotationIds = useMemo(() => [...new Set([...annotationParentIds, id])], [id, annotationParentIds]);
@@ -223,6 +225,14 @@ export const MarkComponent = ({
223
225
  'aria-details': annotationIds.join(', '),
224
226
  ...desktopAccessibilityAttributes
225
227
  };
228
+ if (isExtension && fg('cc_maui_annotations_on_extensions')) {
229
+ // The chart's badge owns interaction. Anchors only supply geometry and annotation state.
230
+ return jsx(ExtensionAnnotation, {
231
+ id: id,
232
+ dataAttributes: overriddenData,
233
+ markRef: id === currentSelectedAnnotationId ? markRef : undefined
234
+ });
235
+ }
226
236
  return jsx(useBlockLevel ? 'div' : 'mark', {
227
237
  ref: id === currentSelectedAnnotationId ? markRef : undefined,
228
238
  id,
@@ -30,7 +30,7 @@ export const AnnotationsPositionContext = /*#__PURE__*/React.createContext({
30
30
  startPos: 1
31
31
  });
32
32
  export const AnnotationsWrapperInner = props => {
33
- var _providers$inlineComm, _providers$inlineComm2;
33
+ var _providers$inlineComm, _providers$inlineComm2, _providers$inlineComm3;
34
34
  const {
35
35
  children,
36
36
  rendererRef,
@@ -51,6 +51,7 @@ export const AnnotationsWrapperInner = props => {
51
51
  value: inlineCommentAnnotationsState
52
52
  }, /*#__PURE__*/React.createElement(AnnotationRangeProvider, {
53
53
  allowCommentsOnMedia: (_providers$inlineComm = providers === null || providers === void 0 ? void 0 : (_providers$inlineComm2 = providers.inlineComment) === null || _providers$inlineComm2 === void 0 ? void 0 : _providers$inlineComm2.allowCommentsOnMedia) !== null && _providers$inlineComm !== void 0 ? _providers$inlineComm : false,
54
+ hasBlockNodeSupport: Boolean(providers === null || providers === void 0 ? void 0 : (_providers$inlineComm3 = providers.inlineComment) === null || _providers$inlineComm3 === void 0 ? void 0 : _providers$inlineComm3.isBlockNodeSupported),
54
55
  isNestedRender: isNestedRender
55
56
  }, /*#__PURE__*/React.createElement(AnnotationHoverContext, null, /*#__PURE__*/React.createElement(AnnotationsContextWrapper, {
56
57
  createAnalyticsEvent: createAnalyticsEvent,
@@ -87,9 +87,10 @@ var RendererActions = /*#__PURE__*/function () {
87
87
  var to;
88
88
  var nodePos;
89
89
  var step;
90
+ var schema = this.schema;
90
91
  this.doc.descendants(function (node, pos) {
91
92
  var found = mark.isInSet(node.marks);
92
- if (found && node.type.name === 'media') {
93
+ if (found && isBlockAnnotationTarget(node, schema)) {
93
94
  nodePos = pos;
94
95
  }
95
96
  if (found && !from) {
@@ -184,13 +185,12 @@ var RendererActions = /*#__PURE__*/function () {
184
185
  key: "isRangeAnnotatable",
185
186
  value: function isRangeAnnotatable(range) {
186
187
  try {
187
- var _startContainer$paren, _endContainer$parentE;
188
188
  if (!range) {
189
189
  return false;
190
190
  }
191
191
  var startContainer = range.startContainer,
192
192
  endContainer = range.endContainer;
193
- if ((_startContainer$paren = startContainer.parentElement) !== null && _startContainer$paren !== void 0 && _startContainer$paren.closest('.ak-renderer-extension') || (_endContainer$parentE = endContainer.parentElement) !== null && _endContainer$parentE !== void 0 && _endContainer$parentE.closest('.ak-renderer-extension')) {
193
+ if (this.isInsideNestedExtensionRenderer(startContainer) || this.isInsideNestedExtensionRenderer(endContainer)) {
194
194
  return false;
195
195
  }
196
196
  return this.isValidAnnotationRange(range);
@@ -206,6 +206,38 @@ var RendererActions = /*#__PURE__*/function () {
206
206
  }
207
207
  }
208
208
 
209
+ /**
210
+ * A range only threatens a nested renderer's own document (e.g. a bodiedExtension's macro
211
+ * body, which renders its own nested `<Renderer>`) when it sits inside that nested renderer's
212
+ * `.ak-renderer-document`. Landing directly on the extension's own outer wrapper -- with no
213
+ * nested document in between -- must stay annotatable so the whole chart/extension can be
214
+ * targeted (MAUI-1256), rather than being rejected outright the way any range touching
215
+ * `.ak-renderer-extension` previously was.
216
+ *
217
+ * Behind `cc_maui_annotations_on_extensions` -- the same gate MAUI-1255 added for extension
218
+ * node-mark support -- to preserve the previous behaviour (reject anything touching
219
+ * `.ak-renderer-extension`) while the feature is off.
220
+ */
221
+ }, {
222
+ key: "isInsideNestedExtensionRenderer",
223
+ value: function isInsideNestedExtensionRenderer(container) {
224
+ // Preserve the legacy parent-based rejection while the gate is disabled.
225
+ if (!fg('cc_maui_annotations_on_extensions')) {
226
+ var _container$parentElem;
227
+ return !!((_container$parentElem = container.parentElement) !== null && _container$parentElem !== void 0 && _container$parentElem.closest('.ak-renderer-extension'));
228
+ }
229
+ var element = container instanceof Element ? container : container.parentElement;
230
+ if (!element) {
231
+ return false;
232
+ }
233
+ var extensionAncestor = element.closest('.ak-renderer-extension');
234
+ if (!extensionAncestor) {
235
+ return false;
236
+ }
237
+ var nestedDocument = element.closest('.ak-renderer-document');
238
+ return !!nestedDocument && extensionAncestor.contains(nestedDocument);
239
+ }
240
+
209
241
  // eslint-disable-next-line @repo/internal/deprecations/deprecation-ticket-required -- Ignored via go/ED-25883
210
242
  /**
211
243
  * This is replaced by `isRangeAnnotatable`.
@@ -97,6 +97,11 @@ var ReactSerializer = /*#__PURE__*/function () {
97
97
  if (shouldSkipLinkMark(mark) || shouldSkipBorderMark(mark)) {
98
98
  return content;
99
99
  }
100
+ // Extension annotations are sibling anchors inside the stable extension shell.
101
+ // Wrapping the extension here would remount its iframe whenever marks change.
102
+ if (node.type.name === 'extension' && mark.type.name === 'annotation' && _this.allowAnnotations && fg('cc_maui_annotations_on_extensions')) {
103
+ return content;
104
+ }
100
105
  return _this.renderMark(markToReact(mark), _this.withMediaMarkProps(node, mark, _this.getMarkProps(mark, [], node)), "".concat(mark.type.name, "-").concat(index), content);
101
106
  }, serializedContent);
102
107
  return withExpandBodyBlock(node, currentPath, index, serialized);
@@ -549,6 +554,9 @@ var ReactSerializer = /*#__PURE__*/function () {
549
554
  var _this$getExtensionHei;
550
555
  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
551
556
  return _objectSpread(_objectSpread({}, this.getProps(node, path)), {}, {
557
+ allowAnnotations: this.allowAnnotations,
558
+ allowAnnotationsDraftMode: this.surroundTextNodesWithTextWrapper,
559
+ extensionNode: node,
552
560
  extensionViewportSizes: this.extensionViewportSizes,
553
561
  hideExtensionKeysWhilePending: this.hideExtensionKeysWhilePending,
554
562
  nodeHeight: (_this$getExtensionHei = this.getExtensionHeight) === null || _this$getExtensionHei === void 0 ? void 0 : _this$getExtensionHei.call(this, node),
@@ -17,6 +17,7 @@ var AnnotationComponent = function AnnotationComponent(_ref) {
17
17
  annotationParentIds = _ref$annotationParent === void 0 ? [] : _ref$annotationParent,
18
18
  allowAnnotations = _ref.allowAnnotations,
19
19
  useBlockLevel = _ref.useBlockLevel,
20
+ isExtension = _ref.isExtension,
20
21
  isMediaInline = _ref.isMediaInline;
21
22
  var data = _objectSpread(_objectSpread({}, dataAttributes), buildAnnotationMarkDataAttributes({
22
23
  id: id,
@@ -36,7 +37,8 @@ var AnnotationComponent = function AnnotationComponent(_ref) {
36
37
  dataAttributes: data,
37
38
  annotationParentIds: annotationParentIds,
38
39
  annotationType: annotationType,
39
- useBlockLevel: useBlockLevel
40
+ useBlockLevel: useBlockLevel,
41
+ isExtension: isExtension
40
42
  }, children);
41
43
  }
42
44
  return (
@@ -0,0 +1,4 @@
1
+ ._154iu2gc{top:var(--ds-space-100,8px)}
2
+ ._1xi2u2gc{right:var(--ds-space-100,8px)}
3
+ ._kqswh2mm{position:relative}
4
+ ._kqswstnw{position:absolute}
@@ -0,0 +1,135 @@
1
+ /* extension-comments.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import "./extension-comments.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
6
+ import { AnnotationMarkStates, AnnotationTypes } from '@atlaskit/adf-schema/annotation';
7
+ import { VIEW_METHOD } from '@atlaskit/editor-common/analytics';
8
+ import { CommentBadgeNext } from '@atlaskit/editor-common/media-single';
9
+ import { AnnotationUpdateEvent } from '@atlaskit/editor-common/types';
10
+ import { useAnnotationManagerState } from '../../ui/annotations/contexts/AnnotationManagerContext';
11
+ import { useAnnotationRangeState } from '../../ui/annotations/contexts/AnnotationRangeContext';
12
+ import { useInlineCommentSubscriberContext } from '../../ui/annotations/hooks/use-inline-comment-subscriber';
13
+ import { useInlineCommentsFilter } from '../../ui/annotations/hooks/use-inline-comments-filter';
14
+ import AnnotationComponent from '../marks/annotation';
15
+ var containerStyles = null;
16
+ var annotationParentIds = [];
17
+ var annotationDataAttributes = {
18
+ 'data-renderer-mark': true,
19
+ 'data-block-mark': true
20
+ };
21
+ var badgeStyles = null;
22
+ var ExtensionCommentsEnabled = function ExtensionCommentsEnabled(_ref) {
23
+ var marks = _ref.marks,
24
+ children = _ref.children,
25
+ enabled = _ref.enabled,
26
+ allowAnnotations = _ref.allowAnnotations,
27
+ allowAnnotationsDraftMode = _ref.allowAnnotationsDraftMode,
28
+ startPos = _ref.startPos;
29
+ var _useAnnotationRangeSt = useAnnotationRangeState(),
30
+ hoverDraftDocumentPosition = _useAnnotationRangeSt.hoverDraftDocumentPosition;
31
+ var isDraft = Boolean(enabled && allowAnnotationsDraftMode && hoverDraftDocumentPosition && hoverDraftDocumentPosition.from + 1 === startPos);
32
+ var updateSubscriber = useInlineCommentSubscriberContext();
33
+ var annotationIds = useMemo(function () {
34
+ var _marks$filter$map;
35
+ return (_marks$filter$map = marks === null || marks === void 0 ? void 0 : marks.filter(function (mark) {
36
+ return mark.type.name === 'annotation';
37
+ }).map(function (mark) {
38
+ return mark.attrs.id;
39
+ })) !== null && _marks$filter$map !== void 0 ? _marks$filter$map : [];
40
+ }, [marks]);
41
+ var activeIds = useInlineCommentsFilter({
42
+ annotationIds: annotationIds,
43
+ filter: {
44
+ state: AnnotationMarkStates.ACTIVE
45
+ }
46
+ });
47
+ var _useState = useState(),
48
+ _useState2 = _slicedToArray(_useState, 2),
49
+ focusedId = _useState2[0],
50
+ setFocusedId = _useState2[1];
51
+ var _useState3 = useState(false),
52
+ _useState4 = _slicedToArray(_useState3, 2),
53
+ entered = _useState4[0],
54
+ setEntered = _useState4[1];
55
+ var _useAnnotationManager = useAnnotationManagerState(),
56
+ currentSelectedAnnotationId = _useAnnotationManager.currentSelectedAnnotationId;
57
+ var active = activeIds.some(function (id) {
58
+ return id === focusedId || id === currentSelectedAnnotationId;
59
+ });
60
+ useEffect(function () {
61
+ if (!updateSubscriber) {
62
+ return;
63
+ }
64
+ var onFocus = function onFocus(payload) {
65
+ return setFocusedId(payload === null || payload === void 0 ? void 0 : payload.annotationId);
66
+ };
67
+ var onBlur = function onBlur() {
68
+ return setFocusedId(undefined);
69
+ };
70
+ updateSubscriber.on(AnnotationUpdateEvent.SET_ANNOTATION_FOCUS, onFocus);
71
+ updateSubscriber.on(AnnotationUpdateEvent.REMOVE_ANNOTATION_FOCUS, onBlur);
72
+ return function () {
73
+ updateSubscriber.off(AnnotationUpdateEvent.SET_ANNOTATION_FOCUS, onFocus);
74
+ updateSubscriber.off(AnnotationUpdateEvent.REMOVE_ANNOTATION_FOCUS, onBlur);
75
+ };
76
+ }, [updateSubscriber]);
77
+ var onClick = useCallback(function (event) {
78
+ event.preventDefault();
79
+ event.stopPropagation();
80
+ // Anchor the thread to this chart, not an icon inside the badge or a nested renderer.
81
+ var extension = event.currentTarget.closest('.ak-renderer-extension');
82
+ if (extension && activeIds.length) {
83
+ updateSubscriber === null || updateSubscriber === void 0 || updateSubscriber.emit(AnnotationUpdateEvent.ON_ANNOTATION_CLICK, {
84
+ annotationIds: activeIds,
85
+ eventTarget: extension,
86
+ eventTargetType: 'extension',
87
+ viewMethod: VIEW_METHOD.BADGE
88
+ });
89
+ }
90
+ }, [activeIds, updateSubscriber]);
91
+ var onMouseEnter = useCallback(function () {
92
+ return setEntered(true);
93
+ }, []);
94
+ var onMouseLeave = useCallback(function () {
95
+ return setEntered(false);
96
+ }, []);
97
+ return /*#__PURE__*/React.createElement("div", {
98
+ "data-annotation-draft-mark": isDraft || undefined,
99
+ "data-renderer-mark": isDraft || undefined,
100
+ "data-renderer-start-pos": isDraft ? startPos : undefined,
101
+ className: ax(["_kqswh2mm"])
102
+ }, children, allowAnnotations && annotationIds.map(function (id) {
103
+ return /*#__PURE__*/React.createElement(AnnotationComponent, {
104
+ key: id,
105
+ id: id,
106
+ annotationType: AnnotationTypes.INLINE_COMMENT,
107
+ annotationParentIds: annotationParentIds,
108
+ allowAnnotations: true,
109
+ useBlockLevel: true,
110
+ isExtension: true,
111
+ dataAttributes: annotationDataAttributes
112
+ });
113
+ }), enabled && activeIds.length > 0 && updateSubscriber && /*#__PURE__*/React.createElement("div", {
114
+ className: ax(["_kqswstnw _154iu2gc _1xi2u2gc"])
115
+ }, /*#__PURE__*/React.createElement(CommentBadgeNext, {
116
+ status: active ? 'active' : entered ? 'entered' : 'default',
117
+ onClick: onClick,
118
+ onMouseEnter: onMouseEnter,
119
+ onMouseLeave: onMouseLeave
120
+ })));
121
+ };
122
+
123
+ /** Only node-aware provider-approved extensions receive comment visuals. */
124
+ export var ExtensionComments = function ExtensionComments(props) {
125
+ if (!props.enabled && !props.allowAnnotations) {
126
+ return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
127
+ }
128
+ return /*#__PURE__*/React.createElement(ExtensionCommentsEnabled, {
129
+ enabled: props.enabled,
130
+ allowAnnotations: props.allowAnnotations,
131
+ allowAnnotationsDraftMode: props.allowAnnotationsDraftMode,
132
+ startPos: props.startPos,
133
+ marks: props.marks
134
+ }, props.children);
135
+ };
@@ -1,10 +1,13 @@
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
5
8
  */
6
9
 
7
- import React, { useEffect, useRef } from 'react';
10
+ import React, { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
8
11
 
9
12
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
10
13
  import { jsx, css } from '@emotion/react';
@@ -13,8 +16,12 @@ import { overflowShadow } from '@atlaskit/editor-common/ui';
13
16
  import { fg } from '@atlaskit/platform-feature-flags/fg';
14
17
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
18
  import { RendererCssClassName } from '../../consts';
19
+ import { ProvidersContext } from '../../ui/annotations/context';
20
+ import { useAnnotationHoverDispatch } from '../../ui/annotations/contexts/AnnotationHoverContext';
21
+ import { useAnnotationRangeDispatch } from '../../ui/annotations/contexts/AnnotationRangeContext';
16
22
  import ExtensionRenderer from '../../ui/ExtensionRenderer';
17
23
  import { calcBreakoutWidthCss } from '../utils/breakout';
24
+ import { ExtensionComments } from './extension-comments';
18
25
  var FORGE_EXTENSION_TYPE = 'com.atlassian.ecosystem';
19
26
  /**
20
27
  * Mirrors `FORGE_INLINE_BODIED_PARAM` in `@atlassian/xen-editor-provider`. Duplicated rather than
@@ -69,7 +76,7 @@ var FireExtensionAsInlineAnalytics = function FireExtensionAsInlineAnalytics(_re
69
76
  return null;
70
77
  };
71
78
  export var renderExtension = function renderExtension(content, layout) {
72
- var _node$parameters, _node$parameters2;
79
+ var _node$parameters, _node$parameters2, _options$dataAttribut;
73
80
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
74
81
  var removeOverflow = arguments.length > 3 ? arguments[3] : undefined;
75
82
  var extensionId = arguments.length > 4 ? arguments[4] : undefined;
@@ -157,11 +164,17 @@ export var renderExtension = function renderExtension(content, layout) {
157
164
  },
158
165
  "data-layout": layout,
159
166
  "data-local-id": localId,
167
+ "data-renderer-start-pos": (_options$dataAttribut = options.dataAttributes) === null || _options$dataAttribut === void 0 ? void 0 : _options$dataAttribut['data-renderer-start-pos'],
160
168
  "data-testid": "extension--wrapper",
161
169
  "data-node-type": "extension",
170
+ "data-inline-comments-target": options.isCommentTarget || undefined,
162
171
  "data-top-level": isTopLevel || undefined,
163
172
  "data-forge-inline": isNativeForgeInline || undefined,
164
- "data-migrated-inline": isMigratedInlineBodied || undefined
173
+ "data-migrated-inline": isMigratedInlineBodied || undefined,
174
+ onBlur: options.onBlur,
175
+ onFocus: options.onFocus,
176
+ onMouseEnter: options.onMouseEnter,
177
+ onMouseLeave: options.onMouseLeave
165
178
  }, jsx("div", {
166
179
  tabIndex: options.tabIndex
167
180
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
@@ -175,6 +188,7 @@ export var renderExtension = function renderExtension(content, layout) {
175
188
  }, extensionDiv) : extensionDiv;
176
189
  };
177
190
  var Extension = function Extension(props) {
191
+ var _providers$inlineComm, _props$dataAttributes;
178
192
  var text = props.text,
179
193
  _props$layout = props.layout,
180
194
  layout = _props$layout === void 0 ? 'default' : _props$layout,
@@ -187,6 +201,57 @@ var Extension = function Extension(props) {
187
201
  nodeHeight = props.nodeHeight,
188
202
  localId = props.localId,
189
203
  isInsideOfInlineExtension = props.isInsideOfInlineExtension;
204
+ var providers = useContext(ProvidersContext);
205
+ var _useAnnotationRangeDi = useAnnotationRangeDispatch(),
206
+ setHoverTarget = _useAnnotationRangeDi.setHoverTarget;
207
+ var _useAnnotationHoverDi = useAnnotationHoverDispatch(),
208
+ cancelTimeout = _useAnnotationHoverDi.cancelTimeout,
209
+ initiateTimeout = _useAnnotationHoverDi.initiateTimeout,
210
+ setIsWithinRange = _useAnnotationHoverDi.setIsWithinRange;
211
+ var isBlockNodeSupported = providers === null || providers === void 0 || (_providers$inlineComm = providers.inlineComment) === null || _providers$inlineComm === void 0 ? void 0 : _providers$inlineComm.isBlockNodeSupported;
212
+ var isCommentTarget = useMemo(function () {
213
+ return Boolean(fg('cc_maui_annotations_on_extensions') && props.extensionNode && (isBlockNodeSupported === null || isBlockNodeSupported === void 0 ? void 0 : isBlockNodeSupported(props.extensionNode)) === true);
214
+ }, [props.extensionNode, isBlockNodeSupported]);
215
+ var isFullPageRenderer = props.rendererAppearance === 'full-page' || props.rendererAppearance === 'full-width';
216
+ var onMouseEnter = useCallback(function (event) {
217
+ cancelTimeout();
218
+ if (event.buttons === 0) {
219
+ setHoverTarget === null || setHoverTarget === void 0 || setHoverTarget(event.currentTarget);
220
+ setIsWithinRange(true);
221
+ }
222
+ }, [cancelTimeout, setHoverTarget, setIsWithinRange]);
223
+ var onMouseLeave = useCallback(function () {
224
+ return initiateTimeout();
225
+ }, [initiateTimeout]);
226
+ var onFocus = useCallback(function (event) {
227
+ if (event.currentTarget.contains(event.relatedTarget)) {
228
+ return;
229
+ }
230
+ cancelTimeout();
231
+ setHoverTarget === null || setHoverTarget === void 0 || setHoverTarget(event.currentTarget);
232
+ setIsWithinRange(true);
233
+ }, [cancelTimeout, setHoverTarget, setIsWithinRange]);
234
+ var onBlur = useCallback(function (event) {
235
+ if (!event.currentTarget.contains(event.relatedTarget)) {
236
+ initiateTimeout();
237
+ }
238
+ }, [initiateTimeout]);
239
+ var commentTargetOptions = isCommentTarget && isFullPageRenderer ? {
240
+ isCommentTarget: true,
241
+ onBlur: onBlur,
242
+ onFocus: onFocus,
243
+ onMouseEnter: onMouseEnter,
244
+ onMouseLeave: onMouseLeave
245
+ } : {
246
+ isCommentTarget: isCommentTarget
247
+ };
248
+ var commentProps = {
249
+ enabled: isCommentTarget,
250
+ allowAnnotations: props.allowAnnotations && fg('cc_maui_annotations_on_extensions'),
251
+ allowAnnotationsDraftMode: props.allowAnnotationsDraftMode,
252
+ startPos: (_props$dataAttributes = props.dataAttributes) === null || _props$dataAttributes === void 0 ? void 0 : _props$dataAttributes['data-renderer-start-pos'],
253
+ marks: props.marks
254
+ };
190
255
  return jsx(ExtensionRenderer
191
256
  // Ignored via go/ees005
192
257
  // eslint-disable-next-line react/jsx-props-no-spreading
@@ -199,13 +264,20 @@ var Extension = function Extension(props) {
199
264
  try {
200
265
  // Return the result directly if it's a valid JSX.Element
201
266
  if (result && /*#__PURE__*/React.isValidElement(result)) {
202
- return renderExtension(result, layout, {
267
+ return renderExtension(jsx(ExtensionComments, {
268
+ enabled: commentProps.enabled,
269
+ allowAnnotations: commentProps.allowAnnotations,
270
+ allowAnnotationsDraftMode: commentProps.allowAnnotationsDraftMode,
271
+ startPos: commentProps.startPos,
272
+ marks: commentProps.marks
273
+ }, result), layout, _objectSpread({
274
+ dataAttributes: props.dataAttributes,
203
275
  isTopLevel: path.length < 1,
204
276
  handleRef: handleRef,
205
277
  shadowClassNames: shadowClassNames,
206
278
  tabIndex: props.tabIndex,
207
279
  rendererAppearance: props.rendererAppearance
208
- }, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
280
+ }, commentTargetOptions), undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
209
281
  }
210
282
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
211
283
  } catch (e) {
@@ -217,13 +289,20 @@ var Extension = function Extension(props) {
217
289
  }
218
290
 
219
291
  // Always return default content if anything goes wrong
220
- return renderExtension(text || 'extension', layout, {
292
+ return renderExtension(jsx(ExtensionComments, {
293
+ enabled: commentProps.enabled,
294
+ allowAnnotations: commentProps.allowAnnotations,
295
+ allowAnnotationsDraftMode: commentProps.allowAnnotationsDraftMode,
296
+ startPos: commentProps.startPos,
297
+ marks: commentProps.marks
298
+ }, text || 'extension'), layout, _objectSpread({
299
+ dataAttributes: props.dataAttributes,
221
300
  isTopLevel: path.length < 1,
222
301
  handleRef: handleRef,
223
302
  shadowClassNames: shadowClassNames,
224
303
  tabIndex: props.tabIndex,
225
304
  rendererAppearance: props.rendererAppearance
226
- }, undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
305
+ }, commentTargetOptions), undefined, parameters === null || parameters === void 0 ? void 0 : parameters.extensionId, extensionViewportSizes, nodeHeight, localId, undefined, undefined, isInsideOfInlineExtension);
227
306
  });
228
307
  };
229
308
  var _default_1 = overflowShadow(Extension, {
@@ -216,11 +216,34 @@ export function resolvePos(node, offset) {
216
216
  }
217
217
  return resolvedPos + offset;
218
218
  }
219
+ function getSelectedCommentTargetPosition(range) {
220
+ var startContainer = range.startContainer,
221
+ startOffset = range.startOffset,
222
+ endContainer = range.endContainer,
223
+ endOffset = range.endOffset;
224
+ if (startContainer !== endContainer || endOffset !== startOffset + 1) {
225
+ return false;
226
+ }
227
+ var selectedNode = startContainer.childNodes[startOffset];
228
+ if (!selectedNode || !isElementNode(selectedNode) || selectedNode.dataset.inlineCommentsTarget !== 'true' || !isPositionPointer(selectedNode)) {
229
+ return false;
230
+ }
231
+
232
+ // Subtract 1 from the renderer start position to get the position before the extension node.
233
+ return getStartPos(selectedNode) - 1;
234
+ }
219
235
  export function getPosFromRange(range) {
220
236
  var startContainer = range.startContainer,
221
237
  startOffset = range.startOffset,
222
238
  endContainer = range.endContainer,
223
239
  endOffset = range.endOffset;
240
+ var selectedCommentTargetPosition = fg('cc_maui_annotations_on_extensions') && getSelectedCommentTargetPosition(range);
241
+ if (selectedCommentTargetPosition !== false) {
242
+ return {
243
+ from: selectedCommentTargetPosition,
244
+ to: selectedCommentTargetPosition
245
+ };
246
+ }
224
247
  var possibleMediaOrMediaSingleElement = findParent(startContainer);
225
248
 
226
249
  // Video hover targets return media single, not media, thus, the extra check in condition.
@@ -62,7 +62,7 @@ export var DEGRADED_SEVERITY_THRESHOLD = 3000;
62
62
  var TABLE_INFO_TIMEOUT = 10000;
63
63
  var RENDER_EVENT_SAMPLE_RATE = 0.1;
64
64
  var packageName = "@atlaskit/renderer";
65
- var packageVersion = "148.0.4";
65
+ var packageVersion = "148.1.0";
66
66
  var setAsQueryContainerStyles = css({
67
67
  containerName: 'ak-renderer-wrapper',
68
68
  containerType: 'inline-size'
@@ -2,7 +2,8 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
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
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- import React, { createContext, useCallback, useContext, useMemo, useReducer } from 'react';
5
+ import React, { createContext, useCallback, useContext, useMemo, useReducer, useRef } from 'react';
6
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
6
7
 
7
8
  // oxlint-disable-next-line eslint/no-redeclare
8
9
 
@@ -113,7 +114,9 @@ export var AnnotationRangeDispatchContext = /*#__PURE__*/createContext({
113
114
  });
114
115
  export var AnnotationRangeProviderInner = function AnnotationRangeProviderInner(_ref) {
115
116
  var children = _ref.children,
116
- allowCommentsOnMedia = _ref.allowCommentsOnMedia;
117
+ allowCommentsOnMedia = _ref.allowCommentsOnMedia,
118
+ hasBlockNodeSupport = _ref.hasBlockNodeSupport;
119
+ var extensionCommentsEnabled = !!hasBlockNodeSupport && fg('cc_maui_annotations_on_extensions');
117
120
  var _useReducer = useReducer(reducer, initialState),
118
121
  _useReducer2 = _slicedToArray(_useReducer, 2),
119
122
  _useReducer2$ = _useReducer2[0],
@@ -141,21 +144,34 @@ export var AnnotationRangeProviderInner = function AnnotationRangeProviderInner(
141
144
  range: range
142
145
  });
143
146
  }, []);
147
+ var hoverDraftRangeRef = useRef(hoverDraftRange);
148
+ hoverDraftRangeRef.current = hoverDraftRange;
144
149
  var setHoverTarget = useCallback(function (target) {
145
- // the HoverComponent expects an element deeply nested inside media, these classes work with the current implementation
146
- var mediaNode = target.querySelector('.media-card-inline-player, .media-file-card-view');
147
- if (!mediaNode) {
150
+ var draftRange = hoverDraftRangeRef.current;
151
+ var draftTarget = draftRange === null || draftRange === void 0 ? void 0 : draftRange.startContainer.childNodes[draftRange.startOffset];
152
+ if (extensionCommentsEnabled && draftTarget instanceof HTMLElement && draftTarget.matches('.ak-renderer-extension[data-inline-comments-target="true"]')) {
153
+ // Keep the composer callbacks bound to the chart chosen when its draft opened.
148
154
  return;
149
155
  }
150
- // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- range for media hover highlight
156
+ // The HoverComponent expects an element deeply nested inside media or the eligible
157
+ // block node's wrapper. Each selector is only included when its comment type is
158
+ // supported, so hover targeting never activates on an ineligible block node.
159
+ var selectors = [allowCommentsOnMedia && '.media-card-inline-player, .media-file-card-view', extensionCommentsEnabled && '.ak-renderer-extension[data-inline-comments-target="true"]'].filter(function (selector) {
160
+ return Boolean(selector);
161
+ }).join(', ');
162
+ var hoverableNode = extensionCommentsEnabled && target.matches('.ak-renderer-extension[data-inline-comments-target="true"]') ? target : selectors ? target.querySelector(selectors) : null;
163
+ if (!hoverableNode) {
164
+ return;
165
+ }
166
+ // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- range for media/extension hover highlight
151
167
  var range = document.createRange();
152
- range.setStartBefore(mediaNode);
153
- range.setEndAfter(mediaNode);
168
+ range.setStartBefore(hoverableNode);
169
+ range.setEndAfter(hoverableNode);
154
170
  dispatch({
155
171
  type: 'setHover',
156
172
  range: range
157
173
  });
158
- }, []);
174
+ }, [allowCommentsOnMedia, extensionCommentsEnabled]);
159
175
  var promoteSelectionToDraft = useCallback(function (position) {
160
176
  dispatch({
161
177
  type: 'promoteSelectionToDraft',
@@ -195,13 +211,13 @@ export var AnnotationRangeProviderInner = function AnnotationRangeProviderInner(
195
211
  clearSelectionRange: clearSelectionRange,
196
212
  clearHoverRange: clearHoverRange,
197
213
  setSelectionRange: setSelectionRange,
198
- setHoverTarget: !!allowCommentsOnMedia ? setHoverTarget : undefined,
214
+ setHoverTarget: allowCommentsOnMedia || extensionCommentsEnabled ? setHoverTarget : undefined,
199
215
  promoteSelectionToDraft: promoteSelectionToDraft,
200
216
  promoteHoverToDraft: promoteHoverToDraft,
201
217
  clearSelectionDraft: clearSelectionDraft,
202
218
  clearHoverDraft: clearHoverDraft
203
219
  };
204
- }, [allowCommentsOnMedia, clearSelectionRange, clearHoverRange, setSelectionRange, setHoverTarget, promoteSelectionToDraft, promoteHoverToDraft, clearSelectionDraft, clearHoverDraft]);
220
+ }, [allowCommentsOnMedia, extensionCommentsEnabled, clearSelectionRange, clearHoverRange, setSelectionRange, setHoverTarget, promoteSelectionToDraft, promoteHoverToDraft, clearSelectionDraft, clearHoverDraft]);
205
221
  return /*#__PURE__*/React.createElement(AnnotationRangeStateContext.Provider, {
206
222
  value: stateData
207
223
  }, /*#__PURE__*/React.createElement(AnnotationRangeDispatchContext.Provider, {
@@ -211,6 +227,7 @@ export var AnnotationRangeProviderInner = function AnnotationRangeProviderInner(
211
227
  export var AnnotationRangeProvider = function AnnotationRangeProvider(_ref2) {
212
228
  var children = _ref2.children,
213
229
  allowCommentsOnMedia = _ref2.allowCommentsOnMedia,
230
+ hasBlockNodeSupport = _ref2.hasBlockNodeSupport,
214
231
  isNestedRender = _ref2.isNestedRender;
215
232
  /*
216
233
  * If this is a nested render, we do not provide the context
@@ -218,7 +235,8 @@ export var AnnotationRangeProvider = function AnnotationRangeProvider(_ref2) {
218
235
  * and we need the original context to create annotations on extensions.
219
236
  */
220
237
  return isNestedRender ? /*#__PURE__*/React.createElement(React.Fragment, null, children) : /*#__PURE__*/React.createElement(AnnotationRangeProviderInner, {
221
- allowCommentsOnMedia: allowCommentsOnMedia
238
+ allowCommentsOnMedia: allowCommentsOnMedia,
239
+ hasBlockNodeSupport: hasBlockNodeSupport
222
240
  }, children);
223
241
  };
224
242
  export var useAnnotationRangeState = function useAnnotationRangeState() {
@@ -0,0 +1,6 @@
1
+ ._154iidpf{top:0}
2
+ ._1ltvidpf{left:0}
3
+ ._1xi2idpf{right:0}
4
+ ._94n5idpf{bottom:0}
5
+ ._kqswstnw{position:absolute}
6
+ ._lcxvglyw{pointer-events:none}
@@ -0,0 +1,27 @@
1
+ /* extension.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import "./extension.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React from 'react';
5
+ var styles = {
6
+ anchor: "_kqswstnw _154iidpf _1xi2idpf _94n5idpf _1ltvidpf _lcxvglyw"
7
+ };
8
+
9
+ /** Full-chart anchors for comment navigation, without wrapping or intercepting the iframe. */
10
+ export var ExtensionAnnotation = function ExtensionAnnotation(_ref) {
11
+ var id = _ref.id,
12
+ dataAttributes = _ref.dataAttributes,
13
+ markRef = _ref.markRef;
14
+ return /*#__PURE__*/React.createElement("div", {
15
+ id: id,
16
+ ref: markRef,
17
+ "data-id": dataAttributes['data-id'],
18
+ "data-mark-type": dataAttributes['data-mark-type'],
19
+ "data-mark-annotation-type": dataAttributes['data-mark-annotation-type'],
20
+ "data-mark-annotation-state": dataAttributes['data-mark-annotation-state'],
21
+ "data-block-mark": dataAttributes['data-block-mark'],
22
+ "data-renderer-mark": dataAttributes['data-renderer-mark'],
23
+ "data-has-focus": dataAttributes['data-has-focus'],
24
+ "data-is-hovered": dataAttributes['data-is-hovered'],
25
+ className: ax([styles.anchor])
26
+ });
27
+ };