@atlaskit/editor-common 114.16.0 → 114.17.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 +24 -0
- package/dist/cjs/extensibility/extensionNodeView.js +91 -22
- package/dist/cjs/messages/media-insert.js +1 -1
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/ui/Expand/index.js +5 -0
- package/dist/es2019/extensibility/extensionNodeView.js +88 -22
- package/dist/es2019/messages/media-insert.js +1 -1
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/ui/Expand/index.js +5 -0
- package/dist/esm/extensibility/extensionNodeView.js +91 -22
- package/dist/esm/messages/media-insert.js +1 -1
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/ui/Expand/index.js +5 -0
- package/dist/types/extensibility/extensionNodeView.d.ts +6 -13
- package/dist/types/ui/Expand/index.d.ts +13 -8
- package/dist/types-ts4.5/extensibility/extensionNodeView.d.ts +6 -13
- package/dist/types-ts4.5/ui/Expand/index.d.ts +13 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 114.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`9c750ab0192db`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9c750ab0192db) -
|
|
8
|
+
Add role=group and aria-label to expand content div so screen readers announce the body of an
|
|
9
|
+
expand node
|
|
10
|
+
- [`09301dc1b0c55`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/09301dc1b0c55) -
|
|
11
|
+
[ux] Switches the order of the image generation tab in the media insert picker to the first
|
|
12
|
+
position and renames the tab to Create. All changes behind an experiment.
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [`42fa4f485424b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/42fa4f485424b) -
|
|
17
|
+
[ux] Fix Table of Contents extension becoming invisible after drag-and-drop or layout resize when
|
|
18
|
+
the platform_editor_hydration_skip_react_portal experiment is enabled (EDITOR-6613). The SSR
|
|
19
|
+
DOM-reuse optimization is now restricted to the very first ExtensionNode init for each
|
|
20
|
+
(extensionKey, localId) identity within an EditorView. Subsequent ExtensionNodes for the same
|
|
21
|
+
identity (e.g. those created when ProseMirror constructs the new node view before destroying the
|
|
22
|
+
old one during drag-and-drop or layout resize) take the normal React render path instead of
|
|
23
|
+
mistakenly reusing the previous instance's still-mounted React-rendered domRef as if it were SSR
|
|
24
|
+
output. Per-identity scoping preserves the optimization for pages with multiple TOC extensions.
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
|
|
3
27
|
## 114.16.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -23,6 +23,66 @@ var _ExtensionNodeWrapper = require("./ExtensionNodeWrapper");
|
|
|
23
23
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
24
24
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
25
25
|
function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
|
|
26
|
+
/**
|
|
27
|
+
* Allowlists of extension keys + layout
|
|
28
|
+
* Currently, only toc with default layout allows to skip React render.
|
|
29
|
+
* Extensions NOT in this list always follow the normal React render path.
|
|
30
|
+
*/
|
|
31
|
+
var ssrHydrationExtensionAllowlist = ['toc'];
|
|
32
|
+
var ssrHydrationLayoutAllowlist = ['default'];
|
|
33
|
+
var isSSRHydrationEligible = function isSSRHydrationEligible(node) {
|
|
34
|
+
var _node$attrs;
|
|
35
|
+
if (node.type.name !== 'extension') {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
var _ref = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {},
|
|
39
|
+
extensionKey = _ref.extensionKey,
|
|
40
|
+
layout = _ref.layout;
|
|
41
|
+
if (!ssrHydrationExtensionAllowlist.includes(extensionKey)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
// Treat a missing layout attr as `default` (the schema default).
|
|
45
|
+
var effectiveLayout = layout !== null && layout !== void 0 ? layout : 'default';
|
|
46
|
+
return ssrHydrationLayoutAllowlist.includes(effectiveLayout);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Per-(EditorView, extensionKey + localId) record of which extension identities
|
|
51
|
+
* have already had their initial-hydration init pass. SSR DOM reuse is only valid
|
|
52
|
+
* the very first time an ExtensionNode init runs for a given identity in a given
|
|
53
|
+
* editor — that is the only moment a real SSR-rendered element for that identity
|
|
54
|
+
* can exist in the editor DOM.
|
|
55
|
+
*
|
|
56
|
+
* After the first init, any element matching the SSR selector is the previous
|
|
57
|
+
* node view's React-rendered domRef that ProseMirror has not yet detached (e.g.
|
|
58
|
+
* during DnD / layout resize, where ProseMirror constructs the new node view
|
|
59
|
+
* BEFORE destroying the old one). Reusing it as if it were SSR DOM causes the
|
|
60
|
+
* new node view to skip React rendering and leaves the extension invisible
|
|
61
|
+
* (EDITOR-6613).
|
|
62
|
+
*/
|
|
63
|
+
var consumedHydrationIdentitiesByEditor = new WeakMap();
|
|
64
|
+
var _getHydrationIdentityKey = function getHydrationIdentityKey(extensionKey, localId) {
|
|
65
|
+
if (typeof extensionKey !== 'string' || typeof localId !== 'string') {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (extensionKey === '' || localId === '') {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return "".concat(extensionKey, "::").concat(localId);
|
|
72
|
+
};
|
|
73
|
+
var hasHydrationIdentityBeenConsumed = function hasHydrationIdentityBeenConsumed(view, identityKey) {
|
|
74
|
+
var consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
75
|
+
return consumed ? consumed.has(identityKey) : false;
|
|
76
|
+
};
|
|
77
|
+
var markHydrationIdentityAsConsumed = function markHydrationIdentityAsConsumed(view, identityKey) {
|
|
78
|
+
var consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
79
|
+
if (!consumed) {
|
|
80
|
+
consumed = new Set();
|
|
81
|
+
consumedHydrationIdentitiesByEditor.set(view, consumed);
|
|
82
|
+
}
|
|
83
|
+
consumed.add(identityKey);
|
|
84
|
+
};
|
|
85
|
+
|
|
26
86
|
// getInlineNodeViewProducer is a new api to use instead of ReactNodeView
|
|
27
87
|
// when creating inline node views, however, it is difficult to test the impact
|
|
28
88
|
// on selections when migrating inlineExtension to use the new api.
|
|
@@ -36,16 +96,8 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
|
|
|
36
96
|
args[_key] = arguments[_key];
|
|
37
97
|
}
|
|
38
98
|
_this = _callSuper(this, ExtensionNode, [].concat(args));
|
|
39
|
-
/**
|
|
40
|
-
* Track whether we found and are reusing SSR'd DOM.
|
|
41
|
-
* When true, we skip React Portal rendering on first init to preserve SSR content.
|
|
42
|
-
*/
|
|
99
|
+
/** True between SSR DOM adoption in `createDomRef` and the SSR→React handoff in `update`. */
|
|
43
100
|
(0, _defineProperty2.default)(_this, "didReuseSsrDom", false);
|
|
44
|
-
/**
|
|
45
|
-
* Track whether this is the first init call.
|
|
46
|
-
* SSR content preservation only happens on the very first init.
|
|
47
|
-
*/
|
|
48
|
-
(0, _defineProperty2.default)(_this, "isFirstInit", true);
|
|
49
101
|
return _this;
|
|
50
102
|
}
|
|
51
103
|
(0, _inherits2.default)(ExtensionNode, _ReactNodeView);
|
|
@@ -59,14 +111,32 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
|
|
|
59
111
|
return this.node.type.isAtom || mutation.type !== 'selection' && mutation.attributeName !== 'data-layout';
|
|
60
112
|
}
|
|
61
113
|
|
|
114
|
+
/** See {@link consumedHydrationIdentitiesByEditor}. Null when attrs are missing → SSR reuse skipped. */
|
|
115
|
+
}, {
|
|
116
|
+
key: "getHydrationIdentityKey",
|
|
117
|
+
value: function getHydrationIdentityKey() {
|
|
118
|
+
var _this$node$attrs, _this$node$attrs2;
|
|
119
|
+
return _getHydrationIdentityKey((_this$node$attrs = this.node.attrs) === null || _this$node$attrs === void 0 ? void 0 : _this$node$attrs.extensionKey, (_this$node$attrs2 = this.node.attrs) === null || _this$node$attrs2 === void 0 ? void 0 : _this$node$attrs2.localId);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** True only for the first ExtensionNode of this identity in this editor. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
123
|
+
}, {
|
|
124
|
+
key: "isInInitialHydrationWindow",
|
|
125
|
+
value: function isInInitialHydrationWindow() {
|
|
126
|
+
var identityKey = this.getHydrationIdentityKey();
|
|
127
|
+
if (identityKey === null) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
return !hasHydrationIdentityBeenConsumed(this.view, identityKey);
|
|
131
|
+
}
|
|
132
|
+
|
|
62
133
|
// Reserve height by setting a minimum height for the extension node view element
|
|
63
134
|
}, {
|
|
64
135
|
key: "createDomRef",
|
|
65
136
|
value: function createDomRef() {
|
|
66
137
|
if (!(0, _platformFeatureFlags.fg)('confluence_connect_macro_preset_height')) {
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
if (!(0, _coreUtils.isSSR)() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && (0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
138
|
+
// SSR DOM reuse — see {@link consumedHydrationIdentitiesByEditor}.
|
|
139
|
+
if (!(0, _coreUtils.isSSR)() && isSSRHydrationEligible(this.node) && this.isInInitialHydrationWindow() && (0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
70
140
|
var ssrElement = this.findSSRElement();
|
|
71
141
|
if (ssrElement) {
|
|
72
142
|
this.didReuseSsrDom = true;
|
|
@@ -121,22 +191,22 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
|
|
|
121
191
|
return null;
|
|
122
192
|
}
|
|
123
193
|
|
|
124
|
-
/**
|
|
125
|
-
* Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
|
|
126
|
-
* This preserves the SSR content without React unnecessarily re-rendering it.
|
|
127
|
-
*/
|
|
194
|
+
/** Skip React Portal render on first init when reusing SSR DOM. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
128
195
|
}, {
|
|
129
196
|
key: "init",
|
|
130
197
|
value: function init() {
|
|
131
198
|
if (!(0, _expValEquals.expValEquals)('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
132
199
|
_superPropGet(ExtensionNode, "init", this, 3)([]);
|
|
133
200
|
} else {
|
|
134
|
-
|
|
201
|
+
var isEligibleForSsrReuse = !(0, _coreUtils.isSSR)() && isSSRHydrationEligible(this.node);
|
|
202
|
+
if (isEligibleForSsrReuse && this.isInInitialHydrationWindow()) {
|
|
135
203
|
var ssrElement = this.findSSRElement();
|
|
136
204
|
var shouldSkipInitRender = ssrElement !== null;
|
|
137
205
|
_superPropGet(ExtensionNode, "init", this, 3)([shouldSkipInitRender]);
|
|
138
|
-
|
|
139
|
-
|
|
206
|
+
var identityKey = this.getHydrationIdentityKey();
|
|
207
|
+
if (identityKey !== null) {
|
|
208
|
+
// Close the hydration window — see {@link consumedHydrationIdentitiesByEditor}.
|
|
209
|
+
markHydrationIdentityAsConsumed(this.view, identityKey);
|
|
140
210
|
}
|
|
141
211
|
} else {
|
|
142
212
|
_superPropGet(ExtensionNode, "init", this, 3)([]);
|
|
@@ -218,9 +288,8 @@ var ExtensionNode = exports.ExtensionNode = /*#__PURE__*/function (_ReactNodeVie
|
|
|
218
288
|
key: "render",
|
|
219
289
|
value: function render(props, forwardRef) {
|
|
220
290
|
var _props$extensionNodeV;
|
|
221
|
-
//
|
|
222
|
-
|
|
223
|
-
if (this.didReuseSsrDom && this.isFirstInit) {
|
|
291
|
+
// While sitting on SSR DOM, skip the React portal — see {@link didReuseSsrDom}.
|
|
292
|
+
if (this.didReuseSsrDom) {
|
|
224
293
|
return null;
|
|
225
294
|
}
|
|
226
295
|
return /*#__PURE__*/_react.default.createElement(_ExtensionNodeWrapper.ExtensionNodeWrapper, {
|
|
@@ -68,7 +68,7 @@ var mediaInsertMessages = exports.mediaInsertMessages = (0, _reactIntl.defineMes
|
|
|
68
68
|
},
|
|
69
69
|
generateTabTitle: {
|
|
70
70
|
id: 'fabric.editor.media.insert.generateTabTitle',
|
|
71
|
-
defaultMessage: '
|
|
71
|
+
defaultMessage: 'Create',
|
|
72
72
|
description: 'Title of the navigation tab that allows users to generate an image through AI'
|
|
73
73
|
},
|
|
74
74
|
mediaPickerPopupAriaLabel: {
|
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
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" != _typeof(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); }
|
|
20
20
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
21
21
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
22
|
-
var packageVersion = "114.
|
|
22
|
+
var packageVersion = "114.16.0";
|
|
23
23
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
24
24
|
// Remove URL as it has UGC
|
|
25
25
|
// Ignored via go/ees007
|
|
@@ -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 = "114.
|
|
27
|
+
var packageVersion = "114.16.0";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -50,6 +50,11 @@ var messages = exports.messages = (0, _reactIntl.defineMessages)({
|
|
|
50
50
|
id: 'fabric.editor.expandAriaLabel',
|
|
51
51
|
defaultMessage: 'Give this expand a title',
|
|
52
52
|
description: 'aria label for an expand node title input field'
|
|
53
|
+
},
|
|
54
|
+
expandBodyAriaLabel: {
|
|
55
|
+
id: 'fabric.editor.expandBodyAriaLabel',
|
|
56
|
+
defaultMessage: 'Expand body content',
|
|
57
|
+
description: 'Aria label for the body content of an expand node'
|
|
53
58
|
}
|
|
54
59
|
});
|
|
55
60
|
var ExpandIconWrapper = exports.ExpandIconWrapper = function ExpandIconWrapper(_ref) {
|
|
@@ -6,6 +6,67 @@ import { isSSR } from '../core-utils';
|
|
|
6
6
|
import ReactNodeView from '../react-node-view';
|
|
7
7
|
import { Extension } from './Extension';
|
|
8
8
|
import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
|
|
9
|
+
/**
|
|
10
|
+
* Allowlists of extension keys + layout
|
|
11
|
+
* Currently, only toc with default layout allows to skip React render.
|
|
12
|
+
* Extensions NOT in this list always follow the normal React render path.
|
|
13
|
+
*/
|
|
14
|
+
const ssrHydrationExtensionAllowlist = ['toc'];
|
|
15
|
+
const ssrHydrationLayoutAllowlist = ['default'];
|
|
16
|
+
const isSSRHydrationEligible = node => {
|
|
17
|
+
var _node$attrs;
|
|
18
|
+
if (node.type.name !== 'extension') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const {
|
|
22
|
+
extensionKey,
|
|
23
|
+
layout
|
|
24
|
+
} = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
25
|
+
if (!ssrHydrationExtensionAllowlist.includes(extensionKey)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
// Treat a missing layout attr as `default` (the schema default).
|
|
29
|
+
const effectiveLayout = layout !== null && layout !== void 0 ? layout : 'default';
|
|
30
|
+
return ssrHydrationLayoutAllowlist.includes(effectiveLayout);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Per-(EditorView, extensionKey + localId) record of which extension identities
|
|
35
|
+
* have already had their initial-hydration init pass. SSR DOM reuse is only valid
|
|
36
|
+
* the very first time an ExtensionNode init runs for a given identity in a given
|
|
37
|
+
* editor — that is the only moment a real SSR-rendered element for that identity
|
|
38
|
+
* can exist in the editor DOM.
|
|
39
|
+
*
|
|
40
|
+
* After the first init, any element matching the SSR selector is the previous
|
|
41
|
+
* node view's React-rendered domRef that ProseMirror has not yet detached (e.g.
|
|
42
|
+
* during DnD / layout resize, where ProseMirror constructs the new node view
|
|
43
|
+
* BEFORE destroying the old one). Reusing it as if it were SSR DOM causes the
|
|
44
|
+
* new node view to skip React rendering and leaves the extension invisible
|
|
45
|
+
* (EDITOR-6613).
|
|
46
|
+
*/
|
|
47
|
+
const consumedHydrationIdentitiesByEditor = new WeakMap();
|
|
48
|
+
const getHydrationIdentityKey = (extensionKey, localId) => {
|
|
49
|
+
if (typeof extensionKey !== 'string' || typeof localId !== 'string') {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
if (extensionKey === '' || localId === '') {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return `${extensionKey}::${localId}`;
|
|
56
|
+
};
|
|
57
|
+
const hasHydrationIdentityBeenConsumed = (view, identityKey) => {
|
|
58
|
+
const consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
59
|
+
return consumed ? consumed.has(identityKey) : false;
|
|
60
|
+
};
|
|
61
|
+
const markHydrationIdentityAsConsumed = (view, identityKey) => {
|
|
62
|
+
let consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
63
|
+
if (!consumed) {
|
|
64
|
+
consumed = new Set();
|
|
65
|
+
consumedHydrationIdentitiesByEditor.set(view, consumed);
|
|
66
|
+
}
|
|
67
|
+
consumed.add(identityKey);
|
|
68
|
+
};
|
|
69
|
+
|
|
9
70
|
// getInlineNodeViewProducer is a new api to use instead of ReactNodeView
|
|
10
71
|
// when creating inline node views, however, it is difficult to test the impact
|
|
11
72
|
// on selections when migrating inlineExtension to use the new api.
|
|
@@ -14,16 +75,8 @@ import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
|
|
|
14
75
|
export class ExtensionNode extends ReactNodeView {
|
|
15
76
|
constructor(...args) {
|
|
16
77
|
super(...args);
|
|
17
|
-
/**
|
|
18
|
-
* Track whether we found and are reusing SSR'd DOM.
|
|
19
|
-
* When true, we skip React Portal rendering on first init to preserve SSR content.
|
|
20
|
-
*/
|
|
78
|
+
/** True between SSR DOM adoption in `createDomRef` and the SSR→React handoff in `update`. */
|
|
21
79
|
_defineProperty(this, "didReuseSsrDom", false);
|
|
22
|
-
/**
|
|
23
|
-
* Track whether this is the first init call.
|
|
24
|
-
* SSR content preservation only happens on the very first init.
|
|
25
|
-
*/
|
|
26
|
-
_defineProperty(this, "isFirstInit", true);
|
|
27
80
|
}
|
|
28
81
|
ignoreMutation(mutation) {
|
|
29
82
|
// Extensions can perform async operations that will change the DOM.
|
|
@@ -33,12 +86,26 @@ export class ExtensionNode extends ReactNodeView {
|
|
|
33
86
|
return this.node.type.isAtom || mutation.type !== 'selection' && mutation.attributeName !== 'data-layout';
|
|
34
87
|
}
|
|
35
88
|
|
|
89
|
+
/** See {@link consumedHydrationIdentitiesByEditor}. Null when attrs are missing → SSR reuse skipped. */
|
|
90
|
+
getHydrationIdentityKey() {
|
|
91
|
+
var _this$node$attrs, _this$node$attrs2;
|
|
92
|
+
return getHydrationIdentityKey((_this$node$attrs = this.node.attrs) === null || _this$node$attrs === void 0 ? void 0 : _this$node$attrs.extensionKey, (_this$node$attrs2 = this.node.attrs) === null || _this$node$attrs2 === void 0 ? void 0 : _this$node$attrs2.localId);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** True only for the first ExtensionNode of this identity in this editor. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
96
|
+
isInInitialHydrationWindow() {
|
|
97
|
+
const identityKey = this.getHydrationIdentityKey();
|
|
98
|
+
if (identityKey === null) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return !hasHydrationIdentityBeenConsumed(this.view, identityKey);
|
|
102
|
+
}
|
|
103
|
+
|
|
36
104
|
// Reserve height by setting a minimum height for the extension node view element
|
|
37
105
|
createDomRef() {
|
|
38
106
|
if (!fg('confluence_connect_macro_preset_height')) {
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
if (!isSSR() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
107
|
+
// SSR DOM reuse — see {@link consumedHydrationIdentitiesByEditor}.
|
|
108
|
+
if (!isSSR() && isSSRHydrationEligible(this.node) && this.isInInitialHydrationWindow() && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
42
109
|
const ssrElement = this.findSSRElement();
|
|
43
110
|
if (ssrElement) {
|
|
44
111
|
this.didReuseSsrDom = true;
|
|
@@ -91,20 +158,20 @@ export class ExtensionNode extends ReactNodeView {
|
|
|
91
158
|
return null;
|
|
92
159
|
}
|
|
93
160
|
|
|
94
|
-
/**
|
|
95
|
-
* Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
|
|
96
|
-
* This preserves the SSR content without React unnecessarily re-rendering it.
|
|
97
|
-
*/
|
|
161
|
+
/** Skip React Portal render on first init when reusing SSR DOM. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
98
162
|
init() {
|
|
99
163
|
if (!expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
100
164
|
super.init();
|
|
101
165
|
} else {
|
|
102
|
-
|
|
166
|
+
const isEligibleForSsrReuse = !isSSR() && isSSRHydrationEligible(this.node);
|
|
167
|
+
if (isEligibleForSsrReuse && this.isInInitialHydrationWindow()) {
|
|
103
168
|
const ssrElement = this.findSSRElement();
|
|
104
169
|
const shouldSkipInitRender = ssrElement !== null;
|
|
105
170
|
super.init(shouldSkipInitRender);
|
|
106
|
-
|
|
107
|
-
|
|
171
|
+
const identityKey = this.getHydrationIdentityKey();
|
|
172
|
+
if (identityKey !== null) {
|
|
173
|
+
// Close the hydration window — see {@link consumedHydrationIdentitiesByEditor}.
|
|
174
|
+
markHydrationIdentityAsConsumed(this.view, identityKey);
|
|
108
175
|
}
|
|
109
176
|
} else {
|
|
110
177
|
super.init();
|
|
@@ -175,9 +242,8 @@ export class ExtensionNode extends ReactNodeView {
|
|
|
175
242
|
}
|
|
176
243
|
render(props, forwardRef) {
|
|
177
244
|
var _props$extensionNodeV;
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
if (this.didReuseSsrDom && this.isFirstInit) {
|
|
245
|
+
// While sitting on SSR DOM, skip the React portal — see {@link didReuseSsrDom}.
|
|
246
|
+
if (this.didReuseSsrDom) {
|
|
181
247
|
return null;
|
|
182
248
|
}
|
|
183
249
|
return /*#__PURE__*/React.createElement(ExtensionNodeWrapper, {
|
|
@@ -62,7 +62,7 @@ export const mediaInsertMessages = defineMessages({
|
|
|
62
62
|
},
|
|
63
63
|
generateTabTitle: {
|
|
64
64
|
id: 'fabric.editor.media.insert.generateTabTitle',
|
|
65
|
-
defaultMessage: '
|
|
65
|
+
defaultMessage: 'Create',
|
|
66
66
|
description: 'Title of the navigation tab that allows users to generate an image through AI'
|
|
67
67
|
},
|
|
68
68
|
mediaPickerPopupAriaLabel: {
|
|
@@ -4,7 +4,7 @@ import { isFedRamp } from './environment';
|
|
|
4
4
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
5
5
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
6
6
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
7
|
-
const packageVersion = "114.
|
|
7
|
+
const packageVersion = "114.16.0";
|
|
8
8
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
9
9
|
// Remove URL as it has UGC
|
|
10
10
|
// Ignored via go/ees007
|
|
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
14
14
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
15
|
import Layer from '../Layer';
|
|
16
16
|
const packageName = "@atlaskit/editor-common";
|
|
17
|
-
const packageVersion = "114.
|
|
17
|
+
const packageVersion = "114.16.0";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -41,6 +41,11 @@ export const messages = defineMessages({
|
|
|
41
41
|
id: 'fabric.editor.expandAriaLabel',
|
|
42
42
|
defaultMessage: 'Give this expand a title',
|
|
43
43
|
description: 'aria label for an expand node title input field'
|
|
44
|
+
},
|
|
45
|
+
expandBodyAriaLabel: {
|
|
46
|
+
id: 'fabric.editor.expandBodyAriaLabel',
|
|
47
|
+
defaultMessage: 'Expand body content',
|
|
48
|
+
description: 'Aria label for the body content of an expand node'
|
|
44
49
|
}
|
|
45
50
|
});
|
|
46
51
|
export const ExpandIconWrapper = ({
|
|
@@ -15,6 +15,66 @@ import { isSSR } from '../core-utils';
|
|
|
15
15
|
import ReactNodeView from '../react-node-view';
|
|
16
16
|
import { Extension } from './Extension';
|
|
17
17
|
import { ExtensionNodeWrapper } from './ExtensionNodeWrapper';
|
|
18
|
+
/**
|
|
19
|
+
* Allowlists of extension keys + layout
|
|
20
|
+
* Currently, only toc with default layout allows to skip React render.
|
|
21
|
+
* Extensions NOT in this list always follow the normal React render path.
|
|
22
|
+
*/
|
|
23
|
+
var ssrHydrationExtensionAllowlist = ['toc'];
|
|
24
|
+
var ssrHydrationLayoutAllowlist = ['default'];
|
|
25
|
+
var isSSRHydrationEligible = function isSSRHydrationEligible(node) {
|
|
26
|
+
var _node$attrs;
|
|
27
|
+
if (node.type.name !== 'extension') {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
var _ref = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {},
|
|
31
|
+
extensionKey = _ref.extensionKey,
|
|
32
|
+
layout = _ref.layout;
|
|
33
|
+
if (!ssrHydrationExtensionAllowlist.includes(extensionKey)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// Treat a missing layout attr as `default` (the schema default).
|
|
37
|
+
var effectiveLayout = layout !== null && layout !== void 0 ? layout : 'default';
|
|
38
|
+
return ssrHydrationLayoutAllowlist.includes(effectiveLayout);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Per-(EditorView, extensionKey + localId) record of which extension identities
|
|
43
|
+
* have already had their initial-hydration init pass. SSR DOM reuse is only valid
|
|
44
|
+
* the very first time an ExtensionNode init runs for a given identity in a given
|
|
45
|
+
* editor — that is the only moment a real SSR-rendered element for that identity
|
|
46
|
+
* can exist in the editor DOM.
|
|
47
|
+
*
|
|
48
|
+
* After the first init, any element matching the SSR selector is the previous
|
|
49
|
+
* node view's React-rendered domRef that ProseMirror has not yet detached (e.g.
|
|
50
|
+
* during DnD / layout resize, where ProseMirror constructs the new node view
|
|
51
|
+
* BEFORE destroying the old one). Reusing it as if it were SSR DOM causes the
|
|
52
|
+
* new node view to skip React rendering and leaves the extension invisible
|
|
53
|
+
* (EDITOR-6613).
|
|
54
|
+
*/
|
|
55
|
+
var consumedHydrationIdentitiesByEditor = new WeakMap();
|
|
56
|
+
var _getHydrationIdentityKey = function getHydrationIdentityKey(extensionKey, localId) {
|
|
57
|
+
if (typeof extensionKey !== 'string' || typeof localId !== 'string') {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (extensionKey === '' || localId === '') {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
return "".concat(extensionKey, "::").concat(localId);
|
|
64
|
+
};
|
|
65
|
+
var hasHydrationIdentityBeenConsumed = function hasHydrationIdentityBeenConsumed(view, identityKey) {
|
|
66
|
+
var consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
67
|
+
return consumed ? consumed.has(identityKey) : false;
|
|
68
|
+
};
|
|
69
|
+
var markHydrationIdentityAsConsumed = function markHydrationIdentityAsConsumed(view, identityKey) {
|
|
70
|
+
var consumed = consumedHydrationIdentitiesByEditor.get(view);
|
|
71
|
+
if (!consumed) {
|
|
72
|
+
consumed = new Set();
|
|
73
|
+
consumedHydrationIdentitiesByEditor.set(view, consumed);
|
|
74
|
+
}
|
|
75
|
+
consumed.add(identityKey);
|
|
76
|
+
};
|
|
77
|
+
|
|
18
78
|
// getInlineNodeViewProducer is a new api to use instead of ReactNodeView
|
|
19
79
|
// when creating inline node views, however, it is difficult to test the impact
|
|
20
80
|
// on selections when migrating inlineExtension to use the new api.
|
|
@@ -28,16 +88,8 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
28
88
|
args[_key] = arguments[_key];
|
|
29
89
|
}
|
|
30
90
|
_this = _callSuper(this, ExtensionNode, [].concat(args));
|
|
31
|
-
/**
|
|
32
|
-
* Track whether we found and are reusing SSR'd DOM.
|
|
33
|
-
* When true, we skip React Portal rendering on first init to preserve SSR content.
|
|
34
|
-
*/
|
|
91
|
+
/** True between SSR DOM adoption in `createDomRef` and the SSR→React handoff in `update`. */
|
|
35
92
|
_defineProperty(_this, "didReuseSsrDom", false);
|
|
36
|
-
/**
|
|
37
|
-
* Track whether this is the first init call.
|
|
38
|
-
* SSR content preservation only happens on the very first init.
|
|
39
|
-
*/
|
|
40
|
-
_defineProperty(_this, "isFirstInit", true);
|
|
41
93
|
return _this;
|
|
42
94
|
}
|
|
43
95
|
_inherits(ExtensionNode, _ReactNodeView);
|
|
@@ -51,14 +103,32 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
51
103
|
return this.node.type.isAtom || mutation.type !== 'selection' && mutation.attributeName !== 'data-layout';
|
|
52
104
|
}
|
|
53
105
|
|
|
106
|
+
/** See {@link consumedHydrationIdentitiesByEditor}. Null when attrs are missing → SSR reuse skipped. */
|
|
107
|
+
}, {
|
|
108
|
+
key: "getHydrationIdentityKey",
|
|
109
|
+
value: function getHydrationIdentityKey() {
|
|
110
|
+
var _this$node$attrs, _this$node$attrs2;
|
|
111
|
+
return _getHydrationIdentityKey((_this$node$attrs = this.node.attrs) === null || _this$node$attrs === void 0 ? void 0 : _this$node$attrs.extensionKey, (_this$node$attrs2 = this.node.attrs) === null || _this$node$attrs2 === void 0 ? void 0 : _this$node$attrs2.localId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** True only for the first ExtensionNode of this identity in this editor. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
115
|
+
}, {
|
|
116
|
+
key: "isInInitialHydrationWindow",
|
|
117
|
+
value: function isInInitialHydrationWindow() {
|
|
118
|
+
var identityKey = this.getHydrationIdentityKey();
|
|
119
|
+
if (identityKey === null) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
return !hasHydrationIdentityBeenConsumed(this.view, identityKey);
|
|
123
|
+
}
|
|
124
|
+
|
|
54
125
|
// Reserve height by setting a minimum height for the extension node view element
|
|
55
126
|
}, {
|
|
56
127
|
key: "createDomRef",
|
|
57
128
|
value: function createDomRef() {
|
|
58
129
|
if (!fg('confluence_connect_macro_preset_height')) {
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
if (!isSSR() && this.isFirstInit && this.node.type.name === 'extension' && this.node.attrs.extensionKey === 'toc' && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
130
|
+
// SSR DOM reuse — see {@link consumedHydrationIdentitiesByEditor}.
|
|
131
|
+
if (!isSSR() && isSSRHydrationEligible(this.node) && this.isInInitialHydrationWindow() && expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
62
132
|
var ssrElement = this.findSSRElement();
|
|
63
133
|
if (ssrElement) {
|
|
64
134
|
this.didReuseSsrDom = true;
|
|
@@ -113,22 +183,22 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
113
183
|
return null;
|
|
114
184
|
}
|
|
115
185
|
|
|
116
|
-
/**
|
|
117
|
-
* Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
|
|
118
|
-
* This preserves the SSR content without React unnecessarily re-rendering it.
|
|
119
|
-
*/
|
|
186
|
+
/** Skip React Portal render on first init when reusing SSR DOM. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
120
187
|
}, {
|
|
121
188
|
key: "init",
|
|
122
189
|
value: function init() {
|
|
123
190
|
if (!expValEquals('platform_editor_hydration_skip_react_portal', 'isEnabled', true)) {
|
|
124
191
|
_superPropGet(ExtensionNode, "init", this, 3)([]);
|
|
125
192
|
} else {
|
|
126
|
-
|
|
193
|
+
var isEligibleForSsrReuse = !isSSR() && isSSRHydrationEligible(this.node);
|
|
194
|
+
if (isEligibleForSsrReuse && this.isInInitialHydrationWindow()) {
|
|
127
195
|
var ssrElement = this.findSSRElement();
|
|
128
196
|
var shouldSkipInitRender = ssrElement !== null;
|
|
129
197
|
_superPropGet(ExtensionNode, "init", this, 3)([shouldSkipInitRender]);
|
|
130
|
-
|
|
131
|
-
|
|
198
|
+
var identityKey = this.getHydrationIdentityKey();
|
|
199
|
+
if (identityKey !== null) {
|
|
200
|
+
// Close the hydration window — see {@link consumedHydrationIdentitiesByEditor}.
|
|
201
|
+
markHydrationIdentityAsConsumed(this.view, identityKey);
|
|
132
202
|
}
|
|
133
203
|
} else {
|
|
134
204
|
_superPropGet(ExtensionNode, "init", this, 3)([]);
|
|
@@ -210,9 +280,8 @@ export var ExtensionNode = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
210
280
|
key: "render",
|
|
211
281
|
value: function render(props, forwardRef) {
|
|
212
282
|
var _props$extensionNodeV;
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
if (this.didReuseSsrDom && this.isFirstInit) {
|
|
283
|
+
// While sitting on SSR DOM, skip the React portal — see {@link didReuseSsrDom}.
|
|
284
|
+
if (this.didReuseSsrDom) {
|
|
216
285
|
return null;
|
|
217
286
|
}
|
|
218
287
|
return /*#__PURE__*/React.createElement(ExtensionNodeWrapper, {
|
|
@@ -62,7 +62,7 @@ export var mediaInsertMessages = defineMessages({
|
|
|
62
62
|
},
|
|
63
63
|
generateTabTitle: {
|
|
64
64
|
id: 'fabric.editor.media.insert.generateTabTitle',
|
|
65
|
-
defaultMessage: '
|
|
65
|
+
defaultMessage: 'Create',
|
|
66
66
|
description: 'Title of the navigation tab that allows users to generate an image through AI'
|
|
67
67
|
},
|
|
68
68
|
mediaPickerPopupAriaLabel: {
|
|
@@ -10,7 +10,7 @@ import { isFedRamp } from './environment';
|
|
|
10
10
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
11
11
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
12
12
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
13
|
-
var packageVersion = "114.
|
|
13
|
+
var packageVersion = "114.16.0";
|
|
14
14
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
15
15
|
// Remove URL as it has UGC
|
|
16
16
|
// Ignored via go/ees007
|
|
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
21
21
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
22
22
|
import Layer from '../Layer';
|
|
23
23
|
var packageName = "@atlaskit/editor-common";
|
|
24
|
-
var packageVersion = "114.
|
|
24
|
+
var packageVersion = "114.16.0";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -43,6 +43,11 @@ export var messages = defineMessages({
|
|
|
43
43
|
id: 'fabric.editor.expandAriaLabel',
|
|
44
44
|
defaultMessage: 'Give this expand a title',
|
|
45
45
|
description: 'aria label for an expand node title input field'
|
|
46
|
+
},
|
|
47
|
+
expandBodyAriaLabel: {
|
|
48
|
+
id: 'fabric.editor.expandBodyAriaLabel',
|
|
49
|
+
defaultMessage: 'Expand body content',
|
|
50
|
+
description: 'Aria label for the body content of an expand node'
|
|
46
51
|
}
|
|
47
52
|
});
|
|
48
53
|
export var ExpandIconWrapper = function ExpandIconWrapper(_ref) {
|
|
@@ -25,20 +25,16 @@ interface ReactExtensionNodeProps {
|
|
|
25
25
|
showUpdatedLivePages1PBodiedExtensionUI?: (node: ADFEntity) => boolean;
|
|
26
26
|
}
|
|
27
27
|
export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNodeView<ReactExtensionNodeProps & AdditionalParams> {
|
|
28
|
-
/**
|
|
29
|
-
* Track whether we found and are reusing SSR'd DOM.
|
|
30
|
-
* When true, we skip React Portal rendering on first init to preserve SSR content.
|
|
31
|
-
*/
|
|
28
|
+
/** True between SSR DOM adoption in `createDomRef` and the SSR→React handoff in `update`. */
|
|
32
29
|
private didReuseSsrDom;
|
|
33
|
-
/**
|
|
34
|
-
* Track whether this is the first init call.
|
|
35
|
-
* SSR content preservation only happens on the very first init.
|
|
36
|
-
*/
|
|
37
|
-
private isFirstInit;
|
|
38
30
|
ignoreMutation(mutation: MutationRecord | {
|
|
39
31
|
target: Node;
|
|
40
32
|
type: 'selection';
|
|
41
33
|
}): boolean;
|
|
34
|
+
/** See {@link consumedHydrationIdentitiesByEditor}. Null when attrs are missing → SSR reuse skipped. */
|
|
35
|
+
private getHydrationIdentityKey;
|
|
36
|
+
/** True only for the first ExtensionNode of this identity in this editor. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
37
|
+
private isInInitialHydrationWindow;
|
|
42
38
|
createDomRef(): HTMLElement;
|
|
43
39
|
/**
|
|
44
40
|
* Cache for SSR element lookup to avoid repeated DOM queries.
|
|
@@ -53,10 +49,7 @@ export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNode
|
|
|
53
49
|
* @returns The SSR'd element if found, otherwise null
|
|
54
50
|
*/
|
|
55
51
|
private findSSRElement;
|
|
56
|
-
/**
|
|
57
|
-
* Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
|
|
58
|
-
* This preserves the SSR content without React unnecessarily re-rendering it.
|
|
59
|
-
*/
|
|
52
|
+
/** Skip React Portal render on first init when reusing SSR DOM. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
60
53
|
init(): this;
|
|
61
54
|
update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
|
|
62
55
|
/**
|
|
@@ -2,35 +2,40 @@ import React from 'react';
|
|
|
2
2
|
import { jsx } from '@emotion/react';
|
|
3
3
|
import type { SerializedStyles } from '@emotion/react';
|
|
4
4
|
export declare const messages: {
|
|
5
|
-
|
|
6
|
-
id: string;
|
|
5
|
+
collapseNode: {
|
|
7
6
|
defaultMessage: string;
|
|
8
7
|
description: string;
|
|
8
|
+
id: string;
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
expandArialabel: {
|
|
11
|
+
defaultMessage: string;
|
|
12
|
+
description: string;
|
|
11
13
|
id: string;
|
|
14
|
+
};
|
|
15
|
+
expandBodyAriaLabel: {
|
|
12
16
|
defaultMessage: string;
|
|
13
17
|
description: string;
|
|
18
|
+
id: string;
|
|
14
19
|
};
|
|
15
20
|
expandDefaultTitle: {
|
|
16
|
-
id: string;
|
|
17
21
|
defaultMessage: string;
|
|
18
22
|
description: string;
|
|
23
|
+
id: string;
|
|
19
24
|
};
|
|
20
25
|
expandNode: {
|
|
21
|
-
id: string;
|
|
22
26
|
defaultMessage: string;
|
|
23
27
|
description: string;
|
|
28
|
+
id: string;
|
|
24
29
|
};
|
|
25
30
|
expandPlaceholderText: {
|
|
26
|
-
id: string;
|
|
27
31
|
defaultMessage: string;
|
|
28
32
|
description: string;
|
|
29
|
-
};
|
|
30
|
-
expandArialabel: {
|
|
31
33
|
id: string;
|
|
34
|
+
};
|
|
35
|
+
loading: {
|
|
32
36
|
defaultMessage: string;
|
|
33
37
|
description: string;
|
|
38
|
+
id: string;
|
|
34
39
|
};
|
|
35
40
|
};
|
|
36
41
|
export declare const ExpandIconWrapper: ({ children, expanded, }: React.HTMLAttributes<HTMLDivElement> & {
|
|
@@ -25,20 +25,16 @@ interface ReactExtensionNodeProps {
|
|
|
25
25
|
showUpdatedLivePages1PBodiedExtensionUI?: (node: ADFEntity) => boolean;
|
|
26
26
|
}
|
|
27
27
|
export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNodeView<ReactExtensionNodeProps & AdditionalParams> {
|
|
28
|
-
/**
|
|
29
|
-
* Track whether we found and are reusing SSR'd DOM.
|
|
30
|
-
* When true, we skip React Portal rendering on first init to preserve SSR content.
|
|
31
|
-
*/
|
|
28
|
+
/** True between SSR DOM adoption in `createDomRef` and the SSR→React handoff in `update`. */
|
|
32
29
|
private didReuseSsrDom;
|
|
33
|
-
/**
|
|
34
|
-
* Track whether this is the first init call.
|
|
35
|
-
* SSR content preservation only happens on the very first init.
|
|
36
|
-
*/
|
|
37
|
-
private isFirstInit;
|
|
38
30
|
ignoreMutation(mutation: MutationRecord | {
|
|
39
31
|
target: Node;
|
|
40
32
|
type: 'selection';
|
|
41
33
|
}): boolean;
|
|
34
|
+
/** See {@link consumedHydrationIdentitiesByEditor}. Null when attrs are missing → SSR reuse skipped. */
|
|
35
|
+
private getHydrationIdentityKey;
|
|
36
|
+
/** True only for the first ExtensionNode of this identity in this editor. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
37
|
+
private isInInitialHydrationWindow;
|
|
42
38
|
createDomRef(): HTMLElement;
|
|
43
39
|
/**
|
|
44
40
|
* Cache for SSR element lookup to avoid repeated DOM queries.
|
|
@@ -53,10 +49,7 @@ export declare class ExtensionNode<AdditionalParams = unknown> extends ReactNode
|
|
|
53
49
|
* @returns The SSR'd element if found, otherwise null
|
|
54
50
|
*/
|
|
55
51
|
private findSSRElement;
|
|
56
|
-
/**
|
|
57
|
-
* Override init() to skip React Portal rendering on first init if we're reusing SSR'd DOM.
|
|
58
|
-
* This preserves the SSR content without React unnecessarily re-rendering it.
|
|
59
|
-
*/
|
|
52
|
+
/** Skip React Portal render on first init when reusing SSR DOM. See {@link consumedHydrationIdentitiesByEditor}. */
|
|
60
53
|
init(): this;
|
|
61
54
|
update(node: PmNode, decorations: ReadonlyArray<Decoration>, _innerDecorations?: DecorationSource, validUpdate?: (currentNode: PmNode, newNode: PmNode) => boolean): boolean;
|
|
62
55
|
/**
|
|
@@ -2,35 +2,40 @@ import React from 'react';
|
|
|
2
2
|
import { jsx } from '@emotion/react';
|
|
3
3
|
import type { SerializedStyles } from '@emotion/react';
|
|
4
4
|
export declare const messages: {
|
|
5
|
-
|
|
6
|
-
id: string;
|
|
5
|
+
collapseNode: {
|
|
7
6
|
defaultMessage: string;
|
|
8
7
|
description: string;
|
|
8
|
+
id: string;
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
expandArialabel: {
|
|
11
|
+
defaultMessage: string;
|
|
12
|
+
description: string;
|
|
11
13
|
id: string;
|
|
14
|
+
};
|
|
15
|
+
expandBodyAriaLabel: {
|
|
12
16
|
defaultMessage: string;
|
|
13
17
|
description: string;
|
|
18
|
+
id: string;
|
|
14
19
|
};
|
|
15
20
|
expandDefaultTitle: {
|
|
16
|
-
id: string;
|
|
17
21
|
defaultMessage: string;
|
|
18
22
|
description: string;
|
|
23
|
+
id: string;
|
|
19
24
|
};
|
|
20
25
|
expandNode: {
|
|
21
|
-
id: string;
|
|
22
26
|
defaultMessage: string;
|
|
23
27
|
description: string;
|
|
28
|
+
id: string;
|
|
24
29
|
};
|
|
25
30
|
expandPlaceholderText: {
|
|
26
|
-
id: string;
|
|
27
31
|
defaultMessage: string;
|
|
28
32
|
description: string;
|
|
29
|
-
};
|
|
30
|
-
expandArialabel: {
|
|
31
33
|
id: string;
|
|
34
|
+
};
|
|
35
|
+
loading: {
|
|
32
36
|
defaultMessage: string;
|
|
33
37
|
description: string;
|
|
38
|
+
id: string;
|
|
34
39
|
};
|
|
35
40
|
};
|
|
36
41
|
export declare const ExpandIconWrapper: ({ children, expanded, }: React.HTMLAttributes<HTMLDivElement> & {
|
package/package.json
CHANGED