@atlaskit/editor-common 114.16.0 → 114.18.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 +37 -0
- package/dist/cjs/extensibility/extensionNodeView.js +91 -22
- package/dist/cjs/messages/markdown-mode.js +5 -5
- package/dist/cjs/messages/media-insert.js +1 -1
- package/dist/cjs/messages/mentions.js +5 -0
- 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/cjs/ui/MediaSingle/grid.js +2 -10
- package/dist/cjs/ui/MediaSingle/styled.js +1 -13
- package/dist/es2019/extensibility/extensionNodeView.js +88 -22
- package/dist/es2019/messages/markdown-mode.js +5 -5
- package/dist/es2019/messages/media-insert.js +1 -1
- package/dist/es2019/messages/mentions.js +5 -0
- 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/es2019/ui/MediaSingle/grid.js +2 -10
- package/dist/es2019/ui/MediaSingle/styled.js +1 -13
- package/dist/esm/extensibility/extensionNodeView.js +91 -22
- package/dist/esm/messages/markdown-mode.js +5 -5
- package/dist/esm/messages/media-insert.js +1 -1
- package/dist/esm/messages/mentions.js +5 -0
- 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/esm/ui/MediaSingle/grid.js +2 -10
- package/dist/esm/ui/MediaSingle/styled.js +1 -13
- package/dist/types/extensibility/extensionNodeView.d.ts +6 -13
- package/dist/types/messages/mentions.d.ts +16 -11
- 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/messages/mentions.d.ts +16 -11
- package/dist/types-ts4.5/ui/Expand/index.d.ts +13 -8
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 114.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`a759f33417d9b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a759f33417d9b) -
|
|
8
|
+
[PIRA-1311](https://opsj.atlassian.net/browse/PIRA-1311) - clean up platform_editor_media_vc_fixes
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- [`7043ace1c45f2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7043ace1c45f2) -
|
|
13
|
+
[ux] reduces slipperiness and improves clarity of inline invites for editor mentions
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
|
|
16
|
+
## 114.17.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- [`9c750ab0192db`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9c750ab0192db) -
|
|
21
|
+
Add role=group and aria-label to expand content div so screen readers announce the body of an
|
|
22
|
+
expand node
|
|
23
|
+
- [`09301dc1b0c55`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/09301dc1b0c55) -
|
|
24
|
+
[ux] Switches the order of the image generation tab in the media insert picker to the first
|
|
25
|
+
position and renames the tab to Create. All changes behind an experiment.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- [`42fa4f485424b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/42fa4f485424b) -
|
|
30
|
+
[ux] Fix Table of Contents extension becoming invisible after drag-and-drop or layout resize when
|
|
31
|
+
the platform_editor_hydration_skip_react_portal experiment is enabled (EDITOR-6613). The SSR
|
|
32
|
+
DOM-reuse optimization is now restricted to the very first ExtensionNode init for each
|
|
33
|
+
(extensionKey, localId) identity within an EditorView. Subsequent ExtensionNodes for the same
|
|
34
|
+
identity (e.g. those created when ProseMirror constructs the new node view before destroying the
|
|
35
|
+
old one during drag-and-drop or layout resize) take the normal React render path instead of
|
|
36
|
+
mistakenly reusing the previous instance's still-mounted React-rendered domRef as if it were SSR
|
|
37
|
+
output. Per-identity scoping preserves the optimization for pages with multiple TOC extensions.
|
|
38
|
+
- Updated dependencies
|
|
39
|
+
|
|
3
40
|
## 114.16.0
|
|
4
41
|
|
|
5
42
|
### 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, {
|
|
@@ -22,18 +22,18 @@ var markdownModeMessages = exports.markdownModeMessages = (0, _reactIntl.defineM
|
|
|
22
22
|
},
|
|
23
23
|
source: {
|
|
24
24
|
id: 'fabric.editor.markdownMode.viewToggle.source',
|
|
25
|
-
defaultMessage: '
|
|
26
|
-
description: 'Tooltip and accessible label for the toggle button that switches the editor into raw markdown source view.'
|
|
25
|
+
defaultMessage: 'Syntax editor',
|
|
26
|
+
description: 'Tooltip and accessible label for the toggle button that switches the editor into raw markdown source (syntax) view.'
|
|
27
27
|
},
|
|
28
28
|
wysiwyg: {
|
|
29
29
|
id: 'fabric.editor.markdownMode.viewToggle.wysiwyg',
|
|
30
|
-
defaultMessage: 'WYSIWYG',
|
|
30
|
+
defaultMessage: 'WYSIWYG editor',
|
|
31
31
|
description: 'Tooltip and accessible label for the toggle button that switches the editor into the WYSIWYG markdown editing view (the default).'
|
|
32
32
|
},
|
|
33
33
|
preview: {
|
|
34
34
|
id: 'fabric.editor.markdownMode.viewToggle.preview',
|
|
35
|
-
defaultMessage: '
|
|
36
|
-
description: 'Tooltip and accessible label for the toggle button that
|
|
35
|
+
defaultMessage: 'Split view (coming soon)',
|
|
36
|
+
description: 'Tooltip and accessible label for the toggle button that will switch the editor into a split view. This feature is not yet available.'
|
|
37
37
|
},
|
|
38
38
|
sourceAriaLabel: {
|
|
39
39
|
id: 'fabric.editor.markdownMode.sourceView.ariaLabel',
|
|
@@ -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: {
|
|
@@ -40,5 +40,10 @@ var mentionMessages = exports.mentionMessages = (0, _reactIntl.defineMessages)({
|
|
|
40
40
|
id: 'fabric.editor.inviteItem.sendInvite',
|
|
41
41
|
defaultMessage: 'Send request to invite teammate',
|
|
42
42
|
description: 'By line text for send request to invite teammate option shown in mentions.'
|
|
43
|
+
},
|
|
44
|
+
inviteButton: {
|
|
45
|
+
id: 'fabric.editor.inviteItem.inviteButton',
|
|
46
|
+
defaultMessage: 'Invite',
|
|
47
|
+
description: 'Label for the invite button shown in the mention typeahead invite item.'
|
|
43
48
|
}
|
|
44
49
|
});
|
|
@@ -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.17.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.17.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) {
|
|
@@ -11,7 +11,6 @@ exports.calcPxFromColumns = calcPxFromColumns;
|
|
|
11
11
|
exports.calcPxFromPct = calcPxFromPct;
|
|
12
12
|
exports.wrappedLayouts = exports.snapToGrid = exports.layoutSupportsWidth = void 0;
|
|
13
13
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
14
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
15
14
|
var _constants = require("../../media-single/constants");
|
|
16
15
|
var validWidthModes = ['center', 'wrap-left', 'wrap-right', 'align-start', 'align-end'];
|
|
17
16
|
var layoutSupportsWidth = exports.layoutSupportsWidth = function layoutSupportsWidth(layout) {
|
|
@@ -67,10 +66,7 @@ var calcMediaPxWidth = exports.calcMediaPxWidth = function calcMediaPxWidth(opts
|
|
|
67
66
|
}
|
|
68
67
|
return calculatedPctWidth;
|
|
69
68
|
}
|
|
70
|
-
|
|
71
|
-
return calculatedPctWidth;
|
|
72
|
-
}
|
|
73
|
-
return Math.min(calculatedPctWidth, origWidth);
|
|
69
|
+
return calculatedPctWidth;
|
|
74
70
|
}
|
|
75
71
|
if (calculatedResizedPctWidth) {
|
|
76
72
|
return calculatedResizedPctWidth;
|
|
@@ -84,11 +80,7 @@ var calcMediaPxWidth = exports.calcMediaPxWidth = function calcMediaPxWidth(opts
|
|
|
84
80
|
} else if (layout && wrappedLayouts.indexOf(layout) !== -1) {
|
|
85
81
|
// when layout is wrap-left, wrap-right, align-start, align-end
|
|
86
82
|
// but no pctWidth is defined
|
|
87
|
-
|
|
88
|
-
return Math.min(calcPxFromPct(0.5, lineLength || width), origWidth);
|
|
89
|
-
}
|
|
90
|
-
var halfLineLength = Math.ceil((lineLength || width) / 2);
|
|
91
|
-
return origWidth <= halfLineLength ? origWidth : halfLineLength;
|
|
83
|
+
return Math.min(calcPxFromPct(0.5, lineLength || width), origWidth);
|
|
92
84
|
}
|
|
93
85
|
return origWidth;
|
|
94
86
|
};
|
|
@@ -16,7 +16,6 @@ var _react = _interopRequireDefault(require("react"));
|
|
|
16
16
|
var _react2 = require("@emotion/react");
|
|
17
17
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
18
18
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
19
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
20
19
|
var _utils = require("../../utils");
|
|
21
20
|
var _breakout = require("../../utils/breakout");
|
|
22
21
|
var _excluded = ["children"];
|
|
@@ -137,16 +136,6 @@ function calcResizedWidth(layout, width) {
|
|
|
137
136
|
return "".concat(width, "px");
|
|
138
137
|
}
|
|
139
138
|
}
|
|
140
|
-
function calcMaxWidth(layout, containerWidth) {
|
|
141
|
-
switch (layout) {
|
|
142
|
-
case 'wide':
|
|
143
|
-
return (0, _breakout.calcWideWidth)(containerWidth);
|
|
144
|
-
case 'full-width':
|
|
145
|
-
return (0, _breakout.calcBreakoutWidth)(layout, containerWidth);
|
|
146
|
-
default:
|
|
147
|
-
return '100%';
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
139
|
function calcMargin(layout) {
|
|
151
140
|
switch (layout) {
|
|
152
141
|
case 'wrap-right':
|
|
@@ -231,7 +220,6 @@ var MediaSingleDimensionHelper = exports.MediaSingleDimensionHelper = function M
|
|
|
231
220
|
_ref$isInRenderer = _ref.isInRenderer,
|
|
232
221
|
isInRenderer = _ref$isInRenderer === void 0 ? false : _ref$isInRenderer;
|
|
233
222
|
var calculatedWidth = roundToClosestEvenPxValue(isExtendedResizeExperienceOn ? "".concat(mediaSingleWidth || width, "px") : mediaSingleWidth ? calcResizedWidth(layout, width || 0, containerWidth) : calcLegacyWidth(layout, width || 0, containerWidth, fullWidthMode, isResized, isInsideOfInlineExtension));
|
|
234
|
-
var calculatedMaxWidth = roundToClosestEvenPxValue(isExtendedResizeExperienceOn ? "".concat(containerWidth, "px") : calcMaxWidth(layout, containerWidth));
|
|
235
223
|
var cssMaxWidth = isExtendedResizeExperienceOn ? 'var(--ak-editor-max-container-width)' : calcMaxCssForPercentageTypeMedia(layout);
|
|
236
224
|
|
|
237
225
|
// jest warning: JSDOM version (22) doesn't support the new @container CSS rule
|
|
@@ -247,7 +235,7 @@ var MediaSingleDimensionHelper = exports.MediaSingleDimensionHelper = function M
|
|
|
247
235
|
'@container ak-renderer-wrapper (min-width: 1px)': {
|
|
248
236
|
maxWidth: '100cqw'
|
|
249
237
|
}
|
|
250
|
-
}) :
|
|
238
|
+
}) : "max-width: ".concat(cssMaxWidth, ";"), isExtendedResizeExperienceOn && "&[class*='is-resizing'] {\n .new-file-experience-wrapper {\n box-shadow: none !important;\n }\n\n ".concat(!isNestedNode && _utils.nonWrappedLayouts.includes(layout) && "margin-left: 50%;\n transform: translateX(-50%);", "\n }"), float(layout), calcMargin(layout), isNestedNode ? /* Make nested node appear responsive when resizing table cell */"max-width: 100%;" : _utils.nonWrappedLayouts.includes(layout) && "margin-left: 50%;\n transform: translateX(-50%);", isImageAligned(layout));
|
|
251
239
|
};
|
|
252
240
|
var RenderFallbackContainer = function RenderFallbackContainer(_ref2) {
|
|
253
241
|
var hasFallbackContainer = _ref2.hasFallbackContainer,
|
|
@@ -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, {
|
|
@@ -17,18 +17,18 @@ export const markdownModeMessages = defineMessages({
|
|
|
17
17
|
},
|
|
18
18
|
source: {
|
|
19
19
|
id: 'fabric.editor.markdownMode.viewToggle.source',
|
|
20
|
-
defaultMessage: '
|
|
21
|
-
description: 'Tooltip and accessible label for the toggle button that switches the editor into raw markdown source view.'
|
|
20
|
+
defaultMessage: 'Syntax editor',
|
|
21
|
+
description: 'Tooltip and accessible label for the toggle button that switches the editor into raw markdown source (syntax) view.'
|
|
22
22
|
},
|
|
23
23
|
wysiwyg: {
|
|
24
24
|
id: 'fabric.editor.markdownMode.viewToggle.wysiwyg',
|
|
25
|
-
defaultMessage: 'WYSIWYG',
|
|
25
|
+
defaultMessage: 'WYSIWYG editor',
|
|
26
26
|
description: 'Tooltip and accessible label for the toggle button that switches the editor into the WYSIWYG markdown editing view (the default).'
|
|
27
27
|
},
|
|
28
28
|
preview: {
|
|
29
29
|
id: 'fabric.editor.markdownMode.viewToggle.preview',
|
|
30
|
-
defaultMessage: '
|
|
31
|
-
description: 'Tooltip and accessible label for the toggle button that
|
|
30
|
+
defaultMessage: 'Split view (coming soon)',
|
|
31
|
+
description: 'Tooltip and accessible label for the toggle button that will switch the editor into a split view. This feature is not yet available.'
|
|
32
32
|
},
|
|
33
33
|
sourceAriaLabel: {
|
|
34
34
|
id: 'fabric.editor.markdownMode.sourceView.ariaLabel',
|
|
@@ -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: {
|
|
@@ -34,5 +34,10 @@ export const mentionMessages = defineMessages({
|
|
|
34
34
|
id: 'fabric.editor.inviteItem.sendInvite',
|
|
35
35
|
defaultMessage: 'Send request to invite teammate',
|
|
36
36
|
description: 'By line text for send request to invite teammate option shown in mentions.'
|
|
37
|
+
},
|
|
38
|
+
inviteButton: {
|
|
39
|
+
id: 'fabric.editor.inviteItem.inviteButton',
|
|
40
|
+
defaultMessage: 'Invite',
|
|
41
|
+
description: 'Label for the invite button shown in the mention typeahead invite item.'
|
|
37
42
|
}
|
|
38
43
|
});
|
|
@@ -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.17.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.17.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 = ({
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { akEditorBreakoutPadding, breakoutWideScaleRatio } from '@atlaskit/editor-shared-styles';
|
|
2
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
2
|
import { MEDIA_SINGLE_GUTTER_SIZE } from '../../media-single/constants';
|
|
4
3
|
const validWidthModes = ['center', 'wrap-left', 'wrap-right', 'align-start', 'align-end'];
|
|
5
4
|
export const layoutSupportsWidth = layout => validWidthModes.indexOf(layout) > -1;
|
|
@@ -55,10 +54,7 @@ export const calcMediaPxWidth = opts => {
|
|
|
55
54
|
}
|
|
56
55
|
return calculatedPctWidth;
|
|
57
56
|
}
|
|
58
|
-
|
|
59
|
-
return calculatedPctWidth;
|
|
60
|
-
}
|
|
61
|
-
return Math.min(calculatedPctWidth, origWidth);
|
|
57
|
+
return calculatedPctWidth;
|
|
62
58
|
}
|
|
63
59
|
if (calculatedResizedPctWidth) {
|
|
64
60
|
return calculatedResizedPctWidth;
|
|
@@ -72,11 +68,7 @@ export const calcMediaPxWidth = opts => {
|
|
|
72
68
|
} else if (layout && wrappedLayouts.indexOf(layout) !== -1) {
|
|
73
69
|
// when layout is wrap-left, wrap-right, align-start, align-end
|
|
74
70
|
// but no pctWidth is defined
|
|
75
|
-
|
|
76
|
-
return Math.min(calcPxFromPct(0.5, lineLength || width), origWidth);
|
|
77
|
-
}
|
|
78
|
-
const halfLineLength = Math.ceil((lineLength || width) / 2);
|
|
79
|
-
return origWidth <= halfLineLength ? origWidth : halfLineLength;
|
|
71
|
+
return Math.min(calcPxFromPct(0.5, lineLength || width), origWidth);
|
|
80
72
|
}
|
|
81
73
|
return origWidth;
|
|
82
74
|
};
|