@atlaskit/editor-common 125.0.0 → 125.1.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.
- package/CHANGELOG.md +22 -0
- package/dist/cjs/element-browser/components/ElementBrowserLoader.js +31 -8
- package/dist/cjs/extensibility/Extension.js +4 -2
- package/dist/cjs/extensibility/ExtensionComponent.js +3 -1
- package/dist/cjs/extensibility/ExtensionNodeWrapper.js +3 -0
- package/dist/cjs/extensibility/GeneratedContentReveal.js +18 -20
- package/dist/cjs/extensibility/extensionNodeView.js +61 -24
- package/dist/cjs/extensions/extension-handlers.js +96 -17
- package/dist/cjs/floating-toolbar/DropdownMenuExtensionItems.js +25 -4
- package/dist/cjs/icons/index.js +33 -10
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/quick-insert/assets/index.js +888 -257
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/ui/Mention/mention-with-profilecard.js +30 -11
- package/dist/es2019/element-browser/components/ElementBrowserLoader.js +16 -2
- package/dist/es2019/extensibility/Extension.js +4 -2
- package/dist/es2019/extensibility/ExtensionComponent.js +3 -1
- package/dist/es2019/extensibility/ExtensionNodeWrapper.js +2 -0
- package/dist/es2019/extensibility/GeneratedContentReveal.js +11 -16
- package/dist/es2019/extensibility/extensionNodeView.js +51 -23
- package/dist/es2019/extensions/extension-handlers.js +70 -15
- package/dist/es2019/floating-toolbar/DropdownMenuExtensionItems.js +16 -2
- package/dist/es2019/icons/index.js +17 -3
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/quick-insert/assets/index.js +386 -66
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/ui/Mention/mention-with-profilecard.js +15 -4
- package/dist/esm/element-browser/components/ElementBrowserLoader.js +28 -6
- package/dist/esm/extensibility/Extension.js +4 -2
- package/dist/esm/extensibility/ExtensionComponent.js +3 -1
- package/dist/esm/extensibility/ExtensionNodeWrapper.js +3 -0
- package/dist/esm/extensibility/GeneratedContentReveal.js +18 -20
- package/dist/esm/extensibility/extensionNodeView.js +56 -23
- package/dist/esm/extensions/extension-handlers.js +97 -17
- package/dist/esm/floating-toolbar/DropdownMenuExtensionItems.js +24 -4
- package/dist/esm/icons/index.js +29 -7
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/quick-insert/assets/index.js +764 -194
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/ui/Mention/mention-with-profilecard.js +25 -8
- package/dist/types/analytics/types/ai-suggestions-events.d.ts +4 -6
- package/dist/types/extensibility/Extension.d.ts +2 -0
- package/dist/types/extensibility/ExtensionComponent.d.ts +2 -0
- package/dist/types/extensibility/ExtensionNodeWrapper.d.ts +3 -1
- package/dist/types/extensibility/GeneratedContentReveal.d.ts +3 -1
- package/dist/types/extensibility/extensionNodeView.d.ts +13 -12
- package/dist/types/icons/index.d.ts +5 -3
- package/dist/types/quick-insert/assets/index.d.ts +34 -32
- package/package.json +5 -4
- package/dist/cjs/extensibility/useNativeEmbedSettled.js +0 -56
- package/dist/es2019/extensibility/useNativeEmbedSettled.js +0 -49
- package/dist/esm/extensibility/useNativeEmbedSettled.js +0 -51
- package/dist/types/extensibility/useNativeEmbedSettled.d.ts +0 -12
|
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
24
24
|
* @jsx jsx
|
|
25
25
|
*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
26
26
|
var packageName = "@atlaskit/editor-common";
|
|
27
|
-
var packageVersion = "
|
|
27
|
+
var packageVersion = "125.0.0";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -8,6 +8,7 @@ exports.default = MentionWithProfileCard;
|
|
|
8
8
|
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
9
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
10
|
var _reactLoadable = _interopRequireDefault(require("react-loadable"));
|
|
11
|
+
var _reactLooselyLazy = require("react-loosely-lazy");
|
|
11
12
|
var _resourcedMention = _interopRequireDefault(require("@atlaskit/mention/resourced-mention"));
|
|
12
13
|
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
13
14
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
@@ -15,24 +16,42 @@ var _anchor = require("@atlaskit/primitives/anchor");
|
|
|
15
16
|
var _profileCardTrigger = _interopRequireDefault(require("@atlaskit/profilecard/profile-card-trigger"));
|
|
16
17
|
var _navigateToTeamsApp2 = require("@atlaskit/teams-app-config/utils/teams-app-navigation/navigate-to-teams-app");
|
|
17
18
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
18
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != (0, _typeof2.default)(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } //
|
|
19
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != (0, _typeof2.default)(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } // oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
20
|
+
// eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- TODO: migrate to @atlaskit/primitives/compiled
|
|
19
21
|
// Lazy-loaded so the agent profile card chunk (and its `@atlaskit/rovo-agent-components`
|
|
20
22
|
// dependency) stays off the critical path — it is only fetched when an agent mention
|
|
21
23
|
// (`userType === 'APP'`) actually renders, never for person mentions.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
var loadAgentProfileCardTrigger = function loadAgentProfileCardTrigger() {
|
|
25
|
+
return Promise.resolve().then(function () {
|
|
26
|
+
return _interopRequireWildcard(require( /* webpackChunkName: "@atlaskit-internal_profilecard/agent-profile-card-trigger" */
|
|
27
|
+
'@atlaskit/profilecard/agent-profile-card-trigger'));
|
|
28
|
+
}).then(function (mod) {
|
|
29
|
+
return mod.AgentProfileCardTrigger;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
var AgentProfileCardTriggerLazy = (0, _reactLooselyLazy.lazy)(function () {
|
|
33
|
+
return Promise.resolve().then(function () {
|
|
34
|
+
return _interopRequireWildcard(require( /* webpackChunkName: "@atlaskit-internal_profilecard/agent-profile-card-trigger" */
|
|
35
|
+
'@atlaskit/profilecard/agent-profile-card-trigger'));
|
|
36
|
+
}).then(function (mod) {
|
|
37
|
+
return mod.AgentProfileCardTrigger;
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
AgentProfileCardTriggerLazy.displayName = 'lazy(AgentProfileCardTrigger)';
|
|
41
|
+
var AgentProfileCardTriggerLoadable = (0, _reactLoadable.default)({
|
|
42
|
+
loader: loadAgentProfileCardTrigger,
|
|
32
43
|
loading: function loading() {
|
|
33
44
|
return null;
|
|
34
45
|
}
|
|
35
46
|
});
|
|
47
|
+
var AgentProfileCardTrigger = function AgentProfileCardTrigger(props) {
|
|
48
|
+
return (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_loosely_lazy_migration') ? /*#__PURE__*/_react.default.createElement(_reactLooselyLazy.LazySuspense, {
|
|
49
|
+
fallback: null
|
|
50
|
+
}, /*#__PURE__*/_react.default.createElement(AgentProfileCardTriggerLazy, props)) :
|
|
51
|
+
/*#__PURE__*/
|
|
52
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
53
|
+
_react.default.createElement(AgentProfileCardTriggerLoadable, props);
|
|
54
|
+
};
|
|
36
55
|
|
|
37
56
|
// Ignored via go/ees005
|
|
38
57
|
// eslint-disable-next-line require-unicode-regexp
|
|
@@ -7,6 +7,11 @@ import React from 'react';
|
|
|
7
7
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
8
8
|
import { css, jsx } from '@emotion/react';
|
|
9
9
|
import Loadable from 'react-loadable';
|
|
10
|
+
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
11
|
+
import { lazy, LazySuspense } from 'react-loosely-lazy';
|
|
12
|
+
|
|
13
|
+
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
14
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
10
15
|
import Spinner from '@atlaskit/spinner/spinner';
|
|
11
16
|
const spinnerContainer = css({
|
|
12
17
|
display: 'flex',
|
|
@@ -15,8 +20,11 @@ const spinnerContainer = css({
|
|
|
15
20
|
height: '100%',
|
|
16
21
|
width: '100%'
|
|
17
22
|
});
|
|
18
|
-
const
|
|
19
|
-
|
|
23
|
+
const loadElementBrowser = () => import( /* webpackChunkName: "@atlaskit-internal_editor-element-browser" */'../ElementBrowser').then(module => module.default);
|
|
24
|
+
const ElementBrowserLazy = lazy(() => import( /* webpackChunkName: "@atlaskit-internal_editor-element-browser" */'../ElementBrowser').then(module => module.default));
|
|
25
|
+
ElementBrowserLazy.displayName = 'lazy(ElementBrowser)';
|
|
26
|
+
const ElementBrowserLoadable = Loadable({
|
|
27
|
+
loader: loadElementBrowser,
|
|
20
28
|
loading: () => jsx("div", {
|
|
21
29
|
css: spinnerContainer
|
|
22
30
|
}, jsx(Spinner, {
|
|
@@ -24,4 +32,10 @@ const ElementBrowserLoader = Loadable({
|
|
|
24
32
|
interactionName: "element-browser-spinner"
|
|
25
33
|
}))
|
|
26
34
|
});
|
|
35
|
+
const ElementBrowserLoader = props => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? jsx(LazySuspense, {
|
|
36
|
+
fallback: null
|
|
37
|
+
}, jsx(ElementBrowserLazy, props)) :
|
|
38
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
39
|
+
jsx(ElementBrowserLoadable, props);
|
|
40
|
+
ElementBrowserLoader.preload = () => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? ElementBrowserLazy.preload() : ElementBrowserLoadable.preload();
|
|
27
41
|
export default ElementBrowserLoader;
|
|
@@ -25,7 +25,8 @@ export class Extension extends Component {
|
|
|
25
25
|
macroInteractionDesignFeatureFlags,
|
|
26
26
|
showLivePagesBodiedMacrosRendererView,
|
|
27
27
|
showUpdatedLivePages1PBodiedExtensionUI,
|
|
28
|
-
rendererExtensionHandlers
|
|
28
|
+
rendererExtensionHandlers,
|
|
29
|
+
onContentReady
|
|
29
30
|
} = this.props;
|
|
30
31
|
|
|
31
32
|
// Extensions are not yet using the new plugin architecture, and the use of the pluginInjectionApi
|
|
@@ -53,7 +54,8 @@ export class Extension extends Component {
|
|
|
53
54
|
showLivePagesBodiedMacrosRendererView: showLivePagesBodiedMacrosRendererView,
|
|
54
55
|
showUpdatedLivePages1PBodiedExtensionUI: showUpdatedLivePages1PBodiedExtensionUI,
|
|
55
56
|
rendererExtensionHandlers: rendererExtensionHandlers,
|
|
56
|
-
isLivePageViewMode: isLivePageViewMode
|
|
57
|
+
isLivePageViewMode: isLivePageViewMode,
|
|
58
|
+
onContentReady: onContentReady
|
|
57
59
|
});
|
|
58
60
|
});
|
|
59
61
|
this.providerFactory = props.providerFactory || new ProviderFactory();
|
|
@@ -181,7 +181,8 @@ class ExtensionComponentInner extends Component {
|
|
|
181
181
|
extensionLoadingHandlers,
|
|
182
182
|
editorView,
|
|
183
183
|
showBodiedExtensionRendererView,
|
|
184
|
-
rendererExtensionHandlers
|
|
184
|
+
rendererExtensionHandlers,
|
|
185
|
+
onContentReady
|
|
185
186
|
} = this.props;
|
|
186
187
|
const {
|
|
187
188
|
extensionType,
|
|
@@ -238,6 +239,7 @@ class ExtensionComponentInner extends Component {
|
|
|
238
239
|
references: this.props.references,
|
|
239
240
|
isSelected: isSelected,
|
|
240
241
|
loadingFallback: loadingFallback,
|
|
242
|
+
onContentReady: onContentReady,
|
|
241
243
|
showUnknownMacroPlaceholder: true
|
|
242
244
|
});
|
|
243
245
|
}
|
|
@@ -67,6 +67,7 @@ export const ExtensionNodeWrapper = ({
|
|
|
67
67
|
nodeType,
|
|
68
68
|
macroInteractionDesignFeatureFlags,
|
|
69
69
|
generatedContentMotion = false,
|
|
70
|
+
contentReady = false,
|
|
70
71
|
intl
|
|
71
72
|
}) => {
|
|
72
73
|
const {
|
|
@@ -76,6 +77,7 @@ export const ExtensionNodeWrapper = ({
|
|
|
76
77
|
// Fixed for the node view's lifetime: switching would remount the subtree and reload the embed.
|
|
77
78
|
if (generatedContentMotion) {
|
|
78
79
|
return jsx(GeneratedContentReveal, {
|
|
80
|
+
contentReady: contentReady,
|
|
79
81
|
intl: intl,
|
|
80
82
|
showMacroInteractionDesignUpdates: showMacroInteractionDesignUpdates
|
|
81
83
|
}, children);
|
|
@@ -3,14 +3,13 @@ import "./GeneratedContentReveal.compiled.css";
|
|
|
3
3
|
import { ax, ix } from "@compiled/react/runtime";
|
|
4
4
|
import React, { useCallback, useEffect, useState } from 'react';
|
|
5
5
|
import { ExtensionSSRReactContextsProvider } from './ExtensionSSRReactContextsProvider';
|
|
6
|
-
import { useNativeEmbedSettled } from './useNativeEmbedSettled';
|
|
7
6
|
|
|
8
7
|
/*
|
|
9
8
|
* Animates a native embed into the document once it has loaded.
|
|
10
9
|
*
|
|
11
10
|
* 1. `collapsed` — clipped to zero height and `inert`. The embed loads behind it, full size but
|
|
12
11
|
* unseen, with its own loading overlay hidden.
|
|
13
|
-
* 2.
|
|
12
|
+
* 2. The extension reports its content ready through `contentReady`.
|
|
14
13
|
* 3. `revealing` — the node animates open to its content height (400ms).
|
|
15
14
|
* 4. The embed fades in (200ms), delayed so it follows the opening instead of overlapping it.
|
|
16
15
|
* 5. `open` — on `animationend`, when the content first becomes visible, `inert` is dropped.
|
|
@@ -55,32 +54,28 @@ const embedContentEnteringStyles = null;
|
|
|
55
54
|
|
|
56
55
|
export const GeneratedContentReveal = ({
|
|
57
56
|
children,
|
|
57
|
+
contentReady,
|
|
58
58
|
intl,
|
|
59
59
|
showMacroInteractionDesignUpdates
|
|
60
60
|
}) => {
|
|
61
|
-
// Held in state so the
|
|
61
|
+
// Held in state so the effect below runs once the span exists.
|
|
62
62
|
const [wrapperElement, setWrapperElement] = useState(null);
|
|
63
|
-
const [
|
|
63
|
+
const [readyTimedOut, setReadyTimedOut] = useState(false);
|
|
64
|
+
const [opened, setOpened] = useState(false);
|
|
64
65
|
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
const startRevealing = useCallback(() => {
|
|
68
|
-
setState(current => current === 'collapsed' ? 'revealing' : current);
|
|
69
|
-
}, []);
|
|
70
|
-
|
|
71
|
-
// Step 2 → 3.
|
|
72
|
-
useNativeEmbedSettled(wrapperElement, startRevealing);
|
|
66
|
+
// Derived, so the two ways a node opens need no ordering between them.
|
|
67
|
+
const state = opened ? 'open' : contentReady || readyTimedOut ? 'revealing' : 'collapsed';
|
|
73
68
|
|
|
74
69
|
// One timer, set on mount, so the deadline never moves.
|
|
75
70
|
useEffect(() => {
|
|
76
|
-
const timer = setTimeout(
|
|
71
|
+
const timer = setTimeout(() => setReadyTimedOut(true), READY_TIMEOUT_MS);
|
|
77
72
|
return () => clearTimeout(timer);
|
|
78
|
-
}, [
|
|
73
|
+
}, []);
|
|
79
74
|
useEffect(() => {
|
|
80
75
|
if (state !== 'revealing') {
|
|
81
76
|
return;
|
|
82
77
|
}
|
|
83
|
-
const timer = setTimeout(() =>
|
|
78
|
+
const timer = setTimeout(() => setOpened(true), REVEAL_TIMEOUT_MS);
|
|
84
79
|
return () => clearTimeout(timer);
|
|
85
80
|
}, [state]);
|
|
86
81
|
|
|
@@ -92,7 +87,7 @@ export const GeneratedContentReveal = ({
|
|
|
92
87
|
const onAnimationEnd = useCallback(event => {
|
|
93
88
|
// The extension's own content animates too, and those events bubble.
|
|
94
89
|
if (event.target === event.currentTarget) {
|
|
95
|
-
|
|
90
|
+
setOpened(true);
|
|
96
91
|
}
|
|
97
92
|
}, []);
|
|
98
93
|
return /*#__PURE__*/React.createElement(ExtensionSSRReactContextsProvider, {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useCallback, useState } from 'react';
|
|
3
3
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
4
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
5
|
import { isSSR } from '../core-utils';
|
|
@@ -264,22 +264,14 @@ export class ExtensionNode extends ReactNodeView {
|
|
|
264
264
|
};
|
|
265
265
|
}
|
|
266
266
|
render(props, forwardRef) {
|
|
267
|
-
var _props$extensionNodeV, _props$extensionNodeV2;
|
|
268
267
|
// While sitting on SSR DOM, skip the React portal — see {@link didReuseSsrDom}.
|
|
269
268
|
if (this.didReuseSsrDom) {
|
|
270
269
|
return null;
|
|
271
270
|
}
|
|
272
|
-
return /*#__PURE__*/React.createElement(
|
|
273
|
-
intl: props.intl,
|
|
274
|
-
nodeType: this.node.type.name,
|
|
275
|
-
macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags
|
|
276
|
-
// Only native embeds animate in; the reveal waits on the embed's own loading state.
|
|
277
|
-
,
|
|
278
|
-
generatedContentMotion: !!((_props$extensionNodeV = props.extensionNodeViewOptions) !== null && _props$extensionNodeV !== void 0 && _props$extensionNodeV.allowAIGeneratedContentMotion) && isNativeEmbedExtension(this.node)
|
|
279
|
-
}, /*#__PURE__*/React.createElement(Extension, {
|
|
271
|
+
return /*#__PURE__*/React.createElement(ExtensionNodeRender, {
|
|
280
272
|
editorView: this.view,
|
|
281
|
-
|
|
282
|
-
|
|
273
|
+
eventDispatcher: this.eventDispatcher,
|
|
274
|
+
forwardRef: forwardRef
|
|
283
275
|
// The getPos arg is always a function when used with nodes
|
|
284
276
|
// the version of the types we use has a union with the type
|
|
285
277
|
// for marks.
|
|
@@ -288,19 +280,55 @@ export class ExtensionNode extends ReactNodeView {
|
|
|
288
280
|
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/57384
|
|
289
281
|
,
|
|
290
282
|
getPos: this.getPos,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
extensionLoadingHandlers: props.extensionLoadingHandlers,
|
|
295
|
-
editorAppearance: (_props$extensionNodeV2 = props.extensionNodeViewOptions) === null || _props$extensionNodeV2 === void 0 ? void 0 : _props$extensionNodeV2.appearance,
|
|
296
|
-
pluginInjectionApi: props.pluginInjectionApi,
|
|
297
|
-
macroInteractionDesignFeatureFlags: props.macroInteractionDesignFeatureFlags,
|
|
298
|
-
showLivePagesBodiedMacrosRendererView: props.showLivePagesBodiedMacrosRendererView,
|
|
299
|
-
showUpdatedLivePages1PBodiedExtensionUI: props.showUpdatedLivePages1PBodiedExtensionUI,
|
|
300
|
-
rendererExtensionHandlers: props.rendererExtensionHandlers
|
|
301
|
-
}));
|
|
283
|
+
node: this.node,
|
|
284
|
+
renderProps: props
|
|
285
|
+
});
|
|
302
286
|
}
|
|
303
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Wraps the extension in its node wrapper. A component rather than part of the node view's `render`,
|
|
290
|
+
* so `contentReady` can be React state: the extension reports its content ready from inside the
|
|
291
|
+
* wrapper, and the wrapper animates the node in once it has.
|
|
292
|
+
*/
|
|
293
|
+
function ExtensionNodeRender({
|
|
294
|
+
editorView,
|
|
295
|
+
eventDispatcher,
|
|
296
|
+
forwardRef,
|
|
297
|
+
getPos,
|
|
298
|
+
node,
|
|
299
|
+
renderProps
|
|
300
|
+
}) {
|
|
301
|
+
var _renderProps$extensio, _renderProps$extensio2;
|
|
302
|
+
const [contentReady, setContentReady] = useState(false);
|
|
303
|
+
const onContentReady = useCallback(() => setContentReady(true), []);
|
|
304
|
+
|
|
305
|
+
// Only native embeds animate in; every other extension type renders as it does without the
|
|
306
|
+
// option, so nothing waits on a signal it does not send.
|
|
307
|
+
const generatedContentMotion = !!((_renderProps$extensio = renderProps.extensionNodeViewOptions) !== null && _renderProps$extensio !== void 0 && _renderProps$extensio.allowAIGeneratedContentMotion) && isNativeEmbedExtension(node);
|
|
308
|
+
return /*#__PURE__*/React.createElement(ExtensionNodeWrapper, {
|
|
309
|
+
intl: renderProps.intl,
|
|
310
|
+
nodeType: node.type.name,
|
|
311
|
+
macroInteractionDesignFeatureFlags: renderProps.macroInteractionDesignFeatureFlags,
|
|
312
|
+
generatedContentMotion: generatedContentMotion,
|
|
313
|
+
contentReady: contentReady
|
|
314
|
+
}, /*#__PURE__*/React.createElement(Extension, {
|
|
315
|
+
editorView: editorView,
|
|
316
|
+
node: node,
|
|
317
|
+
eventDispatcher: eventDispatcher,
|
|
318
|
+
getPos: getPos,
|
|
319
|
+
providerFactory: renderProps.providerFactory,
|
|
320
|
+
handleContentDOMRef: forwardRef,
|
|
321
|
+
extensionHandlers: renderProps.extensionHandlers,
|
|
322
|
+
extensionLoadingHandlers: renderProps.extensionLoadingHandlers,
|
|
323
|
+
editorAppearance: (_renderProps$extensio2 = renderProps.extensionNodeViewOptions) === null || _renderProps$extensio2 === void 0 ? void 0 : _renderProps$extensio2.appearance,
|
|
324
|
+
pluginInjectionApi: renderProps.pluginInjectionApi,
|
|
325
|
+
macroInteractionDesignFeatureFlags: renderProps.macroInteractionDesignFeatureFlags,
|
|
326
|
+
showLivePagesBodiedMacrosRendererView: renderProps.showLivePagesBodiedMacrosRendererView,
|
|
327
|
+
showUpdatedLivePages1PBodiedExtensionUI: renderProps.showUpdatedLivePages1PBodiedExtensionUI,
|
|
328
|
+
rendererExtensionHandlers: renderProps.rendererExtensionHandlers,
|
|
329
|
+
onContentReady: generatedContentMotion ? onContentReady : undefined
|
|
330
|
+
}));
|
|
331
|
+
}
|
|
304
332
|
|
|
305
333
|
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
306
334
|
export default function ExtensionNodeView(portalProviderAPI, eventDispatcher, providerFactory, extensionHandlers, extensionLoadingHandlers, extensionNodeViewOptions, pluginInjectionApi, macroInteractionDesignFeatureFlags, showLivePagesBodiedMacrosRendererView, showUpdatedLivePages1PBodiedExtensionUI, rendererExtensionHandlers, intl) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import { useIntl } from 'react-intl';
|
|
3
5
|
import Loadable from 'react-loadable';
|
|
6
|
+
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
7
|
+
import { lazy, LazySuspense } from 'react-loosely-lazy';
|
|
8
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
4
9
|
import { getExtensionKeyAndNodeKey, resolveImport } from './manifest-helpers';
|
|
5
10
|
import { messages } from './messages';
|
|
6
11
|
import { resolveImportSync } from './resolveImportSync';
|
|
@@ -59,6 +64,38 @@ function isUnknownConfluenceMacroWithBody(extensionNode) {
|
|
|
59
64
|
var _extensionNode$parame, _extensionNode$parame2, _extensionNode$parame3;
|
|
60
65
|
return extensionNode !== null && extensionNode.type === 'extension' && extensionNode.extensionType === 'com.atlassian.confluence.macro.core' && !!((_extensionNode$parame = extensionNode.parameters) !== null && _extensionNode$parame !== void 0 && (_extensionNode$parame2 = _extensionNode$parame.macroParams) !== null && _extensionNode$parame2 !== void 0 && (_extensionNode$parame3 = _extensionNode$parame2.__bodyContent) !== null && _extensionNode$parame3 !== void 0 && _extensionNode$parame3.value);
|
|
61
66
|
}
|
|
67
|
+
// eslint-disable-next-line @repo/internal/react/no-class-components -- error boundaries require a class component
|
|
68
|
+
class ExtensionRendererErrorBoundary extends React.Component {
|
|
69
|
+
constructor(...args) {
|
|
70
|
+
super(...args);
|
|
71
|
+
_defineProperty(this, "state", {});
|
|
72
|
+
}
|
|
73
|
+
static getDerivedStateFromError(error) {
|
|
74
|
+
return {
|
|
75
|
+
error
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
componentDidCatch(error) {
|
|
79
|
+
// eslint-disable-next-line no-console
|
|
80
|
+
console.error('Error rendering extension', error);
|
|
81
|
+
}
|
|
82
|
+
render() {
|
|
83
|
+
return this.state.error ? renderExtensionLoadingError(this.state.error, this.props.fallbackProps) : this.props.children;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const noop = () => {};
|
|
87
|
+
function renderExtensionLoadingError(error, props) {
|
|
88
|
+
// Needed because the old react-loadable (older code-splitting library) error handling behaviour might be relied on by extensions.
|
|
89
|
+
// https://unpkg.com/react-loadable@5.2.2/lib/index.js
|
|
90
|
+
return /*#__PURE__*/React.createElement(ExtensionLoading, _extends({
|
|
91
|
+
isLoading: false,
|
|
92
|
+
pastDelay: true,
|
|
93
|
+
timedOut: false,
|
|
94
|
+
error: error,
|
|
95
|
+
retry: noop
|
|
96
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
97
|
+
}, props));
|
|
98
|
+
}
|
|
62
99
|
function ExtensionLoading(props) {
|
|
63
100
|
const intl = useIntl();
|
|
64
101
|
const extensionNode = props.node;
|
|
@@ -81,27 +118,45 @@ function ExtensionLoading(props) {
|
|
|
81
118
|
|
|
82
119
|
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
83
120
|
export function getNodeRenderer(extensionProvider, extensionType, extensionKey) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
121
|
+
const loadNodeRenderer = () => {
|
|
122
|
+
var _renderSync, _ref;
|
|
123
|
+
const maybePromise = getExtensionModuleNodeMaybePreloaded(extensionProvider, extensionType, extensionKey);
|
|
124
|
+
if (maybePromise instanceof Promise) {
|
|
125
|
+
return maybePromise.then(node => resolveImport(node.render()));
|
|
126
|
+
}
|
|
127
|
+
const preloaded = maybePromise === null || maybePromise === void 0 ? void 0 : (_renderSync = (_ref = maybePromise).renderSync) === null || _renderSync === void 0 ? void 0 : _renderSync.call(_ref);
|
|
128
|
+
// Only product implemented preloading will return sync result
|
|
129
|
+
// However the out-of-box won't handle this. Confluence uses a custom implementation
|
|
130
|
+
return preloaded ?
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
resolveImportSync(preloaded) : resolveImport(maybePromise.render());
|
|
133
|
+
};
|
|
134
|
+
const LazyNodeRenderer = lazy(() => loadNodeRenderer());
|
|
135
|
+
LazyNodeRenderer.displayName = 'lazy(NodeRenderer)';
|
|
136
|
+
// Ignored via go/ees005
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
138
|
+
const LoadableNodeRenderer = Loadable({
|
|
139
|
+
loader: loadNodeRenderer,
|
|
99
140
|
// react-loadable passes all props from <NodeRenderer> to the loading component at runtime,
|
|
100
141
|
// but its TypeScript types only expect LoadingComponentProps. We cast here because
|
|
101
142
|
// ExtensionLoading accepts additional props (node, showUnknownMacroPlaceholder) that
|
|
102
143
|
// react-loadable will pass through but doesn't know about in its type definitions.
|
|
103
144
|
loading: ExtensionLoading
|
|
104
145
|
});
|
|
146
|
+
const NodeRenderer = props => {
|
|
147
|
+
var _props$loadingFallbac;
|
|
148
|
+
if (!isExperimentEnabled('platform_editor_loosely_lazy_migration')) {
|
|
149
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
150
|
+
return /*#__PURE__*/React.createElement(LoadableNodeRenderer, props);
|
|
151
|
+
}
|
|
152
|
+
return /*#__PURE__*/React.createElement(ExtensionRendererErrorBoundary, {
|
|
153
|
+
fallbackProps: props
|
|
154
|
+
}, /*#__PURE__*/React.createElement(LazySuspense, {
|
|
155
|
+
fallback: (_props$loadingFallbac = props.loadingFallback) !== null && _props$loadingFallbac !== void 0 ? _props$loadingFallbac : null
|
|
156
|
+
}, /*#__PURE__*/React.createElement(LazyNodeRenderer, props)));
|
|
157
|
+
};
|
|
158
|
+
NodeRenderer.preload = () => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? LazyNodeRenderer.preload() : LoadableNodeRenderer.preload();
|
|
159
|
+
return NodeRenderer;
|
|
105
160
|
}
|
|
106
161
|
// eslint-disable-next-line @atlaskit/editor/no-re-export
|
|
107
162
|
export { getExtensionManifest } from './getExtensionManifest';
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import Loadable from 'react-loadable';
|
|
3
|
+
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
4
|
+
import { lazy, LazySuspense } from 'react-loosely-lazy';
|
|
5
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
3
6
|
import { getContextualToolbarItemsFromModule } from '../extensions';
|
|
4
7
|
import { nodeToJSON } from '../utils';
|
|
5
8
|
import { DropdownMenuItem } from './DropdownMenuItem';
|
|
@@ -62,10 +65,21 @@ const DropdownMenuExtensionItem = ({
|
|
|
62
65
|
// Use ref to keep icon component stable across renders
|
|
63
66
|
const iconRef = useRef(null);
|
|
64
67
|
if (!iconRef.current && item.icon) {
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
const loadIcon = () => resolveExtensionIcon(item.icon);
|
|
69
|
+
const IconLazy = lazy(() => resolveExtensionIcon(item.icon));
|
|
70
|
+
IconLazy.displayName = 'lazy(ExtensionIcon)';
|
|
71
|
+
const IconLoadable = Loadable({
|
|
72
|
+
loader: loadIcon,
|
|
67
73
|
loading: noop
|
|
68
74
|
});
|
|
75
|
+
const Icon = props => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? /*#__PURE__*/React.createElement(LazySuspense, {
|
|
76
|
+
fallback: null
|
|
77
|
+
}, /*#__PURE__*/React.createElement(IconLazy, props)) :
|
|
78
|
+
/*#__PURE__*/
|
|
79
|
+
// eslint-disable-next-line react/jsx-props-no-spreading -- pass icon props to the legacy component
|
|
80
|
+
React.createElement(IconLoadable, props);
|
|
81
|
+
Icon.preload = () => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? IconLazy.preload() : IconLoadable.preload();
|
|
82
|
+
iconRef.current = Icon;
|
|
69
83
|
}
|
|
70
84
|
const dropdownItem = convertExtensionToDropdownMenuItem({
|
|
71
85
|
item,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// Disable no-re-export rule for entry point files
|
|
2
2
|
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
3
3
|
|
|
4
|
+
import React from 'react';
|
|
4
5
|
import Loadable from 'react-loadable';
|
|
6
|
+
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
7
|
+
import { lazy, LazySuspense } from 'react-loosely-lazy';
|
|
8
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
5
9
|
export { PanelInfoIcon } from './shared/PanelInfoIcon';
|
|
6
10
|
export { PanelWarningIcon } from './shared/PanelWarningIcon';
|
|
7
11
|
export { PanelErrorIcon } from './shared/PanelErrorIcon';
|
|
@@ -10,7 +14,17 @@ export { PanelNoteIcon } from './shared/PanelNoteIcon';
|
|
|
10
14
|
export { BorderIcon } from './shared/BorderIcon';
|
|
11
15
|
export { SteppedRainbowIconDecoration, rainbow, disabledRainbow } from './shared/SteppedRainbowIconDecoration';
|
|
12
16
|
export { DynamicStrokeIconDecoration } from './shared/DynamicStrokeIconDecoration';
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
const loadIconTable = () => import( /* webpackChunkName: "@atlaskit-internal_editor-icon-table" */'../icons/shared/table').then(module => module.default);
|
|
18
|
+
const IconTableLazy = lazy(() => import( /* webpackChunkName: "@atlaskit-internal_editor-icon-table" */'../icons/shared/table').then(module => module.default));
|
|
19
|
+
IconTableLazy.displayName = 'lazy(IconTable)';
|
|
20
|
+
const IconTableLoadable = Loadable({
|
|
21
|
+
loader: loadIconTable,
|
|
15
22
|
loading: () => null
|
|
16
|
-
});
|
|
23
|
+
});
|
|
24
|
+
export const IconTable = props => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? /*#__PURE__*/React.createElement(LazySuspense, {
|
|
25
|
+
fallback: null
|
|
26
|
+
}, /*#__PURE__*/React.createElement(IconTableLazy, props)) :
|
|
27
|
+
/*#__PURE__*/
|
|
28
|
+
// eslint-disable-next-line react/jsx-props-no-spreading -- pass icon props to the legacy component
|
|
29
|
+
React.createElement(IconTableLoadable, props);
|
|
30
|
+
IconTable.preload = () => isExperimentEnabled('platform_editor_loosely_lazy_migration') ? IconTableLazy.preload() : IconTableLoadable.preload();
|
|
@@ -13,7 +13,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
13
13
|
const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
14
14
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
15
15
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
16
|
-
const packageVersion = "
|
|
16
|
+
const packageVersion = "125.0.0";
|
|
17
17
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
18
18
|
// Remove URL as it has UGC
|
|
19
19
|
// Ignored via go/ees007
|