@atlaskit/editor-plugin-layout 11.0.2 → 11.0.4
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 +15 -0
- package/dist/cjs/layoutPlugin.js +18 -16
- package/dist/cjs/nodeviews/index.js +49 -1
- package/dist/cjs/pm-plugins/column-resize-divider.js +25 -7
- package/dist/cjs/pm-plugins/main.js +2 -2
- package/dist/cjs/pm-plugins/resizing.js +29 -4
- package/dist/cjs/ui/LayoutSSRReactContextsProvider.js +34 -0
- package/dist/es2019/layoutPlugin.js +20 -16
- package/dist/es2019/nodeviews/index.js +49 -1
- package/dist/es2019/pm-plugins/column-resize-divider.js +25 -7
- package/dist/es2019/pm-plugins/main.js +2 -2
- package/dist/es2019/pm-plugins/resizing.js +37 -7
- package/dist/es2019/ui/LayoutSSRReactContextsProvider.js +28 -0
- package/dist/esm/layoutPlugin.js +18 -16
- package/dist/esm/nodeviews/index.js +49 -1
- package/dist/esm/pm-plugins/column-resize-divider.js +25 -7
- package/dist/esm/pm-plugins/main.js +2 -2
- package/dist/esm/pm-plugins/resizing.js +29 -4
- package/dist/esm/ui/LayoutSSRReactContextsProvider.js +27 -0
- package/dist/types/nodeviews/index.d.ts +5 -0
- package/dist/types/pm-plugins/column-resize-divider.d.ts +2 -1
- package/dist/types/pm-plugins/main.d.ts +2 -1
- package/dist/types/pm-plugins/resizing.d.ts +2 -1
- package/dist/types/ui/LayoutSSRReactContextsProvider.d.ts +19 -0
- package/dist/types-ts4.5/nodeviews/index.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/column-resize-divider.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
- package/dist/types-ts4.5/pm-plugins/resizing.d.ts +2 -1
- package/dist/types-ts4.5/ui/LayoutSSRReactContextsProvider.d.ts +19 -0
- package/package.json +7 -4
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { bind } from 'bind-event-listener';
|
|
2
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
2
3
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
6
|
import { MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
|
|
5
7
|
|
|
6
8
|
// Class names for the column resize divider widget — must stay in sync with layout.ts in editor-core
|
|
@@ -15,7 +17,7 @@ let dragState = null;
|
|
|
15
17
|
* Dispatches a single undoable ProseMirror transaction to commit the final
|
|
16
18
|
* column widths after a drag completes.
|
|
17
19
|
*/
|
|
18
|
-
const dispatchColumnWidths = (view, sectionPos, leftColIndex, leftWidth, rightWidth) => {
|
|
20
|
+
const dispatchColumnWidths = (view, sectionPos, leftColIndex, leftWidth, rightWidth, editorAnalyticsAPI) => {
|
|
19
21
|
const {
|
|
20
22
|
state
|
|
21
23
|
} = view;
|
|
@@ -47,6 +49,21 @@ const dispatchColumnWidths = (view, sectionPos, leftColIndex, leftWidth, rightWi
|
|
|
47
49
|
tr.replaceWith(sectionPos + 1, sectionPos + sectionNode.nodeSize - 1, Fragment.from(newColumns));
|
|
48
50
|
tr.setMeta('layoutColumnResize', true);
|
|
49
51
|
tr.setMeta('scrollIntoView', false);
|
|
52
|
+
if (fg('platform_editor_layout_resize_analytics')) {
|
|
53
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
54
|
+
action: ACTION.DRAGGED,
|
|
55
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
56
|
+
actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
|
|
57
|
+
attributes: {
|
|
58
|
+
columnCount: sectionNode.childCount,
|
|
59
|
+
leftColumnIndex: leftColIndex,
|
|
60
|
+
leftColumnWidth: Number(leftWidth.toFixed(2)),
|
|
61
|
+
rightColumnWidth: Number(rightWidth.toFixed(2)),
|
|
62
|
+
inputMethod: INPUT_METHOD.DRAG
|
|
63
|
+
},
|
|
64
|
+
eventType: EVENT_TYPE.TRACK
|
|
65
|
+
})(tr);
|
|
66
|
+
}
|
|
50
67
|
view.dispatch(tr);
|
|
51
68
|
};
|
|
52
69
|
|
|
@@ -149,7 +166,8 @@ const onDragEnd = clientX => {
|
|
|
149
166
|
rafId,
|
|
150
167
|
startLeftWidth,
|
|
151
168
|
startRightWidth,
|
|
152
|
-
unbindListeners
|
|
169
|
+
unbindListeners,
|
|
170
|
+
editorAnalyticsAPI
|
|
153
171
|
} = dragState;
|
|
154
172
|
unbindListeners();
|
|
155
173
|
|
|
@@ -173,7 +191,7 @@ const onDragEnd = clientX => {
|
|
|
173
191
|
leftColEl.style.flexBasis = '';
|
|
174
192
|
rightColEl.style.flexBasis = '';
|
|
175
193
|
if (widths && (widths.leftWidth !== startLeftWidth || widths.rightWidth !== startRightWidth)) {
|
|
176
|
-
dispatchColumnWidths(view, sectionPos, leftColIndex, widths.leftWidth, widths.rightWidth);
|
|
194
|
+
dispatchColumnWidths(view, sectionPos, leftColIndex, widths.leftWidth, widths.rightWidth, editorAnalyticsAPI);
|
|
177
195
|
}
|
|
178
196
|
};
|
|
179
197
|
const onDragMouseUp = e => {
|
|
@@ -200,8 +218,7 @@ const onDragCancel = () => {
|
|
|
200
218
|
* column DOM elements for zero-overhead visual feedback (no PM transactions).
|
|
201
219
|
* A single undoable PM transaction is dispatched on mouseup to commit the final widths.
|
|
202
220
|
*/
|
|
203
|
-
const createColumnDividerWidget = (view, sectionPos, columnIndex
|
|
204
|
-
) => {
|
|
221
|
+
const createColumnDividerWidget = (view, sectionPos, columnIndex, editorAnalyticsAPI) => {
|
|
205
222
|
const ownerDoc = view.dom.ownerDocument;
|
|
206
223
|
|
|
207
224
|
// Outer container: wide transparent hit area for easy grabbing, zero flex footprint
|
|
@@ -296,6 +313,7 @@ const createColumnDividerWidget = (view, sectionPos, columnIndex // index of the
|
|
|
296
313
|
const totalGap = childCount > 1 ? computedGap * (childCount - 1) : 0;
|
|
297
314
|
const columnsWidth = sectionRect.width - dividersWidth - totalGap;
|
|
298
315
|
dragState = {
|
|
316
|
+
editorAnalyticsAPI,
|
|
299
317
|
hasDragged: false,
|
|
300
318
|
lastClientX: e.clientX,
|
|
301
319
|
rafId: null,
|
|
@@ -327,7 +345,7 @@ const createColumnDividerWidget = (view, sectionPos, columnIndex // index of the
|
|
|
327
345
|
* Returns ProseMirror Decoration widgets for column dividers between layout columns.
|
|
328
346
|
* Each divider supports drag-to-resize interaction for the adjacent columns.
|
|
329
347
|
*/
|
|
330
|
-
export const getColumnDividerDecorations = (state, view) => {
|
|
348
|
+
export const getColumnDividerDecorations = (state, view, editorAnalyticsAPI) => {
|
|
331
349
|
const decorations = [];
|
|
332
350
|
if (!view) {
|
|
333
351
|
return decorations;
|
|
@@ -344,7 +362,7 @@ export const getColumnDividerDecorations = (state, view) => {
|
|
|
344
362
|
const sectionPos = pos;
|
|
345
363
|
const colIndex = index;
|
|
346
364
|
const widgetPos = pos + offset + 1; // position at the start of this column
|
|
347
|
-
decorations.push(Decoration.widget(widgetPos, () => createColumnDividerWidget(view, sectionPos, colIndex), {
|
|
365
|
+
decorations.push(Decoration.widget(widgetPos, () => createColumnDividerWidget(view, sectionPos, colIndex, editorAnalyticsAPI), {
|
|
348
366
|
side: -1,
|
|
349
367
|
// place before the position
|
|
350
368
|
key: `layout-col-divider-${pos}-${index}`,
|
|
@@ -96,7 +96,7 @@ const handleDeleteLayoutColumn = (state, dispatch) => {
|
|
|
96
96
|
}
|
|
97
97
|
return false;
|
|
98
98
|
};
|
|
99
|
-
export default (options => {
|
|
99
|
+
export default ((options, editorAnalyticsAPI) => {
|
|
100
100
|
// Store a reference to the EditorView so widget decorations can dispatch transactions
|
|
101
101
|
let editorViewRef;
|
|
102
102
|
return new SafePlugin({
|
|
@@ -147,7 +147,7 @@ export default (options => {
|
|
|
147
147
|
const layoutState = pluginKey.getState(state);
|
|
148
148
|
const isLayoutResizingPluginAvailable = layoutResizingPluginKey.get(state) !== undefined;
|
|
149
149
|
if (editorExperiment('advanced_layouts', true) && editorExperiment('platform_editor_layout_column_resize_handle', true) && isLayoutResizingPluginAvailable) {
|
|
150
|
-
const dividerDecorations = getColumnDividerDecorations(state, editorViewRef);
|
|
150
|
+
const dividerDecorations = getColumnDividerDecorations(state, editorViewRef, editorAnalyticsAPI);
|
|
151
151
|
const selectedDecorations = layoutState.pos !== null ? getNodeDecoration(layoutState.pos, state.doc.nodeAt(layoutState.pos)) : [];
|
|
152
152
|
const allDecorations = [...selectedDecorations, ...dividerDecorations];
|
|
153
153
|
if (allDecorations.length > 0) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
|
|
1
2
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
2
3
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
@@ -14,6 +15,28 @@ export const pluginKey = new PluginKey('layoutResizingPlugin');
|
|
|
14
15
|
* (e.g. setting flex-basis to give real-time visual feedback without dispatching
|
|
15
16
|
* PM transactions) are not "corrected" back by ProseMirror's DOM reconciliation.
|
|
16
17
|
*/
|
|
18
|
+
const isLayoutElementLike = element => {
|
|
19
|
+
if (isSSR() && isSSRStreaming()) {
|
|
20
|
+
// In SSR environments, `HTMLElement` is undefined globally so a plain
|
|
21
|
+
// `instanceof HTMLElement` check is always `false`. That makes the
|
|
22
|
+
// `DOMSerializer.renderSpec(...)` result get rejected by the guard below and
|
|
23
|
+
// the NodeView falls back to a bare `<div>`, losing every schema-defined
|
|
24
|
+
// attribute (`data-layout-column`, `style="flex-basis:..."`,
|
|
25
|
+
// `data-column-width`, plus the inner `<div data-layout-content="true">`
|
|
26
|
+
// wrapper) and breaking the layout's flex sizing in SSR output.
|
|
27
|
+
//
|
|
28
|
+
// To unblock SSR streaming without changing CSR semantics, we gate the check:
|
|
29
|
+
// - In SSR (and only when `platform_editor_editor_ssr_streaming` is enabled),
|
|
30
|
+
// use a duck-typed check that mirrors `safe-plugin`'s `isHTMLElement`.
|
|
31
|
+
// - Everywhere else, keep the original `instanceof HTMLElement` check exactly
|
|
32
|
+
// as it was so we don't accidentally widen acceptance in CSR.
|
|
33
|
+
if (element === null || element === undefined) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
return typeof element === 'object' && 'innerHTML' in element && 'style' in element && 'classList' in element;
|
|
37
|
+
}
|
|
38
|
+
return element instanceof HTMLElement;
|
|
39
|
+
};
|
|
17
40
|
class LayoutColumnView {
|
|
18
41
|
constructor(node, view, getPos) {
|
|
19
42
|
// Use the NodeSpec's own toDOM to produce the correct DOM structure and attributes.
|
|
@@ -31,7 +54,7 @@ class LayoutColumnView {
|
|
|
31
54
|
dom,
|
|
32
55
|
contentDOM
|
|
33
56
|
} = DOMSerializer.renderSpec(document, nodeType.spec.toDOM(node));
|
|
34
|
-
if (!(dom
|
|
57
|
+
if (!isLayoutElementLike(dom) || !isLayoutElementLike(contentDOM)) {
|
|
35
58
|
const fallbackDiv = document.createElement('div');
|
|
36
59
|
this.dom = fallbackDiv;
|
|
37
60
|
this.contentDOM = fallbackDiv;
|
|
@@ -56,7 +79,7 @@ class LayoutColumnView {
|
|
|
56
79
|
return mutation.type === 'attributes' && mutation.attributeName === 'style';
|
|
57
80
|
}
|
|
58
81
|
}
|
|
59
|
-
export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher) => new SafePlugin({
|
|
82
|
+
export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher, intl) => new SafePlugin({
|
|
60
83
|
key: pluginKey,
|
|
61
84
|
props: {
|
|
62
85
|
nodeViews: {
|
|
@@ -68,13 +91,20 @@ export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher
|
|
|
68
91
|
portalProviderAPI,
|
|
69
92
|
eventDispatcher,
|
|
70
93
|
pluginInjectionApi,
|
|
71
|
-
options
|
|
94
|
+
options,
|
|
95
|
+
intl
|
|
72
96
|
}).init();
|
|
73
97
|
},
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
98
|
+
// Register the column node view when EITHER:
|
|
99
|
+
// 1. The resize handle experiment is on (its original purpose:
|
|
100
|
+
// suppress style-attribute MutationObserver callbacks during
|
|
101
|
+
// drag, allowing direct flex-basis writes without PM
|
|
102
|
+
// interference).
|
|
103
|
+
// 2. SSR streaming is enabled — the column node view stamps
|
|
104
|
+
// `container-type: inline-size` inline on each column dom so
|
|
105
|
+
// that the SSR-rendered table inside the column constrains
|
|
106
|
+
// its width to the column (see comment in the constructor).
|
|
107
|
+
...(editorExperiment('platform_editor_layout_column_resize_handle', true) || isSSR() && isSSRStreaming() ? {
|
|
78
108
|
layoutColumn: (node, view, getPos) => new LayoutColumnView(node, view, getPos)
|
|
79
109
|
} : {})
|
|
80
110
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { RawIntlProvider } from 'react-intl';
|
|
3
|
+
import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
|
|
4
|
+
/**
|
|
5
|
+
* Wraps the layout section nodeview children with the editor's actual
|
|
6
|
+
* IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
|
|
7
|
+
* descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
|
|
8
|
+
* have a valid intl context and do not throw during the static render pass.
|
|
9
|
+
*
|
|
10
|
+
* Outside of SSR streaming this is a no-op passthrough.
|
|
11
|
+
*
|
|
12
|
+
* Follows the same pattern as `MediaSSRReactContextsProvider` and
|
|
13
|
+
* `SyncBlockSSRReactContextsProvider`.
|
|
14
|
+
*/
|
|
15
|
+
export function LayoutSSRReactContextsProvider({
|
|
16
|
+
children,
|
|
17
|
+
intl
|
|
18
|
+
}) {
|
|
19
|
+
if (!isSSRStreaming() || !isSSR()) {
|
|
20
|
+
return children;
|
|
21
|
+
}
|
|
22
|
+
if (!intl) {
|
|
23
|
+
return children;
|
|
24
|
+
}
|
|
25
|
+
return /*#__PURE__*/React.createElement(RawIntlProvider, {
|
|
26
|
+
value: intl
|
|
27
|
+
}, children);
|
|
28
|
+
}
|
package/dist/esm/layoutPlugin.js
CHANGED
|
@@ -50,7 +50,7 @@ export var selectIntoLayoutSection = function selectIntoLayoutSection(tr) {
|
|
|
50
50
|
return tr;
|
|
51
51
|
};
|
|
52
52
|
export var layoutPlugin = function layoutPlugin(_ref) {
|
|
53
|
-
var _api$
|
|
53
|
+
var _api$analytics2, _api$analytics5;
|
|
54
54
|
var _ref$config = _ref.config,
|
|
55
55
|
options = _ref$config === void 0 ? {} : _ref$config,
|
|
56
56
|
api = _ref.api;
|
|
@@ -98,7 +98,8 @@ export var layoutPlugin = function layoutPlugin(_ref) {
|
|
|
98
98
|
var plugins = [{
|
|
99
99
|
name: 'layout',
|
|
100
100
|
plugin: function plugin() {
|
|
101
|
-
|
|
101
|
+
var _api$analytics;
|
|
102
|
+
return createLayoutPlugin(options, api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions);
|
|
102
103
|
}
|
|
103
104
|
}];
|
|
104
105
|
if ((options.editorAppearance === 'full-page' || options.editorAppearance === 'full-width' || options.editorAppearance === 'max' && editorExperiment('platform_editor_layout_column_resize_handle', true)) && api && editorExperiment('advanced_layouts', true)) {
|
|
@@ -106,15 +107,16 @@ export var layoutPlugin = function layoutPlugin(_ref) {
|
|
|
106
107
|
name: 'layoutResizing',
|
|
107
108
|
plugin: function plugin(_ref2) {
|
|
108
109
|
var portalProviderAPI = _ref2.portalProviderAPI,
|
|
109
|
-
eventDispatcher = _ref2.eventDispatcher
|
|
110
|
-
|
|
110
|
+
eventDispatcher = _ref2.eventDispatcher,
|
|
111
|
+
getIntl = _ref2.getIntl;
|
|
112
|
+
return createLayoutResizingPlugin(options, api, portalProviderAPI, eventDispatcher, getIntl());
|
|
111
113
|
}
|
|
112
114
|
});
|
|
113
115
|
}
|
|
114
116
|
return plugins;
|
|
115
117
|
},
|
|
116
118
|
actions: {
|
|
117
|
-
insertLayoutColumns: insertLayoutColumnsWithAnalytics(api === null || api === void 0 || (_api$
|
|
119
|
+
insertLayoutColumns: insertLayoutColumnsWithAnalytics(api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions)
|
|
118
120
|
},
|
|
119
121
|
pluginsOptions: {
|
|
120
122
|
floatingToolbar: function floatingToolbar(state, intl) {
|
|
@@ -136,8 +138,8 @@ export var layoutPlugin = function layoutPlugin(_ref) {
|
|
|
136
138
|
quickInsert: function quickInsert(_ref3) {
|
|
137
139
|
var formatMessage = _ref3.formatMessage;
|
|
138
140
|
var withInsertLayoutAnalytics = function withInsertLayoutAnalytics(tr, columnCount) {
|
|
139
|
-
var _api$
|
|
140
|
-
api === null || api === void 0 || (_api$
|
|
141
|
+
var _api$analytics3;
|
|
142
|
+
api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || (_api$analytics3 = _api$analytics3.actions) === null || _api$analytics3 === void 0 || _api$analytics3.attachAnalyticsEvent({
|
|
141
143
|
action: ACTION.INSERTED,
|
|
142
144
|
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
143
145
|
actionSubjectId: ACTION_SUBJECT_ID.LAYOUT,
|
|
@@ -333,9 +335,9 @@ export var layoutPlugin = function layoutPlugin(_ref) {
|
|
|
333
335
|
return /*#__PURE__*/React.createElement(IconLayout, null);
|
|
334
336
|
},
|
|
335
337
|
action: function action(insert, state) {
|
|
336
|
-
var _api$
|
|
338
|
+
var _api$analytics4;
|
|
337
339
|
var tr = insert(createDefaultLayoutSection(state));
|
|
338
|
-
api === null || api === void 0 || (_api$
|
|
340
|
+
api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 || (_api$analytics4 = _api$analytics4.actions) === null || _api$analytics4 === void 0 || _api$analytics4.attachAnalyticsEvent({
|
|
339
341
|
action: ACTION.INSERTED,
|
|
340
342
|
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
341
343
|
actionSubjectId: ACTION_SUBJECT_ID.LAYOUT,
|
|
@@ -370,18 +372,18 @@ export var layoutPlugin = function layoutPlugin(_ref) {
|
|
|
370
372
|
return pluginKey.getState(editorState);
|
|
371
373
|
},
|
|
372
374
|
commands: {
|
|
373
|
-
deleteLayoutColumn: deleteLayoutColumn(api === null || api === void 0 || (_api$
|
|
375
|
+
deleteLayoutColumn: deleteLayoutColumn(api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions, api),
|
|
374
376
|
distributeLayoutColumns: function distributeLayoutColumns(options) {
|
|
375
|
-
var _api$
|
|
376
|
-
return _distributeLayoutColumns(api === null || api === void 0 || (_api$
|
|
377
|
+
var _api$analytics6;
|
|
378
|
+
return _distributeLayoutColumns(api === null || api === void 0 || (_api$analytics6 = api.analytics) === null || _api$analytics6 === void 0 ? void 0 : _api$analytics6.actions, api)(options);
|
|
377
379
|
},
|
|
378
380
|
insertLayoutColumn: function insertLayoutColumn(side) {
|
|
379
|
-
var _api$
|
|
380
|
-
return _insertLayoutColumn(side, api === null || api === void 0 || (_api$
|
|
381
|
+
var _api$analytics7;
|
|
382
|
+
return _insertLayoutColumn(side, api === null || api === void 0 || (_api$analytics7 = api.analytics) === null || _api$analytics7 === void 0 ? void 0 : _api$analytics7.actions, api);
|
|
381
383
|
},
|
|
382
384
|
setLayoutColumnValign: function setLayoutColumnValign(valign) {
|
|
383
|
-
var _api$
|
|
384
|
-
return _setLayoutColumnValign(valign, api === null || api === void 0 || (_api$
|
|
385
|
+
var _api$analytics8;
|
|
386
|
+
return _setLayoutColumnValign(valign, api === null || api === void 0 || (_api$analytics8 = api.analytics) === null || _api$analytics8 === void 0 ? void 0 : _api$analytics8.actions, api);
|
|
385
387
|
},
|
|
386
388
|
toggleLayoutColumnMenu: toggleLayoutColumnMenu
|
|
387
389
|
}
|
|
@@ -9,8 +9,9 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
9
9
|
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; }
|
|
10
10
|
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; }
|
|
11
11
|
import React, { useCallback } from 'react';
|
|
12
|
+
import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
|
|
12
13
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
13
|
-
import ReactNodeView from '@atlaskit/editor-common/react-node-view';
|
|
14
|
+
import ReactNodeView, { NodeViewContentHole } from '@atlaskit/editor-common/react-node-view';
|
|
14
15
|
import { BreakoutResizer, ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
|
|
15
16
|
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
|
|
16
17
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
@@ -18,6 +19,7 @@ import { fg } from '@atlaskit/platform-feature-flags';
|
|
|
18
19
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
19
20
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
20
21
|
import { selectIntoLayout } from '../pm-plugins/utils';
|
|
22
|
+
import { LayoutSSRReactContextsProvider } from '../ui/LayoutSSRReactContextsProvider';
|
|
21
23
|
var layoutDynamicFullWidthGuidelineOffset = 16;
|
|
22
24
|
var isEmptyParagraph = function isEmptyParagraph(node) {
|
|
23
25
|
return !!node && node.type.name === 'paragraph' && !node.childCount;
|
|
@@ -131,6 +133,7 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
131
133
|
* @param props.eventDispatcher
|
|
132
134
|
* @param props.pluginInjectionApi
|
|
133
135
|
* @param props.options
|
|
136
|
+
* @param props.intl
|
|
134
137
|
* @example
|
|
135
138
|
*/
|
|
136
139
|
function LayoutSectionView(props) {
|
|
@@ -139,6 +142,7 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
139
142
|
_this = _callSuper(this, LayoutSectionView, [props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props]);
|
|
140
143
|
_this.isEmpty = isEmptyLayout(_this.node);
|
|
141
144
|
_this.options = props.options;
|
|
145
|
+
_this.intl = props.intl;
|
|
142
146
|
return _this;
|
|
143
147
|
}
|
|
144
148
|
|
|
@@ -151,6 +155,13 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
151
155
|
return _createClass(LayoutSectionView, [{
|
|
152
156
|
key: "getContentDOM",
|
|
153
157
|
value: function getContentDOM() {
|
|
158
|
+
// Build the layout DOM via the schema's toDOM spec. This is the same
|
|
159
|
+
// path used in both CSR and SSR — the only SSR-specific concern is
|
|
160
|
+
// re-attaching `contentDOM` (= the `[data-layout-section]` element)
|
|
161
|
+
// after the portal's renderToStaticMarkup + innerHTML write detaches
|
|
162
|
+
// it. We handle that by stamping `data-ssr-content-dom-ref` on the
|
|
163
|
+
// outer container so `ReactNodeView.init()` can find a re-attach
|
|
164
|
+
// target inside `domRef` after the portal write.
|
|
154
165
|
var _ref2 = DOMSerializer.renderSpec(document, toDOM(this.node)),
|
|
155
166
|
container = _ref2.dom,
|
|
156
167
|
contentDOM = _ref2.contentDOM;
|
|
@@ -163,6 +174,20 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
163
174
|
if (fg('platform_editor_adf_with_localid')) {
|
|
164
175
|
this.layoutDOM.setAttribute('data-local-id', this.node.attrs.localId);
|
|
165
176
|
}
|
|
177
|
+
|
|
178
|
+
// SSR streaming re-attach note:
|
|
179
|
+
// In SSR, `init()` appends `container` into `domRef`; the portal's
|
|
180
|
+
// renderToStaticMarkup + innerHTML write then wipes `domRef`,
|
|
181
|
+
// detaching the entire subtree (with PM-serialized children inside
|
|
182
|
+
// `[data-layout-section]`). React's `render()` emits a
|
|
183
|
+
// `<NodeViewContentHole/>` placeholder inside `domRef`; the SSR
|
|
184
|
+
// re-attach logic in `init()` finds it via `[data-ssr-content-dom-ref]`
|
|
185
|
+
// and calls `_handleRef`, which appends `contentDOMWrapper` (the
|
|
186
|
+
// detached `container`) back inside the placeholder. The end result
|
|
187
|
+
// is `domRef > NodeViewContentHole > layout-section-container >
|
|
188
|
+
// [data-layout-section] > [data-layout-column] children` — the
|
|
189
|
+
// layout DOM contract is preserved.
|
|
190
|
+
|
|
166
191
|
return {
|
|
167
192
|
dom: container,
|
|
168
193
|
contentDOM: contentDOM
|
|
@@ -197,6 +222,29 @@ export var LayoutSectionView = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
197
222
|
if (this.layoutDOM) {
|
|
198
223
|
this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
|
|
199
224
|
}
|
|
225
|
+
|
|
226
|
+
// SSR streaming path: render only a `<NodeViewContentHole/>` placeholder
|
|
227
|
+
// so ReactNodeView.init()'s SSR re-attach logic can find the marker
|
|
228
|
+
// (`data-ssr-content-dom-ref`) and re-append the detached
|
|
229
|
+
// contentDOMWrapper — which is the FULL layout structure
|
|
230
|
+
// (`layout-section-container > [data-layout-section] > children`) built
|
|
231
|
+
// in `getContentDOM` via DOMSerializer.renderSpec. This avoids
|
|
232
|
+
// duplicating layout structure between getContentDOM and render(), which
|
|
233
|
+
// previously caused an extra wrapping div between `[data-layout-section]`
|
|
234
|
+
// and the `[data-layout-column]` children and broke the flex layout.
|
|
235
|
+
//
|
|
236
|
+
// The BreakoutResizer is intentionally omitted in SSR — it relies on
|
|
237
|
+
// browser-only APIs and contributes no useful static markup. The
|
|
238
|
+
// LayoutSSRReactContextsProvider wraps the placeholder to inject the
|
|
239
|
+
// editor's IntlShape, defending against any descendants that call
|
|
240
|
+
// `useIntl()` during renderToStaticMarkup.
|
|
241
|
+
if (isSSR() && isSSRStreaming()) {
|
|
242
|
+
return /*#__PURE__*/React.createElement(LayoutSSRReactContextsProvider, {
|
|
243
|
+
intl: this.intl
|
|
244
|
+
}, /*#__PURE__*/React.createElement(NodeViewContentHole, {
|
|
245
|
+
ref: forwardRef
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
200
248
|
if (expValEquals('platform_editor_breakout_resizing', 'isEnabled', true)) {
|
|
201
249
|
return null;
|
|
202
250
|
}
|
|
@@ -2,8 +2,10 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
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
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
4
|
import { bind } from 'bind-event-listener';
|
|
5
|
+
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
6
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
6
7
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
8
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
9
|
import { MIN_LAYOUT_COLUMN_WIDTH_PERCENT } from './consts';
|
|
8
10
|
|
|
9
11
|
// Class names for the column resize divider widget — must stay in sync with layout.ts in editor-core
|
|
@@ -18,7 +20,7 @@ var dragState = null;
|
|
|
18
20
|
* Dispatches a single undoable ProseMirror transaction to commit the final
|
|
19
21
|
* column widths after a drag completes.
|
|
20
22
|
*/
|
|
21
|
-
var dispatchColumnWidths = function dispatchColumnWidths(view, sectionPos, leftColIndex, leftWidth, rightWidth) {
|
|
23
|
+
var dispatchColumnWidths = function dispatchColumnWidths(view, sectionPos, leftColIndex, leftWidth, rightWidth, editorAnalyticsAPI) {
|
|
22
24
|
var state = view.state;
|
|
23
25
|
var sectionNode = state.doc.nodeAt(sectionPos);
|
|
24
26
|
if (!sectionNode) {
|
|
@@ -45,6 +47,21 @@ var dispatchColumnWidths = function dispatchColumnWidths(view, sectionPos, leftC
|
|
|
45
47
|
tr.replaceWith(sectionPos + 1, sectionPos + sectionNode.nodeSize - 1, Fragment.from(newColumns));
|
|
46
48
|
tr.setMeta('layoutColumnResize', true);
|
|
47
49
|
tr.setMeta('scrollIntoView', false);
|
|
50
|
+
if (fg('platform_editor_layout_resize_analytics')) {
|
|
51
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
52
|
+
action: ACTION.DRAGGED,
|
|
53
|
+
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
54
|
+
actionSubjectId: ACTION_SUBJECT_ID.LAYOUT_COLUMN,
|
|
55
|
+
attributes: {
|
|
56
|
+
columnCount: sectionNode.childCount,
|
|
57
|
+
leftColumnIndex: leftColIndex,
|
|
58
|
+
leftColumnWidth: Number(leftWidth.toFixed(2)),
|
|
59
|
+
rightColumnWidth: Number(rightWidth.toFixed(2)),
|
|
60
|
+
inputMethod: INPUT_METHOD.DRAG
|
|
61
|
+
},
|
|
62
|
+
eventType: EVENT_TYPE.TRACK
|
|
63
|
+
})(tr);
|
|
64
|
+
}
|
|
48
65
|
view.dispatch(tr);
|
|
49
66
|
};
|
|
50
67
|
|
|
@@ -146,7 +163,8 @@ var onDragEnd = function onDragEnd(clientX) {
|
|
|
146
163
|
rafId = _dragState2.rafId,
|
|
147
164
|
startLeftWidth = _dragState2.startLeftWidth,
|
|
148
165
|
startRightWidth = _dragState2.startRightWidth,
|
|
149
|
-
unbindListeners = _dragState2.unbindListeners
|
|
166
|
+
unbindListeners = _dragState2.unbindListeners,
|
|
167
|
+
editorAnalyticsAPI = _dragState2.editorAnalyticsAPI;
|
|
150
168
|
unbindListeners();
|
|
151
169
|
|
|
152
170
|
// Cancel any pending rAF so a stale frame doesn't write styles after teardown.
|
|
@@ -169,7 +187,7 @@ var onDragEnd = function onDragEnd(clientX) {
|
|
|
169
187
|
leftColEl.style.flexBasis = '';
|
|
170
188
|
rightColEl.style.flexBasis = '';
|
|
171
189
|
if (widths && (widths.leftWidth !== startLeftWidth || widths.rightWidth !== startRightWidth)) {
|
|
172
|
-
dispatchColumnWidths(view, sectionPos, leftColIndex, widths.leftWidth, widths.rightWidth);
|
|
190
|
+
dispatchColumnWidths(view, sectionPos, leftColIndex, widths.leftWidth, widths.rightWidth, editorAnalyticsAPI);
|
|
173
191
|
}
|
|
174
192
|
};
|
|
175
193
|
var onDragMouseUp = function onDragMouseUp(e) {
|
|
@@ -196,8 +214,7 @@ var onDragCancel = function onDragCancel() {
|
|
|
196
214
|
* column DOM elements for zero-overhead visual feedback (no PM transactions).
|
|
197
215
|
* A single undoable PM transaction is dispatched on mouseup to commit the final widths.
|
|
198
216
|
*/
|
|
199
|
-
var createColumnDividerWidget = function createColumnDividerWidget(view, sectionPos, columnIndex
|
|
200
|
-
) {
|
|
217
|
+
var createColumnDividerWidget = function createColumnDividerWidget(view, sectionPos, columnIndex, editorAnalyticsAPI) {
|
|
201
218
|
var ownerDoc = view.dom.ownerDocument;
|
|
202
219
|
|
|
203
220
|
// Outer container: wide transparent hit area for easy grabbing, zero flex footprint
|
|
@@ -292,6 +309,7 @@ var createColumnDividerWidget = function createColumnDividerWidget(view, section
|
|
|
292
309
|
var totalGap = childCount > 1 ? computedGap * (childCount - 1) : 0;
|
|
293
310
|
var columnsWidth = sectionRect.width - dividersWidth - totalGap;
|
|
294
311
|
dragState = {
|
|
312
|
+
editorAnalyticsAPI: editorAnalyticsAPI,
|
|
295
313
|
hasDragged: false,
|
|
296
314
|
lastClientX: e.clientX,
|
|
297
315
|
rafId: null,
|
|
@@ -323,7 +341,7 @@ var createColumnDividerWidget = function createColumnDividerWidget(view, section
|
|
|
323
341
|
* Returns ProseMirror Decoration widgets for column dividers between layout columns.
|
|
324
342
|
* Each divider supports drag-to-resize interaction for the adjacent columns.
|
|
325
343
|
*/
|
|
326
|
-
export var getColumnDividerDecorations = function getColumnDividerDecorations(state, view) {
|
|
344
|
+
export var getColumnDividerDecorations = function getColumnDividerDecorations(state, view, editorAnalyticsAPI) {
|
|
327
345
|
var decorations = [];
|
|
328
346
|
if (!view) {
|
|
329
347
|
return decorations;
|
|
@@ -339,7 +357,7 @@ export var getColumnDividerDecorations = function getColumnDividerDecorations(st
|
|
|
339
357
|
var colIndex = index;
|
|
340
358
|
var widgetPos = pos + offset + 1; // position at the start of this column
|
|
341
359
|
decorations.push(Decoration.widget(widgetPos, function () {
|
|
342
|
-
return createColumnDividerWidget(view, sectionPos, colIndex);
|
|
360
|
+
return createColumnDividerWidget(view, sectionPos, colIndex, editorAnalyticsAPI);
|
|
343
361
|
}, {
|
|
344
362
|
side: -1,
|
|
345
363
|
// place before the position
|
|
@@ -95,7 +95,7 @@ var handleDeleteLayoutColumn = function handleDeleteLayoutColumn(state, dispatch
|
|
|
95
95
|
}
|
|
96
96
|
return false;
|
|
97
97
|
};
|
|
98
|
-
export default (function (options) {
|
|
98
|
+
export default (function (options, editorAnalyticsAPI) {
|
|
99
99
|
// Store a reference to the EditorView so widget decorations can dispatch transactions
|
|
100
100
|
var editorViewRef;
|
|
101
101
|
return new SafePlugin({
|
|
@@ -145,7 +145,7 @@ export default (function (options) {
|
|
|
145
145
|
var layoutState = pluginKey.getState(state);
|
|
146
146
|
var isLayoutResizingPluginAvailable = layoutResizingPluginKey.get(state) !== undefined;
|
|
147
147
|
if (editorExperiment('advanced_layouts', true) && editorExperiment('platform_editor_layout_column_resize_handle', true) && isLayoutResizingPluginAvailable) {
|
|
148
|
-
var dividerDecorations = getColumnDividerDecorations(state, editorViewRef);
|
|
148
|
+
var dividerDecorations = getColumnDividerDecorations(state, editorViewRef, editorAnalyticsAPI);
|
|
149
149
|
var selectedDecorations = layoutState.pos !== null ? getNodeDecoration(layoutState.pos, state.doc.nodeAt(layoutState.pos)) : [];
|
|
150
150
|
var allDecorations = [].concat(_toConsumableArray(selectedDecorations), _toConsumableArray(dividerDecorations));
|
|
151
151
|
if (allDecorations.length > 0) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
3
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
4
|
+
import _typeof from "@babel/runtime/helpers/typeof";
|
|
4
5
|
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; }
|
|
5
6
|
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; }
|
|
7
|
+
import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
|
|
6
8
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
9
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
8
10
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
@@ -19,6 +21,28 @@ export var pluginKey = new PluginKey('layoutResizingPlugin');
|
|
|
19
21
|
* (e.g. setting flex-basis to give real-time visual feedback without dispatching
|
|
20
22
|
* PM transactions) are not "corrected" back by ProseMirror's DOM reconciliation.
|
|
21
23
|
*/
|
|
24
|
+
var isLayoutElementLike = function isLayoutElementLike(element) {
|
|
25
|
+
if (isSSR() && isSSRStreaming()) {
|
|
26
|
+
// In SSR environments, `HTMLElement` is undefined globally so a plain
|
|
27
|
+
// `instanceof HTMLElement` check is always `false`. That makes the
|
|
28
|
+
// `DOMSerializer.renderSpec(...)` result get rejected by the guard below and
|
|
29
|
+
// the NodeView falls back to a bare `<div>`, losing every schema-defined
|
|
30
|
+
// attribute (`data-layout-column`, `style="flex-basis:..."`,
|
|
31
|
+
// `data-column-width`, plus the inner `<div data-layout-content="true">`
|
|
32
|
+
// wrapper) and breaking the layout's flex sizing in SSR output.
|
|
33
|
+
//
|
|
34
|
+
// To unblock SSR streaming without changing CSR semantics, we gate the check:
|
|
35
|
+
// - In SSR (and only when `platform_editor_editor_ssr_streaming` is enabled),
|
|
36
|
+
// use a duck-typed check that mirrors `safe-plugin`'s `isHTMLElement`.
|
|
37
|
+
// - Everywhere else, keep the original `instanceof HTMLElement` check exactly
|
|
38
|
+
// as it was so we don't accidentally widen acceptance in CSR.
|
|
39
|
+
if (element === null || element === undefined) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return _typeof(element) === 'object' && 'innerHTML' in element && 'style' in element && 'classList' in element;
|
|
43
|
+
}
|
|
44
|
+
return element instanceof HTMLElement;
|
|
45
|
+
};
|
|
22
46
|
var LayoutColumnView = /*#__PURE__*/function () {
|
|
23
47
|
function LayoutColumnView(node, view, getPos) {
|
|
24
48
|
_classCallCheck(this, LayoutColumnView);
|
|
@@ -36,7 +60,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
|
|
|
36
60
|
var _DOMSerializer$render = DOMSerializer.renderSpec(document, nodeType.spec.toDOM(node)),
|
|
37
61
|
dom = _DOMSerializer$render.dom,
|
|
38
62
|
contentDOM = _DOMSerializer$render.contentDOM;
|
|
39
|
-
if (!(dom
|
|
63
|
+
if (!isLayoutElementLike(dom) || !isLayoutElementLike(contentDOM)) {
|
|
40
64
|
var _fallbackDiv = document.createElement('div');
|
|
41
65
|
this.dom = _fallbackDiv;
|
|
42
66
|
this.contentDOM = _fallbackDiv;
|
|
@@ -64,7 +88,7 @@ var LayoutColumnView = /*#__PURE__*/function () {
|
|
|
64
88
|
}
|
|
65
89
|
}]);
|
|
66
90
|
}();
|
|
67
|
-
export default (function (options, pluginInjectionApi, portalProviderAPI, eventDispatcher) {
|
|
91
|
+
export default (function (options, pluginInjectionApi, portalProviderAPI, eventDispatcher, intl) {
|
|
68
92
|
return new SafePlugin({
|
|
69
93
|
key: pluginKey,
|
|
70
94
|
props: {
|
|
@@ -77,10 +101,11 @@ export default (function (options, pluginInjectionApi, portalProviderAPI, eventD
|
|
|
77
101
|
portalProviderAPI: portalProviderAPI,
|
|
78
102
|
eventDispatcher: eventDispatcher,
|
|
79
103
|
pluginInjectionApi: pluginInjectionApi,
|
|
80
|
-
options: options
|
|
104
|
+
options: options,
|
|
105
|
+
intl: intl
|
|
81
106
|
}).init();
|
|
82
107
|
}
|
|
83
|
-
}, editorExperiment('platform_editor_layout_column_resize_handle', true) ? {
|
|
108
|
+
}, editorExperiment('platform_editor_layout_column_resize_handle', true) || isSSR() && isSSRStreaming() ? {
|
|
84
109
|
layoutColumn: function layoutColumn(node, view, getPos) {
|
|
85
110
|
return new LayoutColumnView(node, view, getPos);
|
|
86
111
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { RawIntlProvider } from 'react-intl';
|
|
3
|
+
import { isSSR, isSSRStreaming } from '@atlaskit/editor-common/core-utils';
|
|
4
|
+
/**
|
|
5
|
+
* Wraps the layout section nodeview children with the editor's actual
|
|
6
|
+
* IntlProvider during SSR streaming (renderToStaticMarkup). This ensures any
|
|
7
|
+
* descendants that call `useIntl()` (e.g. `BreakoutResizer`'s ARIA labels)
|
|
8
|
+
* have a valid intl context and do not throw during the static render pass.
|
|
9
|
+
*
|
|
10
|
+
* Outside of SSR streaming this is a no-op passthrough.
|
|
11
|
+
*
|
|
12
|
+
* Follows the same pattern as `MediaSSRReactContextsProvider` and
|
|
13
|
+
* `SyncBlockSSRReactContextsProvider`.
|
|
14
|
+
*/
|
|
15
|
+
export function LayoutSSRReactContextsProvider(_ref) {
|
|
16
|
+
var children = _ref.children,
|
|
17
|
+
intl = _ref.intl;
|
|
18
|
+
if (!isSSRStreaming() || !isSSR()) {
|
|
19
|
+
return children;
|
|
20
|
+
}
|
|
21
|
+
if (!intl) {
|
|
22
|
+
return children;
|
|
23
|
+
}
|
|
24
|
+
return /*#__PURE__*/React.createElement(RawIntlProvider, {
|
|
25
|
+
value: intl
|
|
26
|
+
}, children);
|
|
27
|
+
}
|