@atlaskit/editor-plugin-layout 16.0.7 → 16.0.9

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 CHANGED
@@ -1,5 +1,30 @@
1
1
  # @atlaskit/editor-plugin-layout
2
2
 
3
+ ## 16.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [`ca2fd9cde15a4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ca2fd9cde15a4) -
8
+ Add a vanilla `LayoutSectionView` behind the `platform_editor_vanilla_node_views_phase1`
9
+ experiment.
10
+
11
+ Replaces the `ReactNodeView`-based `LayoutSectionView` with a pure vanilla `NodeView`, eliminating
12
+ the React portal mount (including `<ErrorBoundary>{null}</ErrorBoundary>`) per layout section
13
+ node. It is used on both the client and during SSR streaming, where it also removes the
14
+ `NodeViewContentHole` / `data-ssr-content-dom-ref` re-attach round trip. Requires
15
+ `platform_editor_breakout_resizing` to be fully rolled out.
16
+
17
+ Also extracts `isEmptyLayout` into a shared `nodeviews/utils.ts` (using `isEmptyParagraph` from
18
+ `@atlaskit/editor-common/utils`) to avoid duplication between the two views.
19
+
20
+ - Updated dependencies
21
+
22
+ ## 16.0.8
23
+
24
+ ### Patch Changes
25
+
26
+ - Updated dependencies
27
+
3
28
  ## 16.0.7
4
29
 
5
30
  ### Patch Changes
@@ -19,41 +19,21 @@ var _reactNodeView = _interopRequireWildcard(require("@atlaskit/editor-common/re
19
19
  var _resizer = require("@atlaskit/editor-common/resizer");
20
20
  var _useSharedPluginStateSelector = require("@atlaskit/editor-common/use-shared-plugin-state-selector");
21
21
  var _model = require("@atlaskit/editor-prosemirror/model");
22
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
22
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
23
23
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
24
24
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
25
25
  var _utils = require("../pm-plugins/utils");
26
26
  var _LayoutSSRReactContextsProvider = require("../ui/LayoutSSRReactContextsProvider");
27
+ var _utils2 = require("./utils");
27
28
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
28
29
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
29
30
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
30
31
  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; }
31
32
  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; }
32
33
  var layoutDynamicFullWidthGuidelineOffset = 16;
33
- var isEmptyParagraph = function isEmptyParagraph(node) {
34
- return !!node && node.type.name === 'paragraph' && !node.childCount;
35
- };
36
34
  var isBreakoutAvailable = function isBreakoutAvailable(schema) {
37
35
  return Boolean(schema.marks.breakout);
38
36
  };
39
- var isEmptyLayout = function isEmptyLayout(node) {
40
- if (!node) {
41
- return false;
42
- }
43
- // fast check
44
- // each column should have size 2 from layoutcolumn and 2 from empty paragraph
45
- if (node.content.size / node.childCount !== 4) {
46
- return false;
47
- }
48
- var isEmpty = true;
49
- node.content.forEach(function (maybelayoutColumn) {
50
- if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !isEmptyParagraph(maybelayoutColumn.firstChild)) {
51
- isEmpty = false;
52
- return;
53
- }
54
- });
55
- return isEmpty;
56
- };
57
37
  var selector = function selector(states) {
58
38
  var _states$editorDisable;
59
39
  return {
@@ -123,7 +103,7 @@ var toDOM = function toDOM(node) {
123
103
  class: 'layout-section-container'
124
104
  }, ['div', _objectSpread({
125
105
  'data-layout-section': true
126
- }, (0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid') && {
106
+ }, (0, _fg.fg)('platform_editor_adf_with_localid') && {
127
107
  'data-local-id': node.attrs.localId
128
108
  }), 0]];
129
109
  };
@@ -149,7 +129,7 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
149
129
  var _this;
150
130
  (0, _classCallCheck2.default)(this, LayoutSectionView);
151
131
  _this = _callSuper(this, LayoutSectionView, [props.node, props.view, props.getPos, props.portalProviderAPI, props.eventDispatcher, props]);
152
- _this.isEmpty = isEmptyLayout(_this.node);
132
+ _this.isEmpty = (0, _utils2.isEmptyLayout)(_this.node);
153
133
  _this.options = props.options;
154
134
  _this.intl = props.intl;
155
135
  return _this;
@@ -180,7 +160,7 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
180
160
  this.layoutDOM = container.querySelector('[data-layout-section]');
181
161
  this.layoutDOM.setAttribute('data-column-rule-style', this.node.attrs.columnRuleStyle);
182
162
  this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
183
- if ((0, _platformFeatureFlags.fg)('platform_editor_adf_with_localid')) {
163
+ if ((0, _fg.fg)('platform_editor_adf_with_localid')) {
184
164
  this.layoutDOM.setAttribute('data-local-id', this.node.attrs.localId);
185
165
  }
186
166
 
@@ -227,7 +207,7 @@ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function (_Reac
227
207
  }, {
228
208
  key: "render",
229
209
  value: function render(props, forwardRef) {
230
- this.isEmpty = isEmptyLayout(this.node);
210
+ this.isEmpty = (0, _utils2.isEmptyLayout)(this.node);
231
211
  if (this.layoutDOM) {
232
212
  this.layoutDOM.setAttribute('data-empty-layout', Boolean(this.isEmpty).toString());
233
213
  }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.LayoutSectionView = void 0;
8
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _resizer = require("@atlaskit/editor-common/resizer");
12
+ var _model = require("@atlaskit/editor-prosemirror/model");
13
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
14
+ var _utils = require("./utils");
15
+ 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; }
16
+ 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; }
17
+ var toDOM = function toDOM(node) {
18
+ var _node$attrs$columnRul, _node$attrs$localId;
19
+ return ['div', {
20
+ class: 'layoutSectionView-content-wrap'
21
+ }, ['div', {
22
+ class: 'layout-section-container'
23
+ }, ['div', _objectSpread({
24
+ 'data-layout-section': true,
25
+ // `?? ''` keeps unset attributes out of the DOM as `"null"`, which adf-schema's`parseDOM`
26
+ // reads back as a truthy string.
27
+ 'data-column-rule-style': (_node$attrs$columnRul = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul !== void 0 ? _node$attrs$columnRul : '',
28
+ 'data-empty-layout': String((0, _utils.isEmptyLayout)(node))
29
+ }, (0, _fg.fg)('platform_editor_adf_with_localid') && {
30
+ 'data-local-id': (_node$attrs$localId = node.attrs.localId) !== null && _node$attrs$localId !== void 0 ? _node$attrs$localId : ''
31
+ }), 0]]];
32
+ };
33
+
34
+ /**
35
+ * Requires `platform_editor_breakout_resizing` as well as
36
+ * `platform_editor_vanilla_node_views_phase1`, because it cannot render the
37
+ * React `<BreakoutResizer>` the old view mounts when that experiment is off.
38
+ *
39
+ * Also used for SSR, where it needs no `NodeViewContentHole` /
40
+ * `data-ssr-content-dom-ref` handling — that exists only because the React
41
+ * portal overwrites `container.innerHTML`.
42
+ */
43
+ var LayoutSectionView = exports.LayoutSectionView = /*#__PURE__*/function () {
44
+ function LayoutSectionView(node) {
45
+ (0, _classCallCheck2.default)(this, LayoutSectionView);
46
+ var _ref = _model.DOMSerializer.renderSpec(document, toDOM(node)),
47
+ dom = _ref.dom,
48
+ contentDOM = _ref.contentDOM;
49
+ this.dom = dom;
50
+ this.contentDOM = contentDOM;
51
+ this.node = node;
52
+ }
53
+ return (0, _createClass2.default)(LayoutSectionView, [{
54
+ key: "update",
55
+ value: function update(node) {
56
+ if (node.attrs.columnRuleStyle !== this.node.attrs.columnRuleStyle) {
57
+ var _node$attrs$columnRul2;
58
+ this.contentDOM.setAttribute('data-column-rule-style', (_node$attrs$columnRul2 = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul2 !== void 0 ? _node$attrs$columnRul2 : '');
59
+ }
60
+ var isEmpty = (0, _utils.isEmptyLayout)(node);
61
+ if (isEmpty !== (0, _utils.isEmptyLayout)(this.node)) {
62
+ this.contentDOM.setAttribute('data-empty-layout', String(isEmpty));
63
+ }
64
+ if ((0, _fg.fg)('platform_editor_adf_with_localid') && node.attrs.localId !== this.node.attrs.localId) {
65
+ var _node$attrs$localId2;
66
+ this.contentDOM.setAttribute('data-local-id', (_node$attrs$localId2 = node.attrs.localId) !== null && _node$attrs$localId2 !== void 0 ? _node$attrs$localId2 : '');
67
+ }
68
+ this.node = node;
69
+ return true;
70
+ }
71
+ }, {
72
+ key: "ignoreMutation",
73
+ value: function ignoreMutation(mutation) {
74
+ return (0, _resizer.ignoreResizerMutations)(mutation);
75
+ }
76
+ }]);
77
+ }();
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isEmptyLayout = void 0;
7
+ var _utils = require("@atlaskit/editor-common/utils");
8
+ var isEmptyLayout = exports.isEmptyLayout = function isEmptyLayout(node) {
9
+ if (!node) {
10
+ return false;
11
+ }
12
+ // fast check
13
+ // each column should have size 2 from layoutcolumn and 2 from empty paragraph
14
+ if (node.content.size / node.childCount !== 4) {
15
+ return false;
16
+ }
17
+ var isEmpty = true;
18
+ node.content.forEach(function (maybelayoutColumn) {
19
+ if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !(0, _utils.isEmptyParagraph)(maybelayoutColumn.firstChild)) {
20
+ isEmpty = false;
21
+ }
22
+ });
23
+ return isEmpty;
24
+ };
@@ -13,8 +13,11 @@ var _coreUtils = require("@atlaskit/editor-common/core-utils");
13
13
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
14
14
  var _model = require("@atlaskit/editor-prosemirror/model");
15
15
  var _state = require("@atlaskit/editor-prosemirror/state");
16
+ var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
17
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
16
18
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
17
19
  var _nodeviews = require("../nodeviews");
20
+ var _layoutSectionView = require("../nodeviews/layoutSectionView");
18
21
  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; }
19
22
  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; }
20
23
  var pluginKey = exports.pluginKey = new _state.PluginKey('layoutResizingPlugin');
@@ -100,6 +103,16 @@ var _default = exports.default = function _default(options, pluginInjectionApi,
100
103
  props: {
101
104
  nodeViews: _objectSpread({
102
105
  layoutSection: function layoutSection(node, view, getPos) {
106
+ // Both experiments are required: the vanilla view renders no React, so it
107
+ // cannot mount the <LayoutBreakoutResizer> that LayoutSectionView.render()
108
+ // returns. That resizer is only redundant once
109
+ // `platform_editor_breakout_resizing` is on (render() returns null and
110
+ // breakout resizing is handled by the pragmatic resizer in
111
+ // editor-plugin-breakout). Taking the vanilla path while that experiment is
112
+ // off would silently remove the breakout drag handles.
113
+ if ((0, _expValEquals.expValEquals)('platform_editor_breakout_resizing', 'isEnabled', true) && (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_vanilla_node_views_phase1')) {
114
+ return new _layoutSectionView.LayoutSectionView(node);
115
+ }
103
116
  return new _nodeviews.LayoutSectionView({
104
117
  node: node,
105
118
  view: view,
@@ -5,36 +5,16 @@ import ReactNodeView, { NodeViewContentHole } from '@atlaskit/editor-common/reac
5
5
  import { BreakoutResizer, ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
6
6
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
7
7
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
8
- import { fg } from '@atlaskit/platform-feature-flags';
8
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
9
9
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
10
10
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
11
11
  import { selectIntoLayout } from '../pm-plugins/utils';
12
12
  import { LayoutSSRReactContextsProvider } from '../ui/LayoutSSRReactContextsProvider';
13
+ import { isEmptyLayout } from './utils';
13
14
  const layoutDynamicFullWidthGuidelineOffset = 16;
14
- const isEmptyParagraph = node => {
15
- return !!node && node.type.name === 'paragraph' && !node.childCount;
16
- };
17
15
  const isBreakoutAvailable = schema => {
18
16
  return Boolean(schema.marks.breakout);
19
17
  };
20
- const isEmptyLayout = node => {
21
- if (!node) {
22
- return false;
23
- }
24
- // fast check
25
- // each column should have size 2 from layoutcolumn and 2 from empty paragraph
26
- if (node.content.size / node.childCount !== 4) {
27
- return false;
28
- }
29
- let isEmpty = true;
30
- node.content.forEach(maybelayoutColumn => {
31
- if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !isEmptyParagraph(maybelayoutColumn.firstChild)) {
32
- isEmpty = false;
33
- return;
34
- }
35
- });
36
- return isEmpty;
37
- };
38
18
  const selector = states => {
39
19
  var _states$editorDisable;
40
20
  return {
@@ -0,0 +1,61 @@
1
+ import { ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
2
+ import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
3
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
4
+ import { isEmptyLayout } from './utils';
5
+ const toDOM = node => {
6
+ var _node$attrs$columnRul, _node$attrs$localId;
7
+ return ['div', {
8
+ class: 'layoutSectionView-content-wrap'
9
+ }, ['div', {
10
+ class: 'layout-section-container'
11
+ }, ['div', {
12
+ 'data-layout-section': true,
13
+ // `?? ''` keeps unset attributes out of the DOM as `"null"`, which adf-schema's`parseDOM`
14
+ // reads back as a truthy string.
15
+ 'data-column-rule-style': (_node$attrs$columnRul = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul !== void 0 ? _node$attrs$columnRul : '',
16
+ 'data-empty-layout': String(isEmptyLayout(node)),
17
+ ...(fg('platform_editor_adf_with_localid') && {
18
+ 'data-local-id': (_node$attrs$localId = node.attrs.localId) !== null && _node$attrs$localId !== void 0 ? _node$attrs$localId : ''
19
+ })
20
+ }, 0]]];
21
+ };
22
+
23
+ /**
24
+ * Requires `platform_editor_breakout_resizing` as well as
25
+ * `platform_editor_vanilla_node_views_phase1`, because it cannot render the
26
+ * React `<BreakoutResizer>` the old view mounts when that experiment is off.
27
+ *
28
+ * Also used for SSR, where it needs no `NodeViewContentHole` /
29
+ * `data-ssr-content-dom-ref` handling — that exists only because the React
30
+ * portal overwrites `container.innerHTML`.
31
+ */
32
+ export class LayoutSectionView {
33
+ constructor(node) {
34
+ const {
35
+ dom,
36
+ contentDOM
37
+ } = DOMSerializer.renderSpec(document, toDOM(node));
38
+ this.dom = dom;
39
+ this.contentDOM = contentDOM;
40
+ this.node = node;
41
+ }
42
+ update(node) {
43
+ if (node.attrs.columnRuleStyle !== this.node.attrs.columnRuleStyle) {
44
+ var _node$attrs$columnRul2;
45
+ this.contentDOM.setAttribute('data-column-rule-style', (_node$attrs$columnRul2 = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul2 !== void 0 ? _node$attrs$columnRul2 : '');
46
+ }
47
+ const isEmpty = isEmptyLayout(node);
48
+ if (isEmpty !== isEmptyLayout(this.node)) {
49
+ this.contentDOM.setAttribute('data-empty-layout', String(isEmpty));
50
+ }
51
+ if (fg('platform_editor_adf_with_localid') && node.attrs.localId !== this.node.attrs.localId) {
52
+ var _node$attrs$localId2;
53
+ this.contentDOM.setAttribute('data-local-id', (_node$attrs$localId2 = node.attrs.localId) !== null && _node$attrs$localId2 !== void 0 ? _node$attrs$localId2 : '');
54
+ }
55
+ this.node = node;
56
+ return true;
57
+ }
58
+ ignoreMutation(mutation) {
59
+ return ignoreResizerMutations(mutation);
60
+ }
61
+ }
@@ -0,0 +1,18 @@
1
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
2
+ export const isEmptyLayout = node => {
3
+ if (!node) {
4
+ return false;
5
+ }
6
+ // fast check
7
+ // each column should have size 2 from layoutcolumn and 2 from empty paragraph
8
+ if (node.content.size / node.childCount !== 4) {
9
+ return false;
10
+ }
11
+ let isEmpty = true;
12
+ node.content.forEach(maybelayoutColumn => {
13
+ if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !isEmptyParagraph(maybelayoutColumn.firstChild)) {
14
+ isEmpty = false;
15
+ }
16
+ });
17
+ return isEmpty;
18
+ };
@@ -2,8 +2,11 @@ import { isSSR } from '@atlaskit/editor-common/core-utils';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
3
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
4
4
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
5
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
6
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
7
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
6
8
  import { LayoutSectionView } from '../nodeviews';
9
+ import { LayoutSectionView as LayoutSectionViewVanilla } from '../nodeviews/layoutSectionView';
7
10
  export const pluginKey = new PluginKey('layoutResizingPlugin');
8
11
 
9
12
  /**
@@ -83,6 +86,16 @@ export default ((options, pluginInjectionApi, portalProviderAPI, eventDispatcher
83
86
  props: {
84
87
  nodeViews: {
85
88
  layoutSection: (node, view, getPos) => {
89
+ // Both experiments are required: the vanilla view renders no React, so it
90
+ // cannot mount the <LayoutBreakoutResizer> that LayoutSectionView.render()
91
+ // returns. That resizer is only redundant once
92
+ // `platform_editor_breakout_resizing` is on (render() returns null and
93
+ // breakout resizing is handled by the pragmatic resizer in
94
+ // editor-plugin-breakout). Taking the vanilla path while that experiment is
95
+ // off would silently remove the breakout drag handles.
96
+ if (expValEquals('platform_editor_breakout_resizing', 'isEnabled', true) && isExperimentEnabled('platform_editor_vanilla_node_views_phase1')) {
97
+ return new LayoutSectionViewVanilla(node);
98
+ }
86
99
  return new LayoutSectionView({
87
100
  node,
88
101
  view,
@@ -15,36 +15,16 @@ import ReactNodeView, { NodeViewContentHole } from '@atlaskit/editor-common/reac
15
15
  import { BreakoutResizer, ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
16
16
  import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
17
17
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
18
- import { fg } from '@atlaskit/platform-feature-flags';
18
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
19
19
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
20
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
21
21
  import { selectIntoLayout } from '../pm-plugins/utils';
22
22
  import { LayoutSSRReactContextsProvider } from '../ui/LayoutSSRReactContextsProvider';
23
+ import { isEmptyLayout } from './utils';
23
24
  var layoutDynamicFullWidthGuidelineOffset = 16;
24
- var isEmptyParagraph = function isEmptyParagraph(node) {
25
- return !!node && node.type.name === 'paragraph' && !node.childCount;
26
- };
27
25
  var isBreakoutAvailable = function isBreakoutAvailable(schema) {
28
26
  return Boolean(schema.marks.breakout);
29
27
  };
30
- var isEmptyLayout = function isEmptyLayout(node) {
31
- if (!node) {
32
- return false;
33
- }
34
- // fast check
35
- // each column should have size 2 from layoutcolumn and 2 from empty paragraph
36
- if (node.content.size / node.childCount !== 4) {
37
- return false;
38
- }
39
- var isEmpty = true;
40
- node.content.forEach(function (maybelayoutColumn) {
41
- if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !isEmptyParagraph(maybelayoutColumn.firstChild)) {
42
- isEmpty = false;
43
- return;
44
- }
45
- });
46
- return isEmpty;
47
- };
48
28
  var selector = function selector(states) {
49
29
  var _states$editorDisable;
50
30
  return {
@@ -0,0 +1,70 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ 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
+ 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; }
6
+ import { ignoreResizerMutations } from '@atlaskit/editor-common/resizer';
7
+ import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
8
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
9
+ import { isEmptyLayout } from './utils';
10
+ var toDOM = function toDOM(node) {
11
+ var _node$attrs$columnRul, _node$attrs$localId;
12
+ return ['div', {
13
+ class: 'layoutSectionView-content-wrap'
14
+ }, ['div', {
15
+ class: 'layout-section-container'
16
+ }, ['div', _objectSpread({
17
+ 'data-layout-section': true,
18
+ // `?? ''` keeps unset attributes out of the DOM as `"null"`, which adf-schema's`parseDOM`
19
+ // reads back as a truthy string.
20
+ 'data-column-rule-style': (_node$attrs$columnRul = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul !== void 0 ? _node$attrs$columnRul : '',
21
+ 'data-empty-layout': String(isEmptyLayout(node))
22
+ }, fg('platform_editor_adf_with_localid') && {
23
+ 'data-local-id': (_node$attrs$localId = node.attrs.localId) !== null && _node$attrs$localId !== void 0 ? _node$attrs$localId : ''
24
+ }), 0]]];
25
+ };
26
+
27
+ /**
28
+ * Requires `platform_editor_breakout_resizing` as well as
29
+ * `platform_editor_vanilla_node_views_phase1`, because it cannot render the
30
+ * React `<BreakoutResizer>` the old view mounts when that experiment is off.
31
+ *
32
+ * Also used for SSR, where it needs no `NodeViewContentHole` /
33
+ * `data-ssr-content-dom-ref` handling — that exists only because the React
34
+ * portal overwrites `container.innerHTML`.
35
+ */
36
+ export var LayoutSectionView = /*#__PURE__*/function () {
37
+ function LayoutSectionView(node) {
38
+ _classCallCheck(this, LayoutSectionView);
39
+ var _ref = DOMSerializer.renderSpec(document, toDOM(node)),
40
+ dom = _ref.dom,
41
+ contentDOM = _ref.contentDOM;
42
+ this.dom = dom;
43
+ this.contentDOM = contentDOM;
44
+ this.node = node;
45
+ }
46
+ return _createClass(LayoutSectionView, [{
47
+ key: "update",
48
+ value: function update(node) {
49
+ if (node.attrs.columnRuleStyle !== this.node.attrs.columnRuleStyle) {
50
+ var _node$attrs$columnRul2;
51
+ this.contentDOM.setAttribute('data-column-rule-style', (_node$attrs$columnRul2 = node.attrs.columnRuleStyle) !== null && _node$attrs$columnRul2 !== void 0 ? _node$attrs$columnRul2 : '');
52
+ }
53
+ var isEmpty = isEmptyLayout(node);
54
+ if (isEmpty !== isEmptyLayout(this.node)) {
55
+ this.contentDOM.setAttribute('data-empty-layout', String(isEmpty));
56
+ }
57
+ if (fg('platform_editor_adf_with_localid') && node.attrs.localId !== this.node.attrs.localId) {
58
+ var _node$attrs$localId2;
59
+ this.contentDOM.setAttribute('data-local-id', (_node$attrs$localId2 = node.attrs.localId) !== null && _node$attrs$localId2 !== void 0 ? _node$attrs$localId2 : '');
60
+ }
61
+ this.node = node;
62
+ return true;
63
+ }
64
+ }, {
65
+ key: "ignoreMutation",
66
+ value: function ignoreMutation(mutation) {
67
+ return ignoreResizerMutations(mutation);
68
+ }
69
+ }]);
70
+ }();
@@ -0,0 +1,18 @@
1
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
2
+ export var isEmptyLayout = function isEmptyLayout(node) {
3
+ if (!node) {
4
+ return false;
5
+ }
6
+ // fast check
7
+ // each column should have size 2 from layoutcolumn and 2 from empty paragraph
8
+ if (node.content.size / node.childCount !== 4) {
9
+ return false;
10
+ }
11
+ var isEmpty = true;
12
+ node.content.forEach(function (maybelayoutColumn) {
13
+ if (maybelayoutColumn.type.name !== 'layoutColumn' || maybelayoutColumn.childCount > 1 || !isEmptyParagraph(maybelayoutColumn.firstChild)) {
14
+ isEmpty = false;
15
+ }
16
+ });
17
+ return isEmpty;
18
+ };
@@ -8,8 +8,11 @@ import { isSSR } from '@atlaskit/editor-common/core-utils';
8
8
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
9
9
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
10
10
  import { PluginKey } from '@atlaskit/editor-prosemirror/state';
11
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
12
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
11
13
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
12
14
  import { LayoutSectionView } from '../nodeviews';
15
+ import { LayoutSectionView as LayoutSectionViewVanilla } from '../nodeviews/layoutSectionView';
13
16
  export var pluginKey = new PluginKey('layoutResizingPlugin');
14
17
 
15
18
  /**
@@ -93,6 +96,16 @@ export default (function (options, pluginInjectionApi, portalProviderAPI, eventD
93
96
  props: {
94
97
  nodeViews: _objectSpread({
95
98
  layoutSection: function layoutSection(node, view, getPos) {
99
+ // Both experiments are required: the vanilla view renders no React, so it
100
+ // cannot mount the <LayoutBreakoutResizer> that LayoutSectionView.render()
101
+ // returns. That resizer is only redundant once
102
+ // `platform_editor_breakout_resizing` is on (render() returns null and
103
+ // breakout resizing is handled by the pragmatic resizer in
104
+ // editor-plugin-breakout). Taking the vanilla path while that experiment is
105
+ // off would silently remove the breakout drag handles.
106
+ if (expValEquals('platform_editor_breakout_resizing', 'isEnabled', true) && isExperimentEnabled('platform_editor_vanilla_node_views_phase1')) {
107
+ return new LayoutSectionViewVanilla(node);
108
+ }
96
109
  return new LayoutSectionView({
97
110
  node: node,
98
111
  view: view,
@@ -0,0 +1,22 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ import type { NodeView } from '@atlaskit/editor-prosemirror/view';
3
+ /**
4
+ * Requires `platform_editor_breakout_resizing` as well as
5
+ * `platform_editor_vanilla_node_views_phase1`, because it cannot render the
6
+ * React `<BreakoutResizer>` the old view mounts when that experiment is off.
7
+ *
8
+ * Also used for SSR, where it needs no `NodeViewContentHole` /
9
+ * `data-ssr-content-dom-ref` handling — that exists only because the React
10
+ * portal overwrites `container.innerHTML`.
11
+ */
12
+ export declare class LayoutSectionView implements NodeView {
13
+ dom: HTMLElement;
14
+ contentDOM: HTMLElement;
15
+ private node;
16
+ constructor(node: PMNode);
17
+ update(node: PMNode): boolean;
18
+ ignoreMutation(mutation: MutationRecord | {
19
+ target: Node;
20
+ type: 'selection';
21
+ }): boolean;
22
+ }
@@ -0,0 +1,2 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ export declare const isEmptyLayout: (node?: PMNode) => boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-layout",
3
- "version": "16.0.7",
3
+ "version": "16.0.9",
4
4
  "description": "Layout plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -37,13 +37,13 @@
37
37
  "@atlaskit/editor-plugin-width": "^16.0.0",
38
38
  "@atlaskit/editor-prosemirror": "^8.0.0",
39
39
  "@atlaskit/editor-shared-styles": "^4.0.0",
40
- "@atlaskit/editor-toolbar": "^2.4.0",
40
+ "@atlaskit/editor-toolbar": "^2.5.0",
41
41
  "@atlaskit/editor-ui-control-model": "^2.7.0",
42
42
  "@atlaskit/icon": "^37.4.0",
43
43
  "@atlaskit/icon-lab": "^7.6.0",
44
44
  "@atlaskit/platform-feature-experiments": "^0.3.0",
45
45
  "@atlaskit/platform-feature-flags": "^2.1.0",
46
- "@atlaskit/tmp-editor-statsig": "^152.0.0",
46
+ "@atlaskit/tmp-editor-statsig": "^153.0.0",
47
47
  "@atlaskit/tokens": "^16.7.0",
48
48
  "@babel/runtime": "^7.0.0",
49
49
  "@emotion/react": "^11.7.1",