@atlaskit/editor-common 118.10.2 → 118.11.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/MultiBodiedExtension/index.js +27 -4
- package/dist/cjs/messages/placeholder-text.js +5 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/styles/shared/table.js +1 -1
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/utils/content-visibility.js +177 -0
- package/dist/es2019/extensibility/MultiBodiedExtension/index.js +27 -4
- package/dist/es2019/messages/placeholder-text.js +5 -0
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/styles/shared/table.js +8 -0
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/utils/content-visibility.js +165 -0
- package/dist/esm/extensibility/MultiBodiedExtension/index.js +27 -4
- package/dist/esm/messages/placeholder-text.js +5 -0
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/styles/shared/table.js +1 -1
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/utils/content-visibility.js +166 -0
- package/dist/types/messages/placeholder-text.d.ts +21 -16
- package/dist/types/utils/content-visibility.d.ts +78 -0
- package/package.json +1 -1
- package/utils/content-visibility/package.json +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 118.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`2d23b40eed4f0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2d23b40eed4f0) -
|
|
8
|
+
Add gated content-visibility:auto to tables, expands and media singles to improve editor rendering
|
|
9
|
+
performance on large documents. Applied only to nodes whose rendered size can be estimated closely
|
|
10
|
+
— structurally (row/child counts) for tables and expands, and from the media's own dimensions and
|
|
11
|
+
the renderer's width calculation for media singles. Behind the
|
|
12
|
+
cc_editor_limited_mode_perf_improvements experiment and only active when limited mode is enabled
|
|
13
|
+
for the document (shared large-document detection with the limited-mode plugin).
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
19
|
+
## 118.10.3
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [`2ba69c4d87919`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2ba69c4d87919) -
|
|
24
|
+
Add an experiment-gated empty frame placeholder for multi-bodied extensions under
|
|
25
|
+
confluence_native_tabs_m15.
|
|
26
|
+
|
|
3
27
|
## 118.10.2
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -15,9 +15,12 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
15
15
|
var _react2 = require("@emotion/react");
|
|
16
16
|
var _bindEventListener = require("bind-event-listener");
|
|
17
17
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
18
|
+
var _reactIntl = require("react-intl");
|
|
18
19
|
var _file = _interopRequireDefault(require("@atlaskit/icon/core/file"));
|
|
20
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
19
21
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
20
22
|
var _hooks = require("../../hooks");
|
|
23
|
+
var _placeholderText = require("../../messages/placeholder-text");
|
|
21
24
|
var _MultiBodiedExtension = require("../../ui/MultiBodiedExtension");
|
|
22
25
|
var _utils = require("../../utils");
|
|
23
26
|
var _Lozenge = _interopRequireDefault(require("../Extension/Lozenge"));
|
|
@@ -45,6 +48,20 @@ var getContainerCssExtendedStyles = function getContainerCssExtendedStyles(activ
|
|
|
45
48
|
showMacroInteractionDesignUpdates && _MultiBodiedExtension.removeMarginsAndBorder)))
|
|
46
49
|
);
|
|
47
50
|
};
|
|
51
|
+
|
|
52
|
+
// Renders a visual placeholder when the active frame contains a single empty paragraph.
|
|
53
|
+
var getEmptyFramePlaceholderStyles = function getEmptyFramePlaceholderStyles(activeChildIndex, placeholderText) {
|
|
54
|
+
return (0, _react2.css)((0, _defineProperty2.default)({}, "& .multiBodiedExtension-content-dom-wrapper > [data-extension-frame='true']:nth-of-type(".concat(activeChildIndex + 1
|
|
55
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
56
|
+
, ") > p:only-child:has(.ProseMirror-trailingBreak:only-child)::before"), {
|
|
57
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
58
|
+
// JSON.stringify produces a quoted and escaped CSS string.
|
|
59
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
60
|
+
content: placeholderText,
|
|
61
|
+
pointerEvents: 'none',
|
|
62
|
+
position: 'absolute'
|
|
63
|
+
}));
|
|
64
|
+
};
|
|
48
65
|
var imageStyles = (0, _react2.css)({
|
|
49
66
|
maxHeight: '24px',
|
|
50
67
|
maxWidth: '24px'
|
|
@@ -189,6 +206,8 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
189
206
|
node: node,
|
|
190
207
|
type: 'image'
|
|
191
208
|
});
|
|
209
|
+
var _useIntl = (0, _reactIntl.useIntl)(),
|
|
210
|
+
formatMessage = _useIntl.formatMessage;
|
|
192
211
|
var _useState3 = (0, _react.useState)(0),
|
|
193
212
|
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
|
|
194
213
|
activeChildIndex = _useState4[0],
|
|
@@ -242,6 +261,10 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
242
261
|
mbeWrapperStyles = breakoutStyles;
|
|
243
262
|
}
|
|
244
263
|
var shouldUseUpdatedChrome = (0, _expValEquals.expValEquals)('confluence_native_tabs_experiment', 'isEnabled', true);
|
|
264
|
+
var shouldShowEmptyFramePlaceholder = (0, _isExperimentEnabled.isExperimentEnabled)('confluence_native_tabs_m15');
|
|
265
|
+
var emptyFramePlaceholderText = _react.default.useMemo(function () {
|
|
266
|
+
return JSON.stringify(formatMessage(_placeholderText.placeholderTextMessages.multiBodiedExtensionEmptyFramePlaceholderText));
|
|
267
|
+
}, [formatMessage]);
|
|
245
268
|
var isSelectionInsideMultiBodiedExtension = useIsSelectionInsideNode(editorView, node, getPos, shouldUseUpdatedChrome && !isLivePageViewMode);
|
|
246
269
|
var isMultiBodiedExtensionActive = isNodeSelected || isSelectionInsideMultiBodiedExtension;
|
|
247
270
|
var shouldShowChromeOnInteraction = isNodeHovered || isMultiBodiedExtensionActive;
|
|
@@ -315,10 +338,10 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
315
338
|
"data-testid": "multiBodiedExtension--overlay"
|
|
316
339
|
}), getWrapperTitleContent(imageData, title, showMacroInteractionDesignUpdates), (0, _react2.jsx)("div", {
|
|
317
340
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
318
|
-
className: containerClassNames
|
|
319
|
-
|
|
320
|
-
,
|
|
321
|
-
css
|
|
341
|
+
className: containerClassNames,
|
|
342
|
+
css: [/* eslint-disable @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
|
|
343
|
+
getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates), shouldShowEmptyFramePlaceholder && getEmptyFramePlaceholderStyles(activeChildIndex, emptyFramePlaceholderText)
|
|
344
|
+
/* eslint-enable @atlaskit/design-system/consistent-css-prop-usage */],
|
|
322
345
|
"data-testid": "multiBodiedExtension--container",
|
|
323
346
|
"data-multiBodiedExtension-container": true,
|
|
324
347
|
"data-active-child-index": activeChildIndex
|
|
@@ -50,5 +50,10 @@ var placeholderTextMessages = exports.placeholderTextMessages = (0, _reactIntl.d
|
|
|
50
50
|
id: 'fabric.editor.sourceSyncBlockPlaceholderText',
|
|
51
51
|
defaultMessage: 'Add content you want to reuse. Copy and paste this block to sync in other locations.',
|
|
52
52
|
description: 'Placeholder text shown inside an empty source sync block, prompting users to add reusable content that can be synced across multiple locations.'
|
|
53
|
+
},
|
|
54
|
+
multiBodiedExtensionEmptyFramePlaceholderText: {
|
|
55
|
+
id: 'fabric.editor.multiBodiedExtensionEmptyFramePlaceholderText',
|
|
56
|
+
defaultMessage: 'Type to add content or press / to insert elements',
|
|
57
|
+
description: 'Placeholder text shown inside an empty multi-bodied extension frame, prompting users to type content or use slash commands to insert elements.'
|
|
53
58
|
}
|
|
54
59
|
});
|
|
@@ -28,7 +28,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
28
28
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
29
29
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
30
30
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
31
|
-
var packageVersion = "118.10.
|
|
31
|
+
var packageVersion = "118.10.3";
|
|
32
32
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
33
33
|
// Remove URL as it has UGC
|
|
34
34
|
// Ignored via go/ees007
|
|
@@ -69,7 +69,7 @@ var firstNodeWithNotMarginTop = function firstNodeWithNotMarginTop() {
|
|
|
69
69
|
var tableSharedStyle = exports.tableSharedStyle = function tableSharedStyle() {
|
|
70
70
|
var browser = (0, _browser.getBrowserInfo)();
|
|
71
71
|
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Appears safe to auto-fix, but leaving it up to the team to remediate as the readability only gets worse with autofixing
|
|
72
|
-
return (0, _react.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n\t\t", "\n\t\t.", " {\n\t\t\tposition: relative;\n\t\t\tmargin: 0 auto ", ";\n\t\t\tbox-sizing: border-box;\n\n\t\t\t/**\n\t\t\t * Fix block top alignment inside table cells.\n\t\t\t */\n\t\t\t.decisionItemView-content-wrap:first-of-type > div {\n\t\t\t\tmargin-top: 0;\n\t\t\t}\n\t\t\t", "\n\t\t}\n\t\t.", "[data-number-column='true'] {\n\t\t\tpadding-left: ", "px;\n\t\t\tclear: both;\n\t\t}\n\n\t\t.", " {\n\t\t\twill-change: width, margin-left;\n\t\t}\n\n\t\t.", " table {\n\t\t\twill-change: width;\n\t\t}\n\t\t.", " > table {\n\t\t\tmargin: ", " 0 0 0;\n\t\t}\n\n\t\t.", " > table,\n\t\t.", " > table {\n\t\t\tmargin: ", " ", " 0 0;\n\t\t}\n\n\t\t/* support panel nested in table */\n\t\t", "\n\n\t\t/* avoid applying styles to nested tables (possible via extensions) */\n\t.", " > table,\n\t.", " > table,\n\t.", " > table {\n\t\t\tborder-collapse: collapse;\n\t\t\t", "\n\t\t\ttable-layout: fixed;\n\t\t\tfont-size: 1em;\n\t\t\twidth: 100%;\n\t\t\t", "\n\n\t\t\t&[data-autosize='true'] {\n\t\t\t\ttable-layout: auto;\n\t\t\t}\n\n\t\t\t& {\n\t\t\t\t* {\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t}\n\t\t\t\thr {\n\t\t\t\t\tbox-sizing: content-box;\n\t\t\t\t}\n\n\t\t\t\ttbody {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t\tth td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th,\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tmin-width: ", "px;\n\t\t\t\t\tfont-weight: ", ";\n\t\t\t\t\tvertical-align: top;\n\t\t\t\t\t", "\n\t\t\t\t\tborder: 1px solid ", ";\n\t\t\t\t\tborder-right-width: 0;\n\t\t\t\t\tborder-bottom-width: 0;\n\n\t\t\t\t\tpadding: ", ";\n\t\t\t\t\t/* https://stackoverflow.com/questions/7517127/borders-not-shown-in-firefox-with-border-collapse-on-table-position-relative-o */\n\t\t\t\t\t", "\n\n\t\t\t\t\t", "\n\n\t\t\t\tth p:not(:first-of-type),\n\t\t\t\ttd p:not(:first-of-type) {\n\t\t\t\t\t\tmargin-top: ", ";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Ensures nested tables are compatible with parent table background color - uses specificity to ensure tables nested by extensions are not affected */\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t", "\n\t\t\t\tth {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\ttext-align: left;\n\n\t\t\t\t\t/* only apply this styling to codeblocks in default background headercells */\n\t\t\t\t\t/* TODO this needs to be overhauled as it relies on unsafe selectors */\n\t\t\t\t\t", " {\n\t\t\t\t\t\t.", ":not(.danger) {\n\t\t\t\t\t\t\tbackground-color: ", ";\n\n\t\t\t\t\t\t\t:not(.", ") {\n\t\t\t\t\t\t\t\tbox-shadow: 0px 0px 0px 1px ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-image: ", ";\n\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/* this is only relevant to the element taken care of by renderer */\n\t\t\t\t\t\t\t> [data-ds--code--code-block] {\n\t\t\t\t\t\t\t\tbackground-image: ", "!important;\n\n\t\t\t\t\t\t\t\tbackground-color: ", "!important;\n\n\t\t\t\t\t\t\t\t/* selector lives inside @atlaskit/code */\n\t\t\t\t\t\t\t\t--ds--code--line-number-bg-color: ", ";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t", "\n\t"])), (0, _tableCell.tableCellBackgroundStyleOverride)(), _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, "var(--ds-space-200, 16px)", (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Fake side borders are not needed when the rounded overlay owns the outer border. */\n\t\t\t\t.".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\t\t\t\t\t") : ".".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tdisplay: block;\n\t\t\t\twidth: 1px;\n\t\t\t\theight: calc(100% - ", "var(--ds-space-300, 24px)", ");\n\t\t\t\tbackground: ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: ", "var(--ds-space-300, 24px)", ";\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, " {\n\t\t\t\tright: 0;\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tleft: 0;\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, "[data-with-numbered-table='true'] {\n\t\t\t\tleft: ").concat(_editorSharedStyles.akEditorTableNumberColumnWidth - 1, "px;\n\t\t\t}"), _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _editorSharedStyles.akEditorTableNumberColumnWidth - 1, _TableSharedCssClassName.TableSharedCssClassName.TABLE_RESIZER_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_RESIZER_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, "var(--ds-space-300, 24px)", _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_STICKY_WRAPPER, "var(--ds-space-300, 24px)", "var(--ds-space-100, 8px)", (0, _platformFeatureFlags.fg)('platform_editor_bordered_panel_nested_in_table') ? ".".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, " .ak-editor-panel {\n\t\t\tborder: ", "var(--ds-border-width, 1px)", " solid ", "var(--ds-border, #0B120E24)", ";\n\t\t}") : '', _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_STICKY_WRAPPER, (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Keep a transparent border so the collapsed border model reserves the same 1px slot\n\t\t\t on the table edge; the ::after overlay draws the visible rounded border instead. */\n\t\t\tborder: ".concat(tableCellBorderWidth, "px solid transparent;") : "border: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\tborder-left-color: transparent;\n\t\t\tborder-right-color: transparent;"), (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "position: relative;\n\n\t\t\t/* Table-width outer-border owner for overflow-safe rounded corners. */\n\t\t\t&::after {\n\t\t\t\tcontent: '';\n\t\t\t\tposition: absolute;\n\t\t\t\tinset: -0.5px;\n\t\t\t\tborder: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tborder-radius: ", "var(--ds-radius-xlarge, 12px)", ";\n\t\t\t\tpointer-events: none;\n\t\t\t\tz-index: 1;\n\t\t\t}") : '', "var(--ds-background-neutral-subtle, #00000000)", tableCellMinWidth, "var(--ds-font-weight-regular, 400)", (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_table_menu_updates', 'isEnabled', true) ? "&[data-valign='middle'] {\n\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t&[data-valign='bottom'] {\n\t\t\t\t\t\t\t\tvertical-align: bottom;\n\t\t\t\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtler, #DDDEE1)", "var(--ds-space-100, 8px)", browser.gecko || browser.ie || browser.mac && browser.chrome ? 'background-clip: padding-box;' : '', firstNodeWithNotMarginTop(), "var(--ds-space-150, 12px)", "var(--ds-surface, #FFFFFF)", (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Let the wrapper overlay own the outer table perimeter.\n\t\t\t\t data-reaches-* attributes are set by the TableCell node view. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top] {\n\t\t\t\t\tborder-top-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th[data-reaches-left],\n\t\t\t\t> tbody > tr > td[data-reaches-left] {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-left]::after {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-bottom]::after,\n\t\t\t\t> tbody > tr > th[data-reaches-bottom]::after {\n\t\t\t\t\tborder-bottom-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t/* The rounded-table overlay owns transparent perimeter borders.\n\t\t\t\t Paint edge cell backgrounds into that reserved border area so coloured\n\t\t\t\t first/last rows do not show the page background through 1px seams. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top],\n\t\t\t\t> tbody > tr > th[data-reaches-bottom],\n\t\t\t\t> tbody > tr > td[data-reaches-bottom] {\n\t\t\t\t\tbackground-clip: border-box;\n\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtlest, #F0F1F2)", (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? '&:not(.danger)' : '&:not([style]):not(.danger)', _codeBlock.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, "var(--ds-surface-raised, #FFFFFF)", _editorSharedStyles.akEditorSelectedNodeClassName, "var(--ds-border, #0B120E24)", _codeBlock.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER, (0, _editorSharedStyles.overflowShadow)({
|
|
72
|
+
return (0, _react.css)(_templateObject2 || (_templateObject2 = (0, _taggedTemplateLiteral2.default)(["\n\t\t", "\n\t\t.", " {\n\t\t\tposition: relative;\n\t\t\tmargin: 0 auto ", ";\n\t\t\tbox-sizing: border-box;\n\n\t\t\t/**\n\t\t\t * Fix block top alignment inside table cells.\n\t\t\t */\n\t\t\t.decisionItemView-content-wrap:first-of-type > div {\n\t\t\t\tmargin-top: 0;\n\t\t\t}\n\t\t\t", "\n\t\t}\n\t\t.", "[data-number-column='true'] {\n\t\t\tpadding-left: ", "px;\n\t\t\tclear: both;\n\t\t}\n\n\t\t.", " {\n\t\t\twill-change: width, margin-left;\n\t\t}\n\n\t\t.", " table {\n\t\t\twill-change: width;\n\t\t}\n\t\t.", " > table {\n\t\t\tmargin: ", " 0 0 0;\n\t\t}\n\n\t\t.", " > table,\n\t\t.", " > table {\n\t\t\tmargin: ", " ", " 0 0;\n\t\t}\n\n\t\t/* support panel nested in table */\n\t\t", "\n\n\t\t/* avoid applying styles to nested tables (possible via extensions) */\n\t.", " > table,\n\t.", " > table,\n\t.", " > table {\n\t\t\tborder-collapse: collapse;\n\t\t\t", "\n\t\t\ttable-layout: fixed;\n\t\t\tfont-size: 1em;\n\t\t\twidth: 100%;\n\t\t\t", "\n\n\t\t\t&[data-autosize='true'] {\n\t\t\t\ttable-layout: auto;\n\t\t\t}\n\n\t\t\t& {\n\t\t\t\t* {\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t}\n\t\t\t\thr {\n\t\t\t\t\tbox-sizing: content-box;\n\t\t\t\t}\n\n\t\t\t\ttbody {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t\tth td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th,\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tmin-width: ", "px;\n\t\t\t\t\tfont-weight: ", ";\n\t\t\t\t\tvertical-align: top;\n\t\t\t\t\t", "\n\t\t\t\t\tborder: 1px solid ", ";\n\t\t\t\t\tborder-right-width: 0;\n\t\t\t\t\tborder-bottom-width: 0;\n\n\t\t\t\t\tpadding: ", ";\n\t\t\t\t\t/* https://stackoverflow.com/questions/7517127/borders-not-shown-in-firefox-with-border-collapse-on-table-position-relative-o */\n\t\t\t\t\t", "\n\n\t\t\t\t\t", "\n\n\t\t\t\tth p:not(:first-of-type),\n\t\t\t\ttd p:not(:first-of-type) {\n\t\t\t\t\t\tmargin-top: ", ";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Ensures nested tables are compatible with parent table background color - uses specificity to ensure tables nested by extensions are not affected */\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t", "\n\t\t\t\tth {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\ttext-align: left;\n\n\t\t\t\t\t/* only apply this styling to codeblocks in default background headercells */\n\t\t\t\t\t/* TODO this needs to be overhauled as it relies on unsafe selectors */\n\t\t\t\t\t", " {\n\t\t\t\t\t\t.", ":not(.danger) {\n\t\t\t\t\t\t\tbackground-color: ", ";\n\n\t\t\t\t\t\t\t:not(.", ") {\n\t\t\t\t\t\t\t\tbox-shadow: 0px 0px 0px 1px ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-image: ", ";\n\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/* this is only relevant to the element taken care of by renderer */\n\t\t\t\t\t\t\t> [data-ds--code--code-block] {\n\t\t\t\t\t\t\t\tbackground-image: ", "!important;\n\n\t\t\t\t\t\t\t\tbackground-color: ", "!important;\n\n\t\t\t\t\t\t\t\t/* selector lives inside @atlaskit/code */\n\t\t\t\t\t\t\t\t--ds--code--line-number-bg-color: ", ";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t", "\n\t"])), (0, _tableCell.tableCellBackgroundStyleOverride)(), _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, "var(--ds-space-200, 16px)", (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Fake side borders are not needed when the rounded overlay owns the outer border. */\n\t\t\t\t.".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\t\t\t\t\t") : ".".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tdisplay: block;\n\t\t\t\twidth: 1px;\n\t\t\t\theight: calc(100% - ", "var(--ds-space-300, 24px)", ");\n\t\t\t\tbackground: ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: ", "var(--ds-space-300, 24px)", ";\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_RIGHT_BORDER, " {\n\t\t\t\tright: 0;\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tleft: 0;\n\t\t\t}\n\t\t\t.").concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_LEFT_BORDER, "[data-with-numbered-table='true'] {\n\t\t\t\tleft: ").concat(_editorSharedStyles.akEditorTableNumberColumnWidth - 1, "px;\n\t\t\t}"), _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _editorSharedStyles.akEditorTableNumberColumnWidth - 1, _TableSharedCssClassName.TableSharedCssClassName.TABLE_RESIZER_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_RESIZER_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, "var(--ds-space-300, 24px)", _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_STICKY_WRAPPER, "var(--ds-space-300, 24px)", "var(--ds-space-100, 8px)", (0, _platformFeatureFlags.fg)('platform_editor_bordered_panel_nested_in_table') ? ".".concat(_TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, " .ak-editor-panel {\n\t\t\tborder: ", "var(--ds-border-width, 1px)", " solid ", "var(--ds-border, #0B120E24)", ";\n\t\t}") : '', _TableSharedCssClassName.TableSharedCssClassName.TABLE_CONTAINER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_NODE_WRAPPER, _TableSharedCssClassName.TableSharedCssClassName.TABLE_STICKY_WRAPPER, (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Keep a transparent border so the collapsed border model reserves the same 1px slot\n\t\t\t on the table edge; the ::after overlay draws the visible rounded border instead. */\n\t\t\tborder: ".concat(tableCellBorderWidth, "px solid transparent;") : "border: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\tborder-left-color: transparent;\n\t\t\tborder-right-color: transparent;"), (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "position: relative;\n\n\t\t\t/* Table-width outer-border owner for overflow-safe rounded corners. */\n\t\t\t&::after {\n\t\t\t\tcontent: '';\n\t\t\t\tposition: absolute;\n\t\t\t\tinset: -0.5px;\n\t\t\t\tborder: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tborder-radius: ", "var(--ds-radius-xlarge, 12px)", ";\n\t\t\t\tpointer-events: none;\n\t\t\t\tz-index: 1;\n\t\t\t}\n\n\t\t\t/* When content-visibility is applied to the table (see editor-plugin-table nodeview), the\n\t\t\t implied `contain: paint` clips descendant painting to the table's border-box. The\n\t\t\t overlay above sits at `inset: -0.5px` (half a pixel outside), so it would be shaved \u2014\n\t\t\t most visibly along the bottom. Pull it flush to the edge so it paints inside the clip. */\n\t\t\t&[data-content-visibility]::after {\n\t\t\t\tinset: 0;\n\t\t\t}") : '', "var(--ds-background-neutral-subtle, #00000000)", tableCellMinWidth, "var(--ds-font-weight-regular, 400)", (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_table_menu_updates', 'isEnabled', true) ? "&[data-valign='middle'] {\n\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t&[data-valign='bottom'] {\n\t\t\t\t\t\t\t\tvertical-align: bottom;\n\t\t\t\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtler, #DDDEE1)", "var(--ds-space-100, 8px)", browser.gecko || browser.ie || browser.mac && browser.chrome ? 'background-clip: padding-box;' : '', firstNodeWithNotMarginTop(), "var(--ds-space-150, 12px)", "var(--ds-surface, #FFFFFF)", (0, _expValEquals.expValEquals)('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Let the wrapper overlay own the outer table perimeter.\n\t\t\t\t data-reaches-* attributes are set by the TableCell node view. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top] {\n\t\t\t\t\tborder-top-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th[data-reaches-left],\n\t\t\t\t> tbody > tr > td[data-reaches-left] {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-left]::after {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-bottom]::after,\n\t\t\t\t> tbody > tr > th[data-reaches-bottom]::after {\n\t\t\t\t\tborder-bottom-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t/* The rounded-table overlay owns transparent perimeter borders.\n\t\t\t\t Paint edge cell backgrounds into that reserved border area so coloured\n\t\t\t\t first/last rows do not show the page background through 1px seams. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top],\n\t\t\t\t> tbody > tr > th[data-reaches-bottom],\n\t\t\t\t> tbody > tr > td[data-reaches-bottom] {\n\t\t\t\t\tbackground-clip: border-box;\n\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtlest, #F0F1F2)", (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? '&:not(.danger)' : '&:not([style]):not(.danger)', _codeBlock.CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, "var(--ds-surface-raised, #FFFFFF)", _editorSharedStyles.akEditorSelectedNodeClassName, "var(--ds-border, #0B120E24)", _codeBlock.CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER, (0, _editorSharedStyles.overflowShadow)({
|
|
73
73
|
leftCoverWidth: "var(--ds-space-300, 24px)"
|
|
74
74
|
}), "var(--ds-background-neutral, #0515240F)", _codeBlock.CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER, "var(--ds-background-neutral, #0515240F)", (0, _editorSharedStyles.overflowShadow)({
|
|
75
75
|
leftCoverWidth: "var(--ds-space-300, 24px)"
|
|
@@ -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 = "118.10.
|
|
27
|
+
var packageVersion = "118.10.3";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.applyContentVisibility = applyContentVisibility;
|
|
8
|
+
exports.estimateExpandIntrinsicHeight = estimateExpandIntrinsicHeight;
|
|
9
|
+
exports.estimateMediaSingleIntrinsicSize = estimateMediaSingleIntrinsicSize;
|
|
10
|
+
exports.estimateTableIntrinsicHeight = estimateTableIntrinsicHeight;
|
|
11
|
+
exports.formatIntrinsicSize = formatIntrinsicSize;
|
|
12
|
+
exports.getContentVisibilityStyle = getContentVisibilityStyle;
|
|
13
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
15
|
+
var _utils = require("../media-single/utils");
|
|
16
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
17
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
18
|
+
// Rough per-node rendered-size constants (px), grounded in the real style defaults from
|
|
19
|
+
// `styles/shared/table.ts`, `EditorContentContainer/styles/expandStyles.ts` and
|
|
20
|
+
// `EditorContentContainer/styles/layout.ts`. These only need to be a decent first estimate: the
|
|
21
|
+
// `auto` keyword in `contain-intrinsic-*: auto <estimate>` makes the browser remember each
|
|
22
|
+
// element's real size after its first render, so any inaccuracy self-corrects on scroll. Where the
|
|
23
|
+
// estimate can't be exact we intentionally err slightly HIGH — over-reserving leaves a marginally
|
|
24
|
+
// long scrollbar that shrinks on scroll, whereas under-reserving makes content jump upward.
|
|
25
|
+
var TABLE_ROW_HEIGHT = 44; // row content: line-height + cell padding (space.100 ×2) + cell border
|
|
26
|
+
var TABLE_VERTICAL_MARGIN = 40; // tableMarginTop(24) + tableMarginBottom(16)
|
|
27
|
+
var TABLE_MIN_HEIGHT = 120;
|
|
28
|
+
var BLOCK_HEIGHT = 28; // a typical paragraph/block line + spacing
|
|
29
|
+
|
|
30
|
+
var EXPAND_HEADER_HEIGHT = 48; // min-height:25 + padding + margin of the title row
|
|
31
|
+
var EXPAND_CONTENT_PADDING = 8; // space.100 padding-top when expanded
|
|
32
|
+
|
|
33
|
+
var MEDIA_SINGLE_MIN_HEIGHT = 100;
|
|
34
|
+
var MEDIA_SINGLE_GUTTER = 12; // MEDIA_SINGLE_GUTTER_SIZE — gap between resizer handle and media
|
|
35
|
+
var MEDIA_SINGLE_VERTICAL_MARGIN = 24; // rich-media-item margin: space.150 top + bottom
|
|
36
|
+
var MEDIA_CAPTION_HEIGHT = 32; // caption line-height + vertical padding, when a caption is present
|
|
37
|
+
var DEFAULT_MEDIA_ASPECT_RATIO = 9 / 16; // used only when the media has no intrinsic dimensions
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The intrinsic size a nodeView reserves while off-screen (`contain-intrinsic-width`/`-height`).
|
|
41
|
+
* `width` is optional: for block-level wrappers (expand, layout) the inline size comes from the
|
|
42
|
+
* containing block regardless of size containment, so only `height` is meaningful; for
|
|
43
|
+
* content-sized boxes (the `<table>` element, the mediaSingle wrapper) the width matters and must
|
|
44
|
+
* be supplied or the box collapses to 0 wide while contained.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Estimate the rendered height of a table from its row count. Cell padding and cell borders are
|
|
49
|
+
* already folded into `TABLE_ROW_HEIGHT`; the table's block margins are added as a small buffer.
|
|
50
|
+
*/
|
|
51
|
+
function estimateTableIntrinsicHeight(node) {
|
|
52
|
+
var rows = node.childCount;
|
|
53
|
+
return Math.max(TABLE_MIN_HEIGHT, rows * TABLE_ROW_HEIGHT + TABLE_VERTICAL_MARGIN);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Estimate the rendered height of an expand. A collapsed expand reserves only its header row; an
|
|
58
|
+
* expanded one additionally reserves space for its child blocks. `expanded` is passed in by the
|
|
59
|
+
* caller because the two expand implementations track expanded state differently (a WeakMap in
|
|
60
|
+
* single-player vs the `__expanded` attribute in legacy).
|
|
61
|
+
*/
|
|
62
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
63
|
+
function estimateExpandIntrinsicHeight(node, expanded) {
|
|
64
|
+
if (!expanded) {
|
|
65
|
+
return EXPAND_HEADER_HEIGHT;
|
|
66
|
+
}
|
|
67
|
+
return EXPAND_HEADER_HEIGHT + node.childCount * BLOCK_HEIGHT + EXPAND_CONTENT_PADDING;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Estimate the rendered width AND height of a mediaSingle. Unlike the structural estimates above,
|
|
72
|
+
* media carries its real dimensions in the ADF: the child `media` node's `width`/`height` attrs
|
|
73
|
+
* give the intrinsic aspect ratio, and the rendered pixel width is computed with the exact same
|
|
74
|
+
* `calcMediaSinglePixelWidth` helper the renderer uses (honouring `width`/`widthType`/`layout` and
|
|
75
|
+
* the editor's content/container width). Height then follows from width × aspect ratio — plus a
|
|
76
|
+
* caption row when present and the mediaSingle's block margins — so this is the most accurate
|
|
77
|
+
* estimate of any node type. The pixel width is returned as the intrinsic width because the
|
|
78
|
+
* mediaSingle wrapper is content-sized. `lineLength` and `containerWidth` come from the width
|
|
79
|
+
* plugin's shared state.
|
|
80
|
+
*/
|
|
81
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
82
|
+
function estimateMediaSingleIntrinsicSize(node, lineLength, containerWidth) {
|
|
83
|
+
var _media$attrs, _media$attrs2, _node$attrs$width, _ref;
|
|
84
|
+
var media = node.firstChild;
|
|
85
|
+
var origWidth = Number(media === null || media === void 0 || (_media$attrs = media.attrs) === null || _media$attrs === void 0 ? void 0 : _media$attrs.width) || 0;
|
|
86
|
+
var origHeight = Number(media === null || media === void 0 || (_media$attrs2 = media.attrs) === null || _media$attrs2 === void 0 ? void 0 : _media$attrs2.height) || 0;
|
|
87
|
+
var aspectRatio = origWidth && origHeight ? origHeight / origWidth : DEFAULT_MEDIA_ASPECT_RATIO;
|
|
88
|
+
var pixelWidth = (0, _utils.calcMediaSinglePixelWidth)({
|
|
89
|
+
width: (_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : undefined,
|
|
90
|
+
widthType: node.attrs.widthType,
|
|
91
|
+
origWidth: origWidth || lineLength || containerWidth,
|
|
92
|
+
layout: (_ref = node.attrs.layout) !== null && _ref !== void 0 ? _ref : 'center',
|
|
93
|
+
contentWidth: lineLength || undefined,
|
|
94
|
+
containerWidth: containerWidth || lineLength,
|
|
95
|
+
gutterOffset: MEDIA_SINGLE_GUTTER
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// A caption child (childCount > 1) sits below the media, and the mediaSingle block reserves
|
|
99
|
+
// vertical margin above and below regardless.
|
|
100
|
+
var captionHeight = node.childCount > 1 ? MEDIA_CAPTION_HEIGHT : 0;
|
|
101
|
+
var height = Math.max(MEDIA_SINGLE_MIN_HEIGHT, Math.round(pixelWidth * aspectRatio) + captionHeight + MEDIA_SINGLE_VERTICAL_MARGIN);
|
|
102
|
+
return {
|
|
103
|
+
width: Math.round(pixelWidth),
|
|
104
|
+
height: height
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Produce a single-axis `contain-intrinsic-width`/`-height` value using the `auto` keyword so the
|
|
110
|
+
* browser remembers the element's real size after its first render and only uses the estimate
|
|
111
|
+
* beforehand.
|
|
112
|
+
*/
|
|
113
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
114
|
+
function formatIntrinsicSize(px) {
|
|
115
|
+
return "auto ".concat(Math.round(px), "px");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The `content-visibility` / `contain-intrinsic-*` styles applied to an eligible node. Width and
|
|
120
|
+
* height are kept as separate `contain-intrinsic-width`/`-height` axes rather than the
|
|
121
|
+
* `contain-intrinsic-size` shorthand: the shorthand's single value is applied to BOTH axes, which
|
|
122
|
+
* forces a wrong width on content-sized boxes (e.g. a 500px-tall `<table>` would reserve 500px
|
|
123
|
+
* wide). `containIntrinsicWidth` is omitted for block-level wrappers whose width comes from layout.
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Resolve the `content-visibility` styles for a node, or `undefined` when the optimisation should
|
|
128
|
+
* not apply.
|
|
129
|
+
*
|
|
130
|
+
* Gating is delegated to limited mode: `limitedModeEnabled` should come from the limited-mode
|
|
131
|
+
* plugin's shared state, so this feature shares a single "large document" definition with limited
|
|
132
|
+
* mode rather than a bespoke threshold. The optimisation applies only when the feature gate is on
|
|
133
|
+
* AND limited mode is active.
|
|
134
|
+
*
|
|
135
|
+
* The intrinsic size is supplied lazily via `getIntrinsicSize` so callers can compute a
|
|
136
|
+
* per-instance estimate from the node's structure, and is only evaluated when actually applied.
|
|
137
|
+
*/
|
|
138
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
139
|
+
function getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize) {
|
|
140
|
+
if (!limitedModeEnabled || !(0, _isExperimentEnabled.isExperimentEnabled)('cc_editor_limited_mode_perf_improvements')) {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
var _getIntrinsicSize = getIntrinsicSize(),
|
|
144
|
+
width = _getIntrinsicSize.width,
|
|
145
|
+
height = _getIntrinsicSize.height;
|
|
146
|
+
return _objectSpread({
|
|
147
|
+
contentVisibility: 'auto',
|
|
148
|
+
containIntrinsicHeight: formatIntrinsicSize(height)
|
|
149
|
+
}, width !== undefined ? {
|
|
150
|
+
containIntrinsicWidth: formatIntrinsicSize(width)
|
|
151
|
+
} : {});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Imperatively apply the `content-visibility: auto` rendering optimisation to a node's top-level
|
|
156
|
+
* DOM element (for use in raw-DOM nodeViews), but only when both the feature gate is on and limited
|
|
157
|
+
* mode is active (see `getContentVisibilityStyle`).
|
|
158
|
+
*
|
|
159
|
+
* The intrinsic size uses the `auto` keyword so any initial inaccuracy self-corrects once the
|
|
160
|
+
* element has been rendered once. Safe to call repeatedly (e.g. on expand/collapse toggle) — it
|
|
161
|
+
* simply re-applies or, when ineligible, leaves the element untouched.
|
|
162
|
+
*/
|
|
163
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
164
|
+
function applyContentVisibility(dom, limitedModeEnabled, getIntrinsicSize) {
|
|
165
|
+
var _style$containIntrins;
|
|
166
|
+
var style = getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize);
|
|
167
|
+
if (!style) {
|
|
168
|
+
dom.style.contentVisibility = '';
|
|
169
|
+
dom.style.containIntrinsicHeight = '';
|
|
170
|
+
dom.style.containIntrinsicWidth = '';
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
dom.style.contentVisibility = style.contentVisibility;
|
|
174
|
+
dom.style.containIntrinsicHeight = style.containIntrinsicHeight;
|
|
175
|
+
dom.style.containIntrinsicWidth = (_style$containIntrins = style.containIntrinsicWidth) !== null && _style$containIntrins !== void 0 ? _style$containIntrins : '';
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
@@ -11,9 +11,12 @@ import React, { Fragment, useEffect, useRef, useState } from 'react';
|
|
|
11
11
|
import { css, jsx } from '@emotion/react';
|
|
12
12
|
import { bind } from 'bind-event-listener';
|
|
13
13
|
import classnames from 'classnames';
|
|
14
|
+
import { useIntl } from 'react-intl';
|
|
14
15
|
import EditorFileIcon from '@atlaskit/icon/core/file';
|
|
16
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
15
17
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
16
18
|
import { useSharedPluginStateWithSelector } from '../../hooks';
|
|
19
|
+
import { placeholderTextMessages } from '../../messages/placeholder-text';
|
|
17
20
|
import { removeMarginsAndBorder, sharedMultiBodiedExtensionStyles } from '../../ui/MultiBodiedExtension';
|
|
18
21
|
import { calculateBreakoutStyles, getExtensionLozengeData } from '../../utils';
|
|
19
22
|
import ExtensionLozenge from '../Extension/Lozenge';
|
|
@@ -33,6 +36,21 @@ css(sharedMultiBodiedExtensionStyles.mbeExtensionContainer, {
|
|
|
33
36
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
|
|
34
37
|
showMacroInteractionDesignUpdates && removeMarginsAndBorder)
|
|
35
38
|
});
|
|
39
|
+
|
|
40
|
+
// Renders a visual placeholder when the active frame contains a single empty paragraph.
|
|
41
|
+
const getEmptyFramePlaceholderStyles = (activeChildIndex, placeholderText) => css({
|
|
42
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
43
|
+
[`& .multiBodiedExtension-content-dom-wrapper > [data-extension-frame='true']:nth-of-type(${activeChildIndex + 1
|
|
44
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
45
|
+
}) > p:only-child:has(.ProseMirror-trailingBreak:only-child)::before`]: {
|
|
46
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
47
|
+
// JSON.stringify produces a quoted and escaped CSS string.
|
|
48
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
49
|
+
content: placeholderText,
|
|
50
|
+
pointerEvents: 'none',
|
|
51
|
+
position: 'absolute'
|
|
52
|
+
}
|
|
53
|
+
});
|
|
36
54
|
const imageStyles = css({
|
|
37
55
|
maxHeight: '24px',
|
|
38
56
|
maxWidth: '24px'
|
|
@@ -177,6 +195,9 @@ const MultiBodiedExtensionWithWidth = ({
|
|
|
177
195
|
node,
|
|
178
196
|
type: 'image'
|
|
179
197
|
});
|
|
198
|
+
const {
|
|
199
|
+
formatMessage
|
|
200
|
+
} = useIntl();
|
|
180
201
|
const [activeChildIndex, setActiveChildIndex] = useState(0);
|
|
181
202
|
// Adding to avoid aliasing `this` for the callbacks
|
|
182
203
|
const updateActiveChild = React.useCallback(index => {
|
|
@@ -228,6 +249,8 @@ const MultiBodiedExtensionWithWidth = ({
|
|
|
228
249
|
mbeWrapperStyles = breakoutStyles;
|
|
229
250
|
}
|
|
230
251
|
const shouldUseUpdatedChrome = expValEquals('confluence_native_tabs_experiment', 'isEnabled', true);
|
|
252
|
+
const shouldShowEmptyFramePlaceholder = isExperimentEnabled('confluence_native_tabs_m15');
|
|
253
|
+
const emptyFramePlaceholderText = React.useMemo(() => JSON.stringify(formatMessage(placeholderTextMessages.multiBodiedExtensionEmptyFramePlaceholderText)), [formatMessage]);
|
|
231
254
|
const isSelectionInsideMultiBodiedExtension = useIsSelectionInsideNode(editorView, node, getPos, shouldUseUpdatedChrome && !isLivePageViewMode);
|
|
232
255
|
const isMultiBodiedExtensionActive = isNodeSelected || isSelectionInsideMultiBodiedExtension;
|
|
233
256
|
const shouldShowChromeOnInteraction = isNodeHovered || isMultiBodiedExtensionActive;
|
|
@@ -297,10 +320,10 @@ const MultiBodiedExtensionWithWidth = ({
|
|
|
297
320
|
"data-testid": "multiBodiedExtension--overlay"
|
|
298
321
|
}), getWrapperTitleContent(imageData, title, showMacroInteractionDesignUpdates), jsx("div", {
|
|
299
322
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
300
|
-
className: containerClassNames
|
|
301
|
-
|
|
302
|
-
,
|
|
303
|
-
css
|
|
323
|
+
className: containerClassNames,
|
|
324
|
+
css: [/* eslint-disable @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
|
|
325
|
+
getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates), shouldShowEmptyFramePlaceholder && getEmptyFramePlaceholderStyles(activeChildIndex, emptyFramePlaceholderText)
|
|
326
|
+
/* eslint-enable @atlaskit/design-system/consistent-css-prop-usage */],
|
|
304
327
|
"data-testid": "multiBodiedExtension--container",
|
|
305
328
|
"data-multiBodiedExtension-container": true,
|
|
306
329
|
"data-active-child-index": activeChildIndex
|
|
@@ -44,5 +44,10 @@ export const placeholderTextMessages = defineMessages({
|
|
|
44
44
|
id: 'fabric.editor.sourceSyncBlockPlaceholderText',
|
|
45
45
|
defaultMessage: 'Add content you want to reuse. Copy and paste this block to sync in other locations.',
|
|
46
46
|
description: 'Placeholder text shown inside an empty source sync block, prompting users to add reusable content that can be synced across multiple locations.'
|
|
47
|
+
},
|
|
48
|
+
multiBodiedExtensionEmptyFramePlaceholderText: {
|
|
49
|
+
id: 'fabric.editor.multiBodiedExtensionEmptyFramePlaceholderText',
|
|
50
|
+
defaultMessage: 'Type to add content or press / to insert elements',
|
|
51
|
+
description: 'Placeholder text shown inside an empty multi-bodied extension frame, prompting users to type content or use slash commands to insert elements.'
|
|
47
52
|
}
|
|
48
53
|
});
|
|
@@ -14,7 +14,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
14
14
|
const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
15
15
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
16
16
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
17
|
-
const packageVersion = "118.10.
|
|
17
|
+
const packageVersion = "118.10.3";
|
|
18
18
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
19
19
|
// Remove URL as it has UGC
|
|
20
20
|
// Ignored via go/ees007
|
|
@@ -136,6 +136,14 @@ const tableSharedStyle = () => {
|
|
|
136
136
|
border-radius: ${"var(--ds-radius-xlarge, 12px)"};
|
|
137
137
|
pointer-events: none;
|
|
138
138
|
z-index: 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* When content-visibility is applied to the table (see editor-plugin-table nodeview), the
|
|
142
|
+
implied \`contain: paint\` clips descendant painting to the table's border-box. The
|
|
143
|
+
overlay above sits at \`inset: -0.5px\` (half a pixel outside), so it would be shaved —
|
|
144
|
+
most visibly along the bottom. Pull it flush to the edge so it paints inside the clip. */
|
|
145
|
+
&[data-content-visibility]::after {
|
|
146
|
+
inset: 0;
|
|
139
147
|
}` : ''}
|
|
140
148
|
|
|
141
149
|
&[data-autosize='true'] {
|
|
@@ -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 = "118.10.
|
|
17
|
+
const packageVersion = "118.10.3";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
2
|
+
import { calcMediaSinglePixelWidth } from '../media-single/utils';
|
|
3
|
+
|
|
4
|
+
// Rough per-node rendered-size constants (px), grounded in the real style defaults from
|
|
5
|
+
// `styles/shared/table.ts`, `EditorContentContainer/styles/expandStyles.ts` and
|
|
6
|
+
// `EditorContentContainer/styles/layout.ts`. These only need to be a decent first estimate: the
|
|
7
|
+
// `auto` keyword in `contain-intrinsic-*: auto <estimate>` makes the browser remember each
|
|
8
|
+
// element's real size after its first render, so any inaccuracy self-corrects on scroll. Where the
|
|
9
|
+
// estimate can't be exact we intentionally err slightly HIGH — over-reserving leaves a marginally
|
|
10
|
+
// long scrollbar that shrinks on scroll, whereas under-reserving makes content jump upward.
|
|
11
|
+
const TABLE_ROW_HEIGHT = 44; // row content: line-height + cell padding (space.100 ×2) + cell border
|
|
12
|
+
const TABLE_VERTICAL_MARGIN = 40; // tableMarginTop(24) + tableMarginBottom(16)
|
|
13
|
+
const TABLE_MIN_HEIGHT = 120;
|
|
14
|
+
const BLOCK_HEIGHT = 28; // a typical paragraph/block line + spacing
|
|
15
|
+
|
|
16
|
+
const EXPAND_HEADER_HEIGHT = 48; // min-height:25 + padding + margin of the title row
|
|
17
|
+
const EXPAND_CONTENT_PADDING = 8; // space.100 padding-top when expanded
|
|
18
|
+
|
|
19
|
+
const MEDIA_SINGLE_MIN_HEIGHT = 100;
|
|
20
|
+
const MEDIA_SINGLE_GUTTER = 12; // MEDIA_SINGLE_GUTTER_SIZE — gap between resizer handle and media
|
|
21
|
+
const MEDIA_SINGLE_VERTICAL_MARGIN = 24; // rich-media-item margin: space.150 top + bottom
|
|
22
|
+
const MEDIA_CAPTION_HEIGHT = 32; // caption line-height + vertical padding, when a caption is present
|
|
23
|
+
const DEFAULT_MEDIA_ASPECT_RATIO = 9 / 16; // used only when the media has no intrinsic dimensions
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The intrinsic size a nodeView reserves while off-screen (`contain-intrinsic-width`/`-height`).
|
|
27
|
+
* `width` is optional: for block-level wrappers (expand, layout) the inline size comes from the
|
|
28
|
+
* containing block regardless of size containment, so only `height` is meaningful; for
|
|
29
|
+
* content-sized boxes (the `<table>` element, the mediaSingle wrapper) the width matters and must
|
|
30
|
+
* be supplied or the box collapses to 0 wide while contained.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Estimate the rendered height of a table from its row count. Cell padding and cell borders are
|
|
35
|
+
* already folded into `TABLE_ROW_HEIGHT`; the table's block margins are added as a small buffer.
|
|
36
|
+
*/
|
|
37
|
+
export function estimateTableIntrinsicHeight(node) {
|
|
38
|
+
const rows = node.childCount;
|
|
39
|
+
return Math.max(TABLE_MIN_HEIGHT, rows * TABLE_ROW_HEIGHT + TABLE_VERTICAL_MARGIN);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Estimate the rendered height of an expand. A collapsed expand reserves only its header row; an
|
|
44
|
+
* expanded one additionally reserves space for its child blocks. `expanded` is passed in by the
|
|
45
|
+
* caller because the two expand implementations track expanded state differently (a WeakMap in
|
|
46
|
+
* single-player vs the `__expanded` attribute in legacy).
|
|
47
|
+
*/
|
|
48
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
49
|
+
export function estimateExpandIntrinsicHeight(node, expanded) {
|
|
50
|
+
if (!expanded) {
|
|
51
|
+
return EXPAND_HEADER_HEIGHT;
|
|
52
|
+
}
|
|
53
|
+
return EXPAND_HEADER_HEIGHT + node.childCount * BLOCK_HEIGHT + EXPAND_CONTENT_PADDING;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Estimate the rendered width AND height of a mediaSingle. Unlike the structural estimates above,
|
|
58
|
+
* media carries its real dimensions in the ADF: the child `media` node's `width`/`height` attrs
|
|
59
|
+
* give the intrinsic aspect ratio, and the rendered pixel width is computed with the exact same
|
|
60
|
+
* `calcMediaSinglePixelWidth` helper the renderer uses (honouring `width`/`widthType`/`layout` and
|
|
61
|
+
* the editor's content/container width). Height then follows from width × aspect ratio — plus a
|
|
62
|
+
* caption row when present and the mediaSingle's block margins — so this is the most accurate
|
|
63
|
+
* estimate of any node type. The pixel width is returned as the intrinsic width because the
|
|
64
|
+
* mediaSingle wrapper is content-sized. `lineLength` and `containerWidth` come from the width
|
|
65
|
+
* plugin's shared state.
|
|
66
|
+
*/
|
|
67
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
68
|
+
export function estimateMediaSingleIntrinsicSize(node, lineLength, containerWidth) {
|
|
69
|
+
var _media$attrs, _media$attrs2, _node$attrs$width, _ref;
|
|
70
|
+
const media = node.firstChild;
|
|
71
|
+
const origWidth = Number(media === null || media === void 0 ? void 0 : (_media$attrs = media.attrs) === null || _media$attrs === void 0 ? void 0 : _media$attrs.width) || 0;
|
|
72
|
+
const origHeight = Number(media === null || media === void 0 ? void 0 : (_media$attrs2 = media.attrs) === null || _media$attrs2 === void 0 ? void 0 : _media$attrs2.height) || 0;
|
|
73
|
+
const aspectRatio = origWidth && origHeight ? origHeight / origWidth : DEFAULT_MEDIA_ASPECT_RATIO;
|
|
74
|
+
const pixelWidth = calcMediaSinglePixelWidth({
|
|
75
|
+
width: (_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : undefined,
|
|
76
|
+
widthType: node.attrs.widthType,
|
|
77
|
+
origWidth: origWidth || lineLength || containerWidth,
|
|
78
|
+
layout: (_ref = node.attrs.layout) !== null && _ref !== void 0 ? _ref : 'center',
|
|
79
|
+
contentWidth: lineLength || undefined,
|
|
80
|
+
containerWidth: containerWidth || lineLength,
|
|
81
|
+
gutterOffset: MEDIA_SINGLE_GUTTER
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// A caption child (childCount > 1) sits below the media, and the mediaSingle block reserves
|
|
85
|
+
// vertical margin above and below regardless.
|
|
86
|
+
const captionHeight = node.childCount > 1 ? MEDIA_CAPTION_HEIGHT : 0;
|
|
87
|
+
const height = Math.max(MEDIA_SINGLE_MIN_HEIGHT, Math.round(pixelWidth * aspectRatio) + captionHeight + MEDIA_SINGLE_VERTICAL_MARGIN);
|
|
88
|
+
return {
|
|
89
|
+
width: Math.round(pixelWidth),
|
|
90
|
+
height
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Produce a single-axis `contain-intrinsic-width`/`-height` value using the `auto` keyword so the
|
|
96
|
+
* browser remembers the element's real size after its first render and only uses the estimate
|
|
97
|
+
* beforehand.
|
|
98
|
+
*/
|
|
99
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
100
|
+
export function formatIntrinsicSize(px) {
|
|
101
|
+
return `auto ${Math.round(px)}px`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The `content-visibility` / `contain-intrinsic-*` styles applied to an eligible node. Width and
|
|
106
|
+
* height are kept as separate `contain-intrinsic-width`/`-height` axes rather than the
|
|
107
|
+
* `contain-intrinsic-size` shorthand: the shorthand's single value is applied to BOTH axes, which
|
|
108
|
+
* forces a wrong width on content-sized boxes (e.g. a 500px-tall `<table>` would reserve 500px
|
|
109
|
+
* wide). `containIntrinsicWidth` is omitted for block-level wrappers whose width comes from layout.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Resolve the `content-visibility` styles for a node, or `undefined` when the optimisation should
|
|
114
|
+
* not apply.
|
|
115
|
+
*
|
|
116
|
+
* Gating is delegated to limited mode: `limitedModeEnabled` should come from the limited-mode
|
|
117
|
+
* plugin's shared state, so this feature shares a single "large document" definition with limited
|
|
118
|
+
* mode rather than a bespoke threshold. The optimisation applies only when the feature gate is on
|
|
119
|
+
* AND limited mode is active.
|
|
120
|
+
*
|
|
121
|
+
* The intrinsic size is supplied lazily via `getIntrinsicSize` so callers can compute a
|
|
122
|
+
* per-instance estimate from the node's structure, and is only evaluated when actually applied.
|
|
123
|
+
*/
|
|
124
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
125
|
+
export function getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize) {
|
|
126
|
+
if (!limitedModeEnabled || !isExperimentEnabled('cc_editor_limited_mode_perf_improvements')) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const {
|
|
130
|
+
width,
|
|
131
|
+
height
|
|
132
|
+
} = getIntrinsicSize();
|
|
133
|
+
return {
|
|
134
|
+
contentVisibility: 'auto',
|
|
135
|
+
containIntrinsicHeight: formatIntrinsicSize(height),
|
|
136
|
+
...(width !== undefined ? {
|
|
137
|
+
containIntrinsicWidth: formatIntrinsicSize(width)
|
|
138
|
+
} : {})
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Imperatively apply the `content-visibility: auto` rendering optimisation to a node's top-level
|
|
144
|
+
* DOM element (for use in raw-DOM nodeViews), but only when both the feature gate is on and limited
|
|
145
|
+
* mode is active (see `getContentVisibilityStyle`).
|
|
146
|
+
*
|
|
147
|
+
* The intrinsic size uses the `auto` keyword so any initial inaccuracy self-corrects once the
|
|
148
|
+
* element has been rendered once. Safe to call repeatedly (e.g. on expand/collapse toggle) — it
|
|
149
|
+
* simply re-applies or, when ineligible, leaves the element untouched.
|
|
150
|
+
*/
|
|
151
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
152
|
+
export function applyContentVisibility(dom, limitedModeEnabled, getIntrinsicSize) {
|
|
153
|
+
var _style$containIntrins;
|
|
154
|
+
const style = getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize);
|
|
155
|
+
if (!style) {
|
|
156
|
+
dom.style.contentVisibility = '';
|
|
157
|
+
dom.style.containIntrinsicHeight = '';
|
|
158
|
+
dom.style.containIntrinsicWidth = '';
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
dom.style.contentVisibility = style.contentVisibility;
|
|
162
|
+
dom.style.containIntrinsicHeight = style.containIntrinsicHeight;
|
|
163
|
+
dom.style.containIntrinsicWidth = (_style$containIntrins = style.containIntrinsicWidth) !== null && _style$containIntrins !== void 0 ? _style$containIntrins : '';
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
@@ -16,9 +16,12 @@ import React, { Fragment, useEffect, useRef, useState } from 'react';
|
|
|
16
16
|
import { css, jsx } from '@emotion/react';
|
|
17
17
|
import { bind } from 'bind-event-listener';
|
|
18
18
|
import classnames from 'classnames';
|
|
19
|
+
import { useIntl } from 'react-intl';
|
|
19
20
|
import EditorFileIcon from '@atlaskit/icon/core/file';
|
|
21
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
20
22
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
21
23
|
import { useSharedPluginStateWithSelector } from '../../hooks';
|
|
24
|
+
import { placeholderTextMessages } from '../../messages/placeholder-text';
|
|
22
25
|
import { removeMarginsAndBorder, sharedMultiBodiedExtensionStyles } from '../../ui/MultiBodiedExtension';
|
|
23
26
|
import { calculateBreakoutStyles, getExtensionLozengeData } from '../../utils';
|
|
24
27
|
import ExtensionLozenge from '../Extension/Lozenge';
|
|
@@ -38,6 +41,20 @@ var getContainerCssExtendedStyles = function getContainerCssExtendedStyles(activ
|
|
|
38
41
|
showMacroInteractionDesignUpdates && removeMarginsAndBorder)))
|
|
39
42
|
);
|
|
40
43
|
};
|
|
44
|
+
|
|
45
|
+
// Renders a visual placeholder when the active frame contains a single empty paragraph.
|
|
46
|
+
var getEmptyFramePlaceholderStyles = function getEmptyFramePlaceholderStyles(activeChildIndex, placeholderText) {
|
|
47
|
+
return css(_defineProperty({}, "& .multiBodiedExtension-content-dom-wrapper > [data-extension-frame='true']:nth-of-type(".concat(activeChildIndex + 1
|
|
48
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
49
|
+
, ") > p:only-child:has(.ProseMirror-trailingBreak:only-child)::before"), {
|
|
50
|
+
color: "var(--ds-text-subtlest, #6B6E76)",
|
|
51
|
+
// JSON.stringify produces a quoted and escaped CSS string.
|
|
52
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
|
53
|
+
content: placeholderText,
|
|
54
|
+
pointerEvents: 'none',
|
|
55
|
+
position: 'absolute'
|
|
56
|
+
}));
|
|
57
|
+
};
|
|
41
58
|
var imageStyles = css({
|
|
42
59
|
maxHeight: '24px',
|
|
43
60
|
maxWidth: '24px'
|
|
@@ -182,6 +199,8 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
182
199
|
node: node,
|
|
183
200
|
type: 'image'
|
|
184
201
|
});
|
|
202
|
+
var _useIntl = useIntl(),
|
|
203
|
+
formatMessage = _useIntl.formatMessage;
|
|
185
204
|
var _useState3 = useState(0),
|
|
186
205
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
187
206
|
activeChildIndex = _useState4[0],
|
|
@@ -235,6 +254,10 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
235
254
|
mbeWrapperStyles = breakoutStyles;
|
|
236
255
|
}
|
|
237
256
|
var shouldUseUpdatedChrome = expValEquals('confluence_native_tabs_experiment', 'isEnabled', true);
|
|
257
|
+
var shouldShowEmptyFramePlaceholder = isExperimentEnabled('confluence_native_tabs_m15');
|
|
258
|
+
var emptyFramePlaceholderText = React.useMemo(function () {
|
|
259
|
+
return JSON.stringify(formatMessage(placeholderTextMessages.multiBodiedExtensionEmptyFramePlaceholderText));
|
|
260
|
+
}, [formatMessage]);
|
|
238
261
|
var isSelectionInsideMultiBodiedExtension = useIsSelectionInsideNode(editorView, node, getPos, shouldUseUpdatedChrome && !isLivePageViewMode);
|
|
239
262
|
var isMultiBodiedExtensionActive = isNodeSelected || isSelectionInsideMultiBodiedExtension;
|
|
240
263
|
var shouldShowChromeOnInteraction = isNodeHovered || isMultiBodiedExtensionActive;
|
|
@@ -308,10 +331,10 @@ var MultiBodiedExtensionWithWidth = function MultiBodiedExtensionWithWidth(_ref2
|
|
|
308
331
|
"data-testid": "multiBodiedExtension--overlay"
|
|
309
332
|
}), getWrapperTitleContent(imageData, title, showMacroInteractionDesignUpdates), jsx("div", {
|
|
310
333
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
311
|
-
className: containerClassNames
|
|
312
|
-
|
|
313
|
-
,
|
|
314
|
-
css
|
|
334
|
+
className: containerClassNames,
|
|
335
|
+
css: [/* eslint-disable @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766 */
|
|
336
|
+
getContainerCssExtendedStyles(activeChildIndex, showMacroInteractionDesignUpdates), shouldShowEmptyFramePlaceholder && getEmptyFramePlaceholderStyles(activeChildIndex, emptyFramePlaceholderText)
|
|
337
|
+
/* eslint-enable @atlaskit/design-system/consistent-css-prop-usage */],
|
|
315
338
|
"data-testid": "multiBodiedExtension--container",
|
|
316
339
|
"data-multiBodiedExtension-container": true,
|
|
317
340
|
"data-active-child-index": activeChildIndex
|
|
@@ -44,5 +44,10 @@ export var placeholderTextMessages = defineMessages({
|
|
|
44
44
|
id: 'fabric.editor.sourceSyncBlockPlaceholderText',
|
|
45
45
|
defaultMessage: 'Add content you want to reuse. Copy and paste this block to sync in other locations.',
|
|
46
46
|
description: 'Placeholder text shown inside an empty source sync block, prompting users to add reusable content that can be synced across multiple locations.'
|
|
47
|
+
},
|
|
48
|
+
multiBodiedExtensionEmptyFramePlaceholderText: {
|
|
49
|
+
id: 'fabric.editor.multiBodiedExtensionEmptyFramePlaceholderText',
|
|
50
|
+
defaultMessage: 'Type to add content or press / to insert elements',
|
|
51
|
+
description: 'Placeholder text shown inside an empty multi-bodied extension frame, prompting users to type content or use slash commands to insert elements.'
|
|
47
52
|
}
|
|
48
53
|
});
|
|
@@ -20,7 +20,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
20
20
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
21
21
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
22
22
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
23
|
-
var packageVersion = "118.10.
|
|
23
|
+
var packageVersion = "118.10.3";
|
|
24
24
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
25
25
|
// Remove URL as it has UGC
|
|
26
26
|
// Ignored via go/ees007
|
|
@@ -49,7 +49,7 @@ var firstNodeWithNotMarginTop = function firstNodeWithNotMarginTop() {
|
|
|
49
49
|
var tableSharedStyle = function tableSharedStyle() {
|
|
50
50
|
var browser = getBrowserInfo();
|
|
51
51
|
// eslint-disable-next-line @atlaskit/design-system/no-css-tagged-template-expression -- Appears safe to auto-fix, but leaving it up to the team to remediate as the readability only gets worse with autofixing
|
|
52
|
-
return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n\t\t", "\n\t\t.", " {\n\t\t\tposition: relative;\n\t\t\tmargin: 0 auto ", ";\n\t\t\tbox-sizing: border-box;\n\n\t\t\t/**\n\t\t\t * Fix block top alignment inside table cells.\n\t\t\t */\n\t\t\t.decisionItemView-content-wrap:first-of-type > div {\n\t\t\t\tmargin-top: 0;\n\t\t\t}\n\t\t\t", "\n\t\t}\n\t\t.", "[data-number-column='true'] {\n\t\t\tpadding-left: ", "px;\n\t\t\tclear: both;\n\t\t}\n\n\t\t.", " {\n\t\t\twill-change: width, margin-left;\n\t\t}\n\n\t\t.", " table {\n\t\t\twill-change: width;\n\t\t}\n\t\t.", " > table {\n\t\t\tmargin: ", " 0 0 0;\n\t\t}\n\n\t\t.", " > table,\n\t\t.", " > table {\n\t\t\tmargin: ", " ", " 0 0;\n\t\t}\n\n\t\t/* support panel nested in table */\n\t\t", "\n\n\t\t/* avoid applying styles to nested tables (possible via extensions) */\n\t.", " > table,\n\t.", " > table,\n\t.", " > table {\n\t\t\tborder-collapse: collapse;\n\t\t\t", "\n\t\t\ttable-layout: fixed;\n\t\t\tfont-size: 1em;\n\t\t\twidth: 100%;\n\t\t\t", "\n\n\t\t\t&[data-autosize='true'] {\n\t\t\t\ttable-layout: auto;\n\t\t\t}\n\n\t\t\t& {\n\t\t\t\t* {\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t}\n\t\t\t\thr {\n\t\t\t\t\tbox-sizing: content-box;\n\t\t\t\t}\n\n\t\t\t\ttbody {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t\tth td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th,\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tmin-width: ", "px;\n\t\t\t\t\tfont-weight: ", ";\n\t\t\t\t\tvertical-align: top;\n\t\t\t\t\t", "\n\t\t\t\t\tborder: 1px solid ", ";\n\t\t\t\t\tborder-right-width: 0;\n\t\t\t\t\tborder-bottom-width: 0;\n\n\t\t\t\t\tpadding: ", ";\n\t\t\t\t\t/* https://stackoverflow.com/questions/7517127/borders-not-shown-in-firefox-with-border-collapse-on-table-position-relative-o */\n\t\t\t\t\t", "\n\n\t\t\t\t\t", "\n\n\t\t\t\tth p:not(:first-of-type),\n\t\t\t\ttd p:not(:first-of-type) {\n\t\t\t\t\t\tmargin-top: ", ";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Ensures nested tables are compatible with parent table background color - uses specificity to ensure tables nested by extensions are not affected */\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t", "\n\t\t\t\tth {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\ttext-align: left;\n\n\t\t\t\t\t/* only apply this styling to codeblocks in default background headercells */\n\t\t\t\t\t/* TODO this needs to be overhauled as it relies on unsafe selectors */\n\t\t\t\t\t", " {\n\t\t\t\t\t\t.", ":not(.danger) {\n\t\t\t\t\t\t\tbackground-color: ", ";\n\n\t\t\t\t\t\t\t:not(.", ") {\n\t\t\t\t\t\t\t\tbox-shadow: 0px 0px 0px 1px ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-image: ", ";\n\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/* this is only relevant to the element taken care of by renderer */\n\t\t\t\t\t\t\t> [data-ds--code--code-block] {\n\t\t\t\t\t\t\t\tbackground-image: ", "!important;\n\n\t\t\t\t\t\t\t\tbackground-color: ", "!important;\n\n\t\t\t\t\t\t\t\t/* selector lives inside @atlaskit/code */\n\t\t\t\t\t\t\t\t--ds--code--line-number-bg-color: ", ";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t", "\n\t"])), tableCellBackgroundStyleOverride(), TableSharedCssClassName.TABLE_CONTAINER, "var(--ds-space-200, 16px)", expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Fake side borders are not needed when the rounded overlay owns the outer border. */\n\t\t\t\t.".concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\t\t\t\t\t") : ".".concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tdisplay: block;\n\t\t\t\twidth: 1px;\n\t\t\t\theight: calc(100% - ", "var(--ds-space-300, 24px)", ");\n\t\t\t\tbackground: ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: ", "var(--ds-space-300, 24px)", ";\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, " {\n\t\t\t\tright: 0;\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tleft: 0;\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, "[data-with-numbered-table='true'] {\n\t\t\t\tleft: ").concat(akEditorTableNumberColumnWidth - 1, "px;\n\t\t\t}"), TableSharedCssClassName.TABLE_CONTAINER, akEditorTableNumberColumnWidth - 1, TableSharedCssClassName.TABLE_RESIZER_CONTAINER, TableSharedCssClassName.TABLE_RESIZER_CONTAINER, TableSharedCssClassName.TABLE_NODE_WRAPPER, "var(--ds-space-300, 24px)", TableSharedCssClassName.TABLE_CONTAINER, TableSharedCssClassName.TABLE_STICKY_WRAPPER, "var(--ds-space-300, 24px)", "var(--ds-space-100, 8px)", fg('platform_editor_bordered_panel_nested_in_table') ? ".".concat(TableSharedCssClassName.TABLE_NODE_WRAPPER, " .ak-editor-panel {\n\t\t\tborder: ", "var(--ds-border-width, 1px)", " solid ", "var(--ds-border, #0B120E24)", ";\n\t\t}") : '', TableSharedCssClassName.TABLE_CONTAINER, TableSharedCssClassName.TABLE_NODE_WRAPPER, TableSharedCssClassName.TABLE_STICKY_WRAPPER, expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Keep a transparent border so the collapsed border model reserves the same 1px slot\n\t\t\t on the table edge; the ::after overlay draws the visible rounded border instead. */\n\t\t\tborder: ".concat(tableCellBorderWidth, "px solid transparent;") : "border: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\tborder-left-color: transparent;\n\t\t\tborder-right-color: transparent;"), expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "position: relative;\n\n\t\t\t/* Table-width outer-border owner for overflow-safe rounded corners. */\n\t\t\t&::after {\n\t\t\t\tcontent: '';\n\t\t\t\tposition: absolute;\n\t\t\t\tinset: -0.5px;\n\t\t\t\tborder: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tborder-radius: ", "var(--ds-radius-xlarge, 12px)", ";\n\t\t\t\tpointer-events: none;\n\t\t\t\tz-index: 1;\n\t\t\t}") : '', "var(--ds-background-neutral-subtle, #00000000)", tableCellMinWidth, "var(--ds-font-weight-regular, 400)", expValEqualsNoExposure('platform_editor_table_menu_updates', 'isEnabled', true) ? "&[data-valign='middle'] {\n\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t&[data-valign='bottom'] {\n\t\t\t\t\t\t\t\tvertical-align: bottom;\n\t\t\t\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtler, #DDDEE1)", "var(--ds-space-100, 8px)", browser.gecko || browser.ie || browser.mac && browser.chrome ? 'background-clip: padding-box;' : '', firstNodeWithNotMarginTop(), "var(--ds-space-150, 12px)", "var(--ds-surface, #FFFFFF)", expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Let the wrapper overlay own the outer table perimeter.\n\t\t\t\t data-reaches-* attributes are set by the TableCell node view. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top] {\n\t\t\t\t\tborder-top-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th[data-reaches-left],\n\t\t\t\t> tbody > tr > td[data-reaches-left] {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-left]::after {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-bottom]::after,\n\t\t\t\t> tbody > tr > th[data-reaches-bottom]::after {\n\t\t\t\t\tborder-bottom-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t/* The rounded-table overlay owns transparent perimeter borders.\n\t\t\t\t Paint edge cell backgrounds into that reserved border area so coloured\n\t\t\t\t first/last rows do not show the page background through 1px seams. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top],\n\t\t\t\t> tbody > tr > th[data-reaches-bottom],\n\t\t\t\t> tbody > tr > td[data-reaches-bottom] {\n\t\t\t\t\tbackground-clip: border-box;\n\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtlest, #F0F1F2)", expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? '&:not(.danger)' : '&:not([style]):not(.danger)', CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, "var(--ds-surface-raised, #FFFFFF)", akEditorSelectedNodeClassName, "var(--ds-border, #0B120E24)", CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER, overflowShadow({
|
|
52
|
+
return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n\t\t", "\n\t\t.", " {\n\t\t\tposition: relative;\n\t\t\tmargin: 0 auto ", ";\n\t\t\tbox-sizing: border-box;\n\n\t\t\t/**\n\t\t\t * Fix block top alignment inside table cells.\n\t\t\t */\n\t\t\t.decisionItemView-content-wrap:first-of-type > div {\n\t\t\t\tmargin-top: 0;\n\t\t\t}\n\t\t\t", "\n\t\t}\n\t\t.", "[data-number-column='true'] {\n\t\t\tpadding-left: ", "px;\n\t\t\tclear: both;\n\t\t}\n\n\t\t.", " {\n\t\t\twill-change: width, margin-left;\n\t\t}\n\n\t\t.", " table {\n\t\t\twill-change: width;\n\t\t}\n\t\t.", " > table {\n\t\t\tmargin: ", " 0 0 0;\n\t\t}\n\n\t\t.", " > table,\n\t\t.", " > table {\n\t\t\tmargin: ", " ", " 0 0;\n\t\t}\n\n\t\t/* support panel nested in table */\n\t\t", "\n\n\t\t/* avoid applying styles to nested tables (possible via extensions) */\n\t.", " > table,\n\t.", " > table,\n\t.", " > table {\n\t\t\tborder-collapse: collapse;\n\t\t\t", "\n\t\t\ttable-layout: fixed;\n\t\t\tfont-size: 1em;\n\t\t\twidth: 100%;\n\t\t\t", "\n\n\t\t\t&[data-autosize='true'] {\n\t\t\t\ttable-layout: auto;\n\t\t\t}\n\n\t\t\t& {\n\t\t\t\t* {\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t}\n\t\t\t\thr {\n\t\t\t\t\tbox-sizing: content-box;\n\t\t\t\t}\n\n\t\t\t\ttbody {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t\tth td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th,\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tmin-width: ", "px;\n\t\t\t\t\tfont-weight: ", ";\n\t\t\t\t\tvertical-align: top;\n\t\t\t\t\t", "\n\t\t\t\t\tborder: 1px solid ", ";\n\t\t\t\t\tborder-right-width: 0;\n\t\t\t\t\tborder-bottom-width: 0;\n\n\t\t\t\t\tpadding: ", ";\n\t\t\t\t\t/* https://stackoverflow.com/questions/7517127/borders-not-shown-in-firefox-with-border-collapse-on-table-position-relative-o */\n\t\t\t\t\t", "\n\n\t\t\t\t\t", "\n\n\t\t\t\tth p:not(:first-of-type),\n\t\t\t\ttd p:not(:first-of-type) {\n\t\t\t\t\t\tmargin-top: ", ";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Ensures nested tables are compatible with parent table background color - uses specificity to ensure tables nested by extensions are not affected */\n\t\t\t\t> tbody > tr > td {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t}\n\n\t\t\t\t", "\n\t\t\t\tth {\n\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\ttext-align: left;\n\n\t\t\t\t\t/* only apply this styling to codeblocks in default background headercells */\n\t\t\t\t\t/* TODO this needs to be overhauled as it relies on unsafe selectors */\n\t\t\t\t\t", " {\n\t\t\t\t\t\t.", ":not(.danger) {\n\t\t\t\t\t\t\tbackground-color: ", ";\n\n\t\t\t\t\t\t\t:not(.", ") {\n\t\t\t\t\t\t\t\tbox-shadow: 0px 0px 0px 1px ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-image: ", ";\n\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t.", " {\n\t\t\t\t\t\t\t\tbackground-color: ", ";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t/* this is only relevant to the element taken care of by renderer */\n\t\t\t\t\t\t\t> [data-ds--code--code-block] {\n\t\t\t\t\t\t\t\tbackground-image: ", "!important;\n\n\t\t\t\t\t\t\t\tbackground-color: ", "!important;\n\n\t\t\t\t\t\t\t\t/* selector lives inside @atlaskit/code */\n\t\t\t\t\t\t\t\t--ds--code--line-number-bg-color: ", ";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t", "\n\t"])), tableCellBackgroundStyleOverride(), TableSharedCssClassName.TABLE_CONTAINER, "var(--ds-space-200, 16px)", expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Fake side borders are not needed when the rounded overlay owns the outer border. */\n\t\t\t\t.".concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\t\tdisplay: none;\n\t\t\t\t}\n\t\t\t\t\t") : ".".concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, ",\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tdisplay: block;\n\t\t\t\twidth: 1px;\n\t\t\t\theight: calc(100% - ", "var(--ds-space-300, 24px)", ");\n\t\t\t\tbackground: ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tposition: absolute;\n\t\t\t\ttop: ", "var(--ds-space-300, 24px)", ";\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_RIGHT_BORDER, " {\n\t\t\t\tright: 0;\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, " {\n\t\t\t\tleft: 0;\n\t\t\t}\n\t\t\t.").concat(TableSharedCssClassName.TABLE_LEFT_BORDER, "[data-with-numbered-table='true'] {\n\t\t\t\tleft: ").concat(akEditorTableNumberColumnWidth - 1, "px;\n\t\t\t}"), TableSharedCssClassName.TABLE_CONTAINER, akEditorTableNumberColumnWidth - 1, TableSharedCssClassName.TABLE_RESIZER_CONTAINER, TableSharedCssClassName.TABLE_RESIZER_CONTAINER, TableSharedCssClassName.TABLE_NODE_WRAPPER, "var(--ds-space-300, 24px)", TableSharedCssClassName.TABLE_CONTAINER, TableSharedCssClassName.TABLE_STICKY_WRAPPER, "var(--ds-space-300, 24px)", "var(--ds-space-100, 8px)", fg('platform_editor_bordered_panel_nested_in_table') ? ".".concat(TableSharedCssClassName.TABLE_NODE_WRAPPER, " .ak-editor-panel {\n\t\t\tborder: ", "var(--ds-border-width, 1px)", " solid ", "var(--ds-border, #0B120E24)", ";\n\t\t}") : '', TableSharedCssClassName.TABLE_CONTAINER, TableSharedCssClassName.TABLE_NODE_WRAPPER, TableSharedCssClassName.TABLE_STICKY_WRAPPER, expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Keep a transparent border so the collapsed border model reserves the same 1px slot\n\t\t\t on the table edge; the ::after overlay draws the visible rounded border instead. */\n\t\t\tborder: ".concat(tableCellBorderWidth, "px solid transparent;") : "border: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\tborder-left-color: transparent;\n\t\t\tborder-right-color: transparent;"), expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "position: relative;\n\n\t\t\t/* Table-width outer-border owner for overflow-safe rounded corners. */\n\t\t\t&::after {\n\t\t\t\tcontent: '';\n\t\t\t\tposition: absolute;\n\t\t\t\tinset: -0.5px;\n\t\t\t\tborder: ".concat(tableCellBorderWidth, "px solid ", "var(--ds-background-accent-gray-subtler, #DDDEE1)", ";\n\t\t\t\tborder-radius: ", "var(--ds-radius-xlarge, 12px)", ";\n\t\t\t\tpointer-events: none;\n\t\t\t\tz-index: 1;\n\t\t\t}\n\n\t\t\t/* When content-visibility is applied to the table (see editor-plugin-table nodeview), the\n\t\t\t implied `contain: paint` clips descendant painting to the table's border-box. The\n\t\t\t overlay above sits at `inset: -0.5px` (half a pixel outside), so it would be shaved \u2014\n\t\t\t most visibly along the bottom. Pull it flush to the edge so it paints inside the clip. */\n\t\t\t&[data-content-visibility]::after {\n\t\t\t\tinset: 0;\n\t\t\t}") : '', "var(--ds-background-neutral-subtle, #00000000)", tableCellMinWidth, "var(--ds-font-weight-regular, 400)", expValEqualsNoExposure('platform_editor_table_menu_updates', 'isEnabled', true) ? "&[data-valign='middle'] {\n\t\t\t\t\t\t\t\tvertical-align: middle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t&[data-valign='bottom'] {\n\t\t\t\t\t\t\t\tvertical-align: bottom;\n\t\t\t\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtler, #DDDEE1)", "var(--ds-space-100, 8px)", browser.gecko || browser.ie || browser.mac && browser.chrome ? 'background-clip: padding-box;' : '', firstNodeWithNotMarginTop(), "var(--ds-space-150, 12px)", "var(--ds-surface, #FFFFFF)", expValEquals('platform_editor_table_q4_loveability', 'isEnabled', true) ? "/* Let the wrapper overlay own the outer table perimeter.\n\t\t\t\t data-reaches-* attributes are set by the TableCell node view. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top] {\n\t\t\t\t\tborder-top-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > th[data-reaches-left],\n\t\t\t\t> tbody > tr > td[data-reaches-left] {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-left]::after {\n\t\t\t\t\tborder-left-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t> tbody > tr > td[data-reaches-bottom]::after,\n\t\t\t\t> tbody > tr > th[data-reaches-bottom]::after {\n\t\t\t\t\tborder-bottom-color: transparent;\n\t\t\t\t}\n\n\t\t\t\t/* The rounded-table overlay owns transparent perimeter borders.\n\t\t\t\t Paint edge cell backgrounds into that reserved border area so coloured\n\t\t\t\t first/last rows do not show the page background through 1px seams. */\n\t\t\t\t> tbody > tr > th[data-reaches-top],\n\t\t\t\t> tbody > tr > td[data-reaches-top],\n\t\t\t\t> tbody > tr > th[data-reaches-bottom],\n\t\t\t\t> tbody > tr > td[data-reaches-bottom] {\n\t\t\t\t\tbackground-clip: border-box;\n\t\t\t\t}" : '', "var(--ds-background-accent-gray-subtlest, #F0F1F2)", expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? '&:not(.danger)' : '&:not([style]):not(.danger)', CodeBlockSharedCssClassName.CODEBLOCK_CONTAINER, "var(--ds-surface-raised, #FFFFFF)", akEditorSelectedNodeClassName, "var(--ds-border, #0B120E24)", CodeBlockSharedCssClassName.CODEBLOCK_CONTENT_WRAPPER, overflowShadow({
|
|
53
53
|
leftCoverWidth: "var(--ds-space-300, 24px)"
|
|
54
54
|
}), "var(--ds-background-neutral, #0515240F)", CodeBlockSharedCssClassName.CODEBLOCK_LINE_NUMBER_GUTTER, "var(--ds-background-neutral, #0515240F)", overflowShadow({
|
|
55
55
|
leftCoverWidth: "var(--ds-space-300, 24px)"
|
|
@@ -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 = "118.10.
|
|
24
|
+
var packageVersion = "118.10.3";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
5
|
+
import { calcMediaSinglePixelWidth } from '../media-single/utils';
|
|
6
|
+
|
|
7
|
+
// Rough per-node rendered-size constants (px), grounded in the real style defaults from
|
|
8
|
+
// `styles/shared/table.ts`, `EditorContentContainer/styles/expandStyles.ts` and
|
|
9
|
+
// `EditorContentContainer/styles/layout.ts`. These only need to be a decent first estimate: the
|
|
10
|
+
// `auto` keyword in `contain-intrinsic-*: auto <estimate>` makes the browser remember each
|
|
11
|
+
// element's real size after its first render, so any inaccuracy self-corrects on scroll. Where the
|
|
12
|
+
// estimate can't be exact we intentionally err slightly HIGH — over-reserving leaves a marginally
|
|
13
|
+
// long scrollbar that shrinks on scroll, whereas under-reserving makes content jump upward.
|
|
14
|
+
var TABLE_ROW_HEIGHT = 44; // row content: line-height + cell padding (space.100 ×2) + cell border
|
|
15
|
+
var TABLE_VERTICAL_MARGIN = 40; // tableMarginTop(24) + tableMarginBottom(16)
|
|
16
|
+
var TABLE_MIN_HEIGHT = 120;
|
|
17
|
+
var BLOCK_HEIGHT = 28; // a typical paragraph/block line + spacing
|
|
18
|
+
|
|
19
|
+
var EXPAND_HEADER_HEIGHT = 48; // min-height:25 + padding + margin of the title row
|
|
20
|
+
var EXPAND_CONTENT_PADDING = 8; // space.100 padding-top when expanded
|
|
21
|
+
|
|
22
|
+
var MEDIA_SINGLE_MIN_HEIGHT = 100;
|
|
23
|
+
var MEDIA_SINGLE_GUTTER = 12; // MEDIA_SINGLE_GUTTER_SIZE — gap between resizer handle and media
|
|
24
|
+
var MEDIA_SINGLE_VERTICAL_MARGIN = 24; // rich-media-item margin: space.150 top + bottom
|
|
25
|
+
var MEDIA_CAPTION_HEIGHT = 32; // caption line-height + vertical padding, when a caption is present
|
|
26
|
+
var DEFAULT_MEDIA_ASPECT_RATIO = 9 / 16; // used only when the media has no intrinsic dimensions
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The intrinsic size a nodeView reserves while off-screen (`contain-intrinsic-width`/`-height`).
|
|
30
|
+
* `width` is optional: for block-level wrappers (expand, layout) the inline size comes from the
|
|
31
|
+
* containing block regardless of size containment, so only `height` is meaningful; for
|
|
32
|
+
* content-sized boxes (the `<table>` element, the mediaSingle wrapper) the width matters and must
|
|
33
|
+
* be supplied or the box collapses to 0 wide while contained.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Estimate the rendered height of a table from its row count. Cell padding and cell borders are
|
|
38
|
+
* already folded into `TABLE_ROW_HEIGHT`; the table's block margins are added as a small buffer.
|
|
39
|
+
*/
|
|
40
|
+
export function estimateTableIntrinsicHeight(node) {
|
|
41
|
+
var rows = node.childCount;
|
|
42
|
+
return Math.max(TABLE_MIN_HEIGHT, rows * TABLE_ROW_HEIGHT + TABLE_VERTICAL_MARGIN);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Estimate the rendered height of an expand. A collapsed expand reserves only its header row; an
|
|
47
|
+
* expanded one additionally reserves space for its child blocks. `expanded` is passed in by the
|
|
48
|
+
* caller because the two expand implementations track expanded state differently (a WeakMap in
|
|
49
|
+
* single-player vs the `__expanded` attribute in legacy).
|
|
50
|
+
*/
|
|
51
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
52
|
+
export function estimateExpandIntrinsicHeight(node, expanded) {
|
|
53
|
+
if (!expanded) {
|
|
54
|
+
return EXPAND_HEADER_HEIGHT;
|
|
55
|
+
}
|
|
56
|
+
return EXPAND_HEADER_HEIGHT + node.childCount * BLOCK_HEIGHT + EXPAND_CONTENT_PADDING;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Estimate the rendered width AND height of a mediaSingle. Unlike the structural estimates above,
|
|
61
|
+
* media carries its real dimensions in the ADF: the child `media` node's `width`/`height` attrs
|
|
62
|
+
* give the intrinsic aspect ratio, and the rendered pixel width is computed with the exact same
|
|
63
|
+
* `calcMediaSinglePixelWidth` helper the renderer uses (honouring `width`/`widthType`/`layout` and
|
|
64
|
+
* the editor's content/container width). Height then follows from width × aspect ratio — plus a
|
|
65
|
+
* caption row when present and the mediaSingle's block margins — so this is the most accurate
|
|
66
|
+
* estimate of any node type. The pixel width is returned as the intrinsic width because the
|
|
67
|
+
* mediaSingle wrapper is content-sized. `lineLength` and `containerWidth` come from the width
|
|
68
|
+
* plugin's shared state.
|
|
69
|
+
*/
|
|
70
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
71
|
+
export function estimateMediaSingleIntrinsicSize(node, lineLength, containerWidth) {
|
|
72
|
+
var _media$attrs, _media$attrs2, _node$attrs$width, _ref;
|
|
73
|
+
var media = node.firstChild;
|
|
74
|
+
var origWidth = Number(media === null || media === void 0 || (_media$attrs = media.attrs) === null || _media$attrs === void 0 ? void 0 : _media$attrs.width) || 0;
|
|
75
|
+
var origHeight = Number(media === null || media === void 0 || (_media$attrs2 = media.attrs) === null || _media$attrs2 === void 0 ? void 0 : _media$attrs2.height) || 0;
|
|
76
|
+
var aspectRatio = origWidth && origHeight ? origHeight / origWidth : DEFAULT_MEDIA_ASPECT_RATIO;
|
|
77
|
+
var pixelWidth = calcMediaSinglePixelWidth({
|
|
78
|
+
width: (_node$attrs$width = node.attrs.width) !== null && _node$attrs$width !== void 0 ? _node$attrs$width : undefined,
|
|
79
|
+
widthType: node.attrs.widthType,
|
|
80
|
+
origWidth: origWidth || lineLength || containerWidth,
|
|
81
|
+
layout: (_ref = node.attrs.layout) !== null && _ref !== void 0 ? _ref : 'center',
|
|
82
|
+
contentWidth: lineLength || undefined,
|
|
83
|
+
containerWidth: containerWidth || lineLength,
|
|
84
|
+
gutterOffset: MEDIA_SINGLE_GUTTER
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// A caption child (childCount > 1) sits below the media, and the mediaSingle block reserves
|
|
88
|
+
// vertical margin above and below regardless.
|
|
89
|
+
var captionHeight = node.childCount > 1 ? MEDIA_CAPTION_HEIGHT : 0;
|
|
90
|
+
var height = Math.max(MEDIA_SINGLE_MIN_HEIGHT, Math.round(pixelWidth * aspectRatio) + captionHeight + MEDIA_SINGLE_VERTICAL_MARGIN);
|
|
91
|
+
return {
|
|
92
|
+
width: Math.round(pixelWidth),
|
|
93
|
+
height: height
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Produce a single-axis `contain-intrinsic-width`/`-height` value using the `auto` keyword so the
|
|
99
|
+
* browser remembers the element's real size after its first render and only uses the estimate
|
|
100
|
+
* beforehand.
|
|
101
|
+
*/
|
|
102
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
103
|
+
export function formatIntrinsicSize(px) {
|
|
104
|
+
return "auto ".concat(Math.round(px), "px");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* The `content-visibility` / `contain-intrinsic-*` styles applied to an eligible node. Width and
|
|
109
|
+
* height are kept as separate `contain-intrinsic-width`/`-height` axes rather than the
|
|
110
|
+
* `contain-intrinsic-size` shorthand: the shorthand's single value is applied to BOTH axes, which
|
|
111
|
+
* forces a wrong width on content-sized boxes (e.g. a 500px-tall `<table>` would reserve 500px
|
|
112
|
+
* wide). `containIntrinsicWidth` is omitted for block-level wrappers whose width comes from layout.
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Resolve the `content-visibility` styles for a node, or `undefined` when the optimisation should
|
|
117
|
+
* not apply.
|
|
118
|
+
*
|
|
119
|
+
* Gating is delegated to limited mode: `limitedModeEnabled` should come from the limited-mode
|
|
120
|
+
* plugin's shared state, so this feature shares a single "large document" definition with limited
|
|
121
|
+
* mode rather than a bespoke threshold. The optimisation applies only when the feature gate is on
|
|
122
|
+
* AND limited mode is active.
|
|
123
|
+
*
|
|
124
|
+
* The intrinsic size is supplied lazily via `getIntrinsicSize` so callers can compute a
|
|
125
|
+
* per-instance estimate from the node's structure, and is only evaluated when actually applied.
|
|
126
|
+
*/
|
|
127
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
128
|
+
export function getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize) {
|
|
129
|
+
if (!limitedModeEnabled || !isExperimentEnabled('cc_editor_limited_mode_perf_improvements')) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
var _getIntrinsicSize = getIntrinsicSize(),
|
|
133
|
+
width = _getIntrinsicSize.width,
|
|
134
|
+
height = _getIntrinsicSize.height;
|
|
135
|
+
return _objectSpread({
|
|
136
|
+
contentVisibility: 'auto',
|
|
137
|
+
containIntrinsicHeight: formatIntrinsicSize(height)
|
|
138
|
+
}, width !== undefined ? {
|
|
139
|
+
containIntrinsicWidth: formatIntrinsicSize(width)
|
|
140
|
+
} : {});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Imperatively apply the `content-visibility: auto` rendering optimisation to a node's top-level
|
|
145
|
+
* DOM element (for use in raw-DOM nodeViews), but only when both the feature gate is on and limited
|
|
146
|
+
* mode is active (see `getContentVisibilityStyle`).
|
|
147
|
+
*
|
|
148
|
+
* The intrinsic size uses the `auto` keyword so any initial inaccuracy self-corrects once the
|
|
149
|
+
* element has been rendered once. Safe to call repeatedly (e.g. on expand/collapse toggle) — it
|
|
150
|
+
* simply re-applies or, when ineligible, leaves the element untouched.
|
|
151
|
+
*/
|
|
152
|
+
// eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
|
|
153
|
+
export function applyContentVisibility(dom, limitedModeEnabled, getIntrinsicSize) {
|
|
154
|
+
var _style$containIntrins;
|
|
155
|
+
var style = getContentVisibilityStyle(limitedModeEnabled, getIntrinsicSize);
|
|
156
|
+
if (!style) {
|
|
157
|
+
dom.style.contentVisibility = '';
|
|
158
|
+
dom.style.containIntrinsicHeight = '';
|
|
159
|
+
dom.style.containIntrinsicWidth = '';
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
dom.style.contentVisibility = style.contentVisibility;
|
|
163
|
+
dom.style.containIntrinsicHeight = style.containIntrinsicHeight;
|
|
164
|
+
dom.style.containIntrinsicWidth = (_style$containIntrins = style.containIntrinsicWidth) !== null && _style$containIntrins !== void 0 ? _style$containIntrins : '';
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
@@ -1,47 +1,52 @@
|
|
|
1
1
|
export declare const placeholderTextMessages: {
|
|
2
|
-
|
|
3
|
-
id: string;
|
|
2
|
+
longEmptyNodePlaceholderADFPrefix: {
|
|
4
3
|
defaultMessage: string;
|
|
5
4
|
description: string;
|
|
6
|
-
};
|
|
7
|
-
shortEmptyNodePlaceholderText: {
|
|
8
5
|
id: string;
|
|
9
|
-
defaultMessage: string;
|
|
10
|
-
description: string;
|
|
11
6
|
};
|
|
12
|
-
|
|
13
|
-
id: string;
|
|
7
|
+
longEmptyNodePlaceholderADFSlashShortcut: {
|
|
14
8
|
defaultMessage: string;
|
|
15
9
|
description: string;
|
|
16
|
-
};
|
|
17
|
-
shortEmptyNodePlaceholderADFSuffix: {
|
|
18
10
|
id: string;
|
|
11
|
+
};
|
|
12
|
+
longEmptyNodePlaceholderADFSuffix: {
|
|
19
13
|
defaultMessage: string;
|
|
20
14
|
description: string;
|
|
15
|
+
id: string;
|
|
21
16
|
};
|
|
22
17
|
longEmptyNodePlaceholderText: {
|
|
23
|
-
id: string;
|
|
24
18
|
defaultMessage: string;
|
|
25
19
|
description: string;
|
|
26
|
-
};
|
|
27
|
-
longEmptyNodePlaceholderADFPrefix: {
|
|
28
20
|
id: string;
|
|
21
|
+
};
|
|
22
|
+
multiBodiedExtensionEmptyFramePlaceholderText: {
|
|
29
23
|
defaultMessage: string;
|
|
30
24
|
description: string;
|
|
25
|
+
id: string;
|
|
31
26
|
};
|
|
32
|
-
|
|
27
|
+
placeholderTextPlaceholder: {
|
|
28
|
+
defaultMessage: string;
|
|
29
|
+
description: string;
|
|
33
30
|
id: string;
|
|
31
|
+
};
|
|
32
|
+
shortEmptyNodePlaceholderADFSlashShortcut: {
|
|
34
33
|
defaultMessage: string;
|
|
35
34
|
description: string;
|
|
35
|
+
id: string;
|
|
36
36
|
};
|
|
37
|
-
|
|
37
|
+
shortEmptyNodePlaceholderADFSuffix: {
|
|
38
|
+
defaultMessage: string;
|
|
39
|
+
description: string;
|
|
38
40
|
id: string;
|
|
41
|
+
};
|
|
42
|
+
shortEmptyNodePlaceholderText: {
|
|
39
43
|
defaultMessage: string;
|
|
40
44
|
description: string;
|
|
45
|
+
id: string;
|
|
41
46
|
};
|
|
42
47
|
sourceSyncBlockPlaceholderText: {
|
|
43
|
-
id: string;
|
|
44
48
|
defaultMessage: string;
|
|
45
49
|
description: string;
|
|
50
|
+
id: string;
|
|
46
51
|
};
|
|
47
52
|
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
/**
|
|
3
|
+
* The intrinsic size a nodeView reserves while off-screen (`contain-intrinsic-width`/`-height`).
|
|
4
|
+
* `width` is optional: for block-level wrappers (expand, layout) the inline size comes from the
|
|
5
|
+
* containing block regardless of size containment, so only `height` is meaningful; for
|
|
6
|
+
* content-sized boxes (the `<table>` element, the mediaSingle wrapper) the width matters and must
|
|
7
|
+
* be supplied or the box collapses to 0 wide while contained.
|
|
8
|
+
*/
|
|
9
|
+
export type IntrinsicSize = {
|
|
10
|
+
height: number;
|
|
11
|
+
width?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Estimate the rendered height of a table from its row count. Cell padding and cell borders are
|
|
15
|
+
* already folded into `TABLE_ROW_HEIGHT`; the table's block margins are added as a small buffer.
|
|
16
|
+
*/
|
|
17
|
+
export declare function estimateTableIntrinsicHeight(node: PMNode): number;
|
|
18
|
+
/**
|
|
19
|
+
* Estimate the rendered height of an expand. A collapsed expand reserves only its header row; an
|
|
20
|
+
* expanded one additionally reserves space for its child blocks. `expanded` is passed in by the
|
|
21
|
+
* caller because the two expand implementations track expanded state differently (a WeakMap in
|
|
22
|
+
* single-player vs the `__expanded` attribute in legacy).
|
|
23
|
+
*/
|
|
24
|
+
export declare function estimateExpandIntrinsicHeight(node: PMNode, expanded: boolean): number;
|
|
25
|
+
/**
|
|
26
|
+
* Estimate the rendered width AND height of a mediaSingle. Unlike the structural estimates above,
|
|
27
|
+
* media carries its real dimensions in the ADF: the child `media` node's `width`/`height` attrs
|
|
28
|
+
* give the intrinsic aspect ratio, and the rendered pixel width is computed with the exact same
|
|
29
|
+
* `calcMediaSinglePixelWidth` helper the renderer uses (honouring `width`/`widthType`/`layout` and
|
|
30
|
+
* the editor's content/container width). Height then follows from width × aspect ratio — plus a
|
|
31
|
+
* caption row when present and the mediaSingle's block margins — so this is the most accurate
|
|
32
|
+
* estimate of any node type. The pixel width is returned as the intrinsic width because the
|
|
33
|
+
* mediaSingle wrapper is content-sized. `lineLength` and `containerWidth` come from the width
|
|
34
|
+
* plugin's shared state.
|
|
35
|
+
*/
|
|
36
|
+
export declare function estimateMediaSingleIntrinsicSize(node: PMNode, lineLength: number, containerWidth: number): IntrinsicSize;
|
|
37
|
+
/**
|
|
38
|
+
* Produce a single-axis `contain-intrinsic-width`/`-height` value using the `auto` keyword so the
|
|
39
|
+
* browser remembers the element's real size after its first render and only uses the estimate
|
|
40
|
+
* beforehand.
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatIntrinsicSize(px: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* The `content-visibility` / `contain-intrinsic-*` styles applied to an eligible node. Width and
|
|
45
|
+
* height are kept as separate `contain-intrinsic-width`/`-height` axes rather than the
|
|
46
|
+
* `contain-intrinsic-size` shorthand: the shorthand's single value is applied to BOTH axes, which
|
|
47
|
+
* forces a wrong width on content-sized boxes (e.g. a 500px-tall `<table>` would reserve 500px
|
|
48
|
+
* wide). `containIntrinsicWidth` is omitted for block-level wrappers whose width comes from layout.
|
|
49
|
+
*/
|
|
50
|
+
type ContentVisibilityStyle = {
|
|
51
|
+
containIntrinsicHeight: string;
|
|
52
|
+
containIntrinsicWidth?: string;
|
|
53
|
+
contentVisibility: 'auto';
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Resolve the `content-visibility` styles for a node, or `undefined` when the optimisation should
|
|
57
|
+
* not apply.
|
|
58
|
+
*
|
|
59
|
+
* Gating is delegated to limited mode: `limitedModeEnabled` should come from the limited-mode
|
|
60
|
+
* plugin's shared state, so this feature shares a single "large document" definition with limited
|
|
61
|
+
* mode rather than a bespoke threshold. The optimisation applies only when the feature gate is on
|
|
62
|
+
* AND limited mode is active.
|
|
63
|
+
*
|
|
64
|
+
* The intrinsic size is supplied lazily via `getIntrinsicSize` so callers can compute a
|
|
65
|
+
* per-instance estimate from the node's structure, and is only evaluated when actually applied.
|
|
66
|
+
*/
|
|
67
|
+
export declare function getContentVisibilityStyle(limitedModeEnabled: boolean, getIntrinsicSize: () => IntrinsicSize): ContentVisibilityStyle | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Imperatively apply the `content-visibility: auto` rendering optimisation to a node's top-level
|
|
70
|
+
* DOM element (for use in raw-DOM nodeViews), but only when both the feature gate is on and limited
|
|
71
|
+
* mode is active (see `getContentVisibilityStyle`).
|
|
72
|
+
*
|
|
73
|
+
* The intrinsic size uses the `auto` keyword so any initial inaccuracy self-corrects once the
|
|
74
|
+
* element has been rendered once. Safe to call repeatedly (e.g. on expand/collapse toggle) — it
|
|
75
|
+
* simply re-applies or, when ineligible, leaves the element untouched.
|
|
76
|
+
*/
|
|
77
|
+
export declare function applyContentVisibility(dom: HTMLElement, limitedModeEnabled: boolean, getIntrinsicSize: () => IntrinsicSize): boolean;
|
|
78
|
+
export {};
|
package/package.json
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/editor-common/utils/content-visibility",
|
|
3
|
+
"main": "../../dist/cjs/utils/content-visibility.js",
|
|
4
|
+
"module": "../../dist/esm/utils/content-visibility.js",
|
|
5
|
+
"module:es2019": "../../dist/es2019/utils/content-visibility.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"**/*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../../dist/types/utils/content-visibility.d.ts"
|
|
10
|
+
}
|