@atlaskit/editor-plugin-block-controls 17.0.0 → 17.1.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/blockControlsPlugin.js +23 -4
  3. package/dist/cjs/pm-plugins/decorations-drag-handle.js +5 -22
  4. package/dist/cjs/pm-plugins/decorations-quick-insert-button.js +2 -6
  5. package/dist/cjs/ui/block-controls-surface-context.js +60 -0
  6. package/dist/cjs/ui/block-controls-surface.compiled.css +3 -0
  7. package/dist/cjs/ui/block-controls-surface.js +160 -0
  8. package/dist/cjs/ui/quick-insert-button.js +9 -0
  9. package/dist/cjs/ui/utils/get-node-content-element.js +24 -0
  10. package/dist/cjs/ui/utils/get-surface-placement.js +39 -0
  11. package/dist/es2019/blockControlsPlugin.js +28 -4
  12. package/dist/es2019/pm-plugins/decorations-drag-handle.js +5 -22
  13. package/dist/es2019/pm-plugins/decorations-quick-insert-button.js +2 -6
  14. package/dist/es2019/ui/block-controls-surface-context.js +51 -0
  15. package/dist/es2019/ui/block-controls-surface.compiled.css +3 -0
  16. package/dist/es2019/ui/block-controls-surface.js +144 -0
  17. package/dist/es2019/ui/quick-insert-button.js +9 -0
  18. package/dist/es2019/ui/utils/get-node-content-element.js +18 -0
  19. package/dist/es2019/ui/utils/get-surface-placement.js +30 -0
  20. package/dist/esm/blockControlsPlugin.js +23 -4
  21. package/dist/esm/pm-plugins/decorations-drag-handle.js +5 -22
  22. package/dist/esm/pm-plugins/decorations-quick-insert-button.js +2 -6
  23. package/dist/esm/ui/block-controls-surface-context.js +53 -0
  24. package/dist/esm/ui/block-controls-surface.compiled.css +3 -0
  25. package/dist/esm/ui/block-controls-surface.js +151 -0
  26. package/dist/esm/ui/quick-insert-button.js +9 -0
  27. package/dist/esm/ui/utils/get-node-content-element.js +18 -0
  28. package/dist/esm/ui/utils/get-surface-placement.js +32 -0
  29. package/dist/types/blockControlsPluginType.d.ts +3 -1
  30. package/dist/types/ui/block-controls-surface-context.d.ts +4 -0
  31. package/dist/types/ui/block-controls-surface.d.ts +14 -0
  32. package/dist/types/ui/quick-insert-button.d.ts +8 -0
  33. package/dist/types/ui/utils/get-node-content-element.d.ts +1 -0
  34. package/dist/types/ui/utils/get-surface-placement.d.ts +23 -0
  35. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 17.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`5f66a8c3706e3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5f66a8c3706e3) -
8
+ Add the registry-backed Block Controls Quick Insert surface behind
9
+ `platform_editor_block_control_migration`, including typed surface context, cached registry
10
+ lookup, stable left/right surface identities, and experiment-gated Quick Insert registration.
11
+
12
+ ### Patch Changes
13
+
14
+ - [`63734bcc6ac05`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/63734bcc6ac05) -
15
+ Clean up feature gate `platform_editor_fix_widget_destroy`
16
+ - Updated dependencies
17
+
18
+ ## 17.0.1
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 17.0.0
4
25
 
5
26
  ### Patch Changes
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.blockControlsPlugin = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = _interopRequireDefault(require("react"));
10
+ var _surfaceKeys = require("@atlaskit/editor-common/block-controls/surface-keys");
10
11
  var _selection = require("@atlaskit/editor-common/selection");
11
12
  var _toolbarFlagCheck = require("@atlaskit/editor-common/toolbar-flag-check");
12
13
  var _state = require("@atlaskit/editor-prosemirror/state");
@@ -29,6 +30,7 @@ var _pluginKey = require("./pm-plugins/selection-preservation/plugin-key");
29
30
  var _pmPlugin2 = require("./pm-plugins/selection-preservation/pm-plugin");
30
31
  var _expandAndUpdateSelection2 = require("./pm-plugins/utils/expand-and-update-selection");
31
32
  var _getSelection = require("./pm-plugins/utils/getSelection");
33
+ var _blockControlsSurface = require("./ui/block-controls-surface");
32
34
  var _globalStyles = require("./ui/global-styles");
33
35
  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; }
34
36
  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; }
@@ -39,6 +41,19 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
39
41
  var nodeDecorationRegistry = [];
40
42
  var rightSideControlsEnabled = (_config$rightSideCont = config === null || config === void 0 ? void 0 : config.rightSideControlsEnabled) !== null && _config$rightSideCont !== void 0 ? _config$rightSideCont : false;
41
43
  var quickInsertButtonEnabled = (_config$quickInsertBu = config === null || config === void 0 ? void 0 : config.quickInsertButtonEnabled) !== null && _config$quickInsertBu !== void 0 ? _config$quickInsertBu : true;
44
+ var blockControlMigrationEnabled = (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_block_control_migration');
45
+ if (blockControlMigrationEnabled) {
46
+ var _api$uiControlRegistr;
47
+ api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register([_surfaceKeys.BLOCK_CONTROLS_LEFT_SURFACE, _objectSpread(_objectSpread({}, _surfaceKeys.BLOCK_CONTROLS_LEFT_SECTION), {}, {
48
+ parents: [_objectSpread(_objectSpread({}, _surfaceKeys.BLOCK_CONTROLS_LEFT_SURFACE), {}, {
49
+ rank: 100
50
+ })]
51
+ }), _objectSpread(_objectSpread({}, _surfaceKeys.BLOCK_CONTROLS_LEFT_GROUP), {}, {
52
+ parents: [_objectSpread(_objectSpread({}, _surfaceKeys.BLOCK_CONTROLS_LEFT_SECTION), {}, {
53
+ rank: 100
54
+ })]
55
+ })]);
56
+ }
42
57
  return {
43
58
  name: 'blockControls',
44
59
  actions: {
@@ -107,7 +122,7 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
107
122
  plugin: function plugin(_ref2) {
108
123
  var getIntl = _ref2.getIntl,
109
124
  nodeViewPortalProviderAPI = _ref2.nodeViewPortalProviderAPI;
110
- return (0, _main.createPlugin)(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled);
125
+ return (0, _main.createPlugin)(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled && !blockControlMigrationEnabled);
111
126
  }
112
127
  }];
113
128
  if ((0, _experiments.editorExperiment)('platform_editor_controls', 'variant1')) {
@@ -422,10 +437,14 @@ var blockControlsPlugin = exports.blockControlsPlugin = function blockControlsPl
422
437
  }
423
438
  return sharedState;
424
439
  },
425
- contentComponent: function contentComponent() {
426
- return /*#__PURE__*/_react.default.createElement(_globalStyles.GlobalStylesWrapper, {
440
+ contentComponent: function contentComponent(_ref0) {
441
+ var editorView = _ref0.editorView;
442
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_globalStyles.GlobalStylesWrapper, {
427
443
  api: api
428
- });
444
+ }), blockControlMigrationEnabled && editorView && api ? /*#__PURE__*/_react.default.createElement(_blockControlsSurface.BlockControlsSurface, {
445
+ api: api,
446
+ editorView: editorView
447
+ }) : null);
429
448
  }
430
449
  };
431
450
  };
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.findHandleDec = exports.findActiveDragHandleNodeDec = exports.emptyParagraphNodeDecorations = exports.dragHandleDecoration = exports.createActiveDragHandleNodeDecoration = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _react = require("react");
10
- var _bindEventListener = require("bind-event-listener");
11
10
  var _uuid = _interopRequireDefault(require("uuid"));
12
11
  var _view = require("@atlaskit/editor-prosemirror/view");
13
12
  var _fg = require("@atlaskit/platform-feature-flags/fg");
@@ -62,7 +61,6 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
62
61
  anchorRectCache = _ref.anchorRectCache,
63
62
  editorState = _ref.editorState;
64
63
  (0, _decorationsCommon.unmountDecorations)(nodeViewPortalProviderAPI, 'data-blocks-drag-handle-container', 'data-blocks-drag-handle-key');
65
- var unbind;
66
64
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
67
65
  var key = (0, _uuid.default)();
68
66
  var widgetSpec = (0, _experiments.editorExperiment)('platform_editor_breakout_resizing', true) ? {
@@ -75,19 +73,13 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
75
73
  * Exclude 'breakout' on purpose, so the widgets render at the top of the document to avoid z-index issues
76
74
  * Other block marks must be added, otherwise PM will split the DOM elements causing mutations and re-draws
77
75
  */
78
- marks: (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _marks.getMatchingBlockMarks)(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
79
- destroy: function destroy(node) {
80
- unbind && unbind();
81
- }
76
+ marks: (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _marks.getMatchingBlockMarks)(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : []
82
77
  } : {
83
78
  side: -1,
84
79
  type: _decorationsCommon.TYPE_HANDLE_DEC,
85
80
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
86
81
  testid: "".concat(_decorationsCommon.TYPE_HANDLE_DEC, "-").concat((0, _uuid.default)()),
87
- marks: (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _marks.getMatchingBlockMarks)(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
88
- destroy: function destroy(node) {
89
- unbind && unbind();
90
- }
82
+ marks: (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _marks.getMatchingBlockMarks)(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : []
91
83
  };
92
84
  return _view.Decoration.widget(pos, function (view, getPosUnsafe) {
93
85
  var element = document.createElement('span');
@@ -118,18 +110,9 @@ var dragHandleDecoration = exports.dragHandleDecoration = function dragHandleDec
118
110
  * However, the tooltip for nested drag handle is no long working.
119
111
  */
120
112
  if (newPos === undefined || !isTopLevelNode) {
121
- if ((0, _fg.fg)('platform_editor_fix_widget_destroy')) {
122
- element.onmouseover = function (e) {
123
- e.stopPropagation();
124
- };
125
- } else {
126
- unbind = (0, _bindEventListener.bind)(element, {
127
- type: 'mouseover',
128
- listener: function listener(e) {
129
- e.stopPropagation();
130
- }
131
- });
132
- }
113
+ element.onmouseover = function (e) {
114
+ e.stopPropagation();
115
+ };
133
116
  }
134
117
 
135
118
  // There are times when global clear: "both" styles are applied to this decoration causing jumpiness
@@ -64,9 +64,7 @@ var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function
64
64
 
65
65
  marks: (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true) ? (0, _marks.getMatchingBlockMarks)(editorState, rootPos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
66
66
  destroy: function destroy(_) {
67
- if ((0, _fg.fg)('platform_editor_fix_widget_destroy')) {
68
- nodeViewPortalProviderAPI.remove(key);
69
- }
67
+ nodeViewPortalProviderAPI.remove(key);
70
68
  cleanupCallbacks.forEach(function (cb) {
71
69
  cb();
72
70
  });
@@ -75,9 +73,7 @@ var quickInsertButtonDecoration = exports.quickInsertButtonDecoration = function
75
73
  side: -2,
76
74
  type: TYPE_QUICK_INSERT,
77
75
  destroy: function destroy(_) {
78
- if ((0, _fg.fg)('platform_editor_fix_widget_destroy')) {
79
- nodeViewPortalProviderAPI.remove(key);
80
- }
76
+ nodeViewPortalProviderAPI.remove(key);
81
77
  cleanupCallbacks.forEach(function (cb) {
82
78
  cb();
83
79
  });
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createBlockControlsSurfaceContext = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
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
+ 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; }
11
+ var getNodeContext = function getNodeContext(view, pos) {
12
+ var node = view.state.doc.nodeAt(pos);
13
+ if (!node) {
14
+ return undefined;
15
+ }
16
+ var $pos = view.state.doc.resolve(pos);
17
+ var ancestors = [];
18
+ for (var depth = 0; depth <= $pos.depth; depth++) {
19
+ var ancestor = $pos.node(depth);
20
+ ancestors.push({
21
+ depth: depth,
22
+ pos: depth === 0 ? 0 : $pos.before(depth),
23
+ type: {
24
+ name: ancestor.type.name
25
+ }
26
+ });
27
+ }
28
+ return {
29
+ ancestors: ancestors,
30
+ depth: $pos.depth + 1,
31
+ node: node,
32
+ parentType: $pos.parent.type.name,
33
+ pos: pos,
34
+ type: {
35
+ name: node.type.name
36
+ }
37
+ };
38
+ };
39
+ var createBlockControlsSurfaceContext = exports.createBlockControlsSurfaceContext = function createBlockControlsSurfaceContext(view, activeNode) {
40
+ var _activeNode$rootPos, _activeNode$rootNodeT;
41
+ if (!activeNode) {
42
+ return undefined;
43
+ }
44
+ var rootPos = (_activeNode$rootPos = activeNode.rootPos) !== null && _activeNode$rootPos !== void 0 ? _activeNode$rootPos : activeNode.pos;
45
+ var activeNodeContext = getNodeContext(view, activeNode.pos);
46
+ var rootNodeContext = getNodeContext(view, rootPos);
47
+ if (!activeNodeContext || !rootNodeContext) {
48
+ return undefined;
49
+ }
50
+ return {
51
+ activeNode: _objectSpread(_objectSpread({}, activeNodeContext), {}, {
52
+ rootPos: rootPos,
53
+ rootType: {
54
+ name: (_activeNode$rootNodeT = activeNode.rootNodeType) !== null && _activeNode$rootNodeT !== void 0 ? _activeNode$rootNodeT : rootNodeContext.type.name
55
+ }
56
+ }),
57
+ rootNode: rootNodeContext,
58
+ targetNode: rootNodeContext
59
+ };
60
+ };
@@ -0,0 +1,3 @@
1
+ ._1e0c1txw{display:flex}
2
+ ._1pbyb4wl{z-index:100}
3
+ ._kqswstnw{position:absolute}
@@ -0,0 +1,160 @@
1
+ /* block-controls-surface.tsx generated by @compiled/babel-plugin v2.0.0 */
2
+ "use strict";
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.BlockControlsSurface = void 0;
10
+ require("./block-controls-surface.compiled.css");
11
+ var _runtime = require("@compiled/react/runtime");
12
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
13
+ var _react = _interopRequireWildcard(require("react"));
14
+ var _bindEventListener = require("bind-event-listener");
15
+ var _browserApis = require("@atlaskit/browser-apis");
16
+ var _blockControlUiContext = require("@atlaskit/editor-common/block-controls/block-control-ui-context");
17
+ var _surfaceKeys = require("@atlaskit/editor-common/block-controls/surface-keys");
18
+ var _hooks = require("@atlaskit/editor-common/hooks");
19
+ var _surfaceRenderer = require("@atlaskit/editor-ui-control-model/surface-renderer");
20
+ var _types = require("@atlaskit/editor-ui-control-model/types");
21
+ var _decorationsCommon = require("../pm-plugins/decorations-common");
22
+ var _blockControlsSurfaceContext = require("./block-controls-surface-context");
23
+ var _getNodeContentElement = require("./utils/get-node-content-element");
24
+ var _getSurfacePlacement = require("./utils/get-surface-placement");
25
+ var _visibilityContainer = require("./visibility-container");
26
+ 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); }
27
+ var BLOCK_CONTROLS_SURFACE_Z_INDEX = 100;
28
+ var surfaceStyles = null;
29
+ var BlockControlsSurface = exports.BlockControlsSurface = function BlockControlsSurface(_ref) {
30
+ var _api$uiControlRegistr, _api$uiControlRegistr2;
31
+ var api = _ref.api,
32
+ editorView = _ref.editorView;
33
+ var activeNode = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls'], function (states) {
34
+ var _states$blockControls;
35
+ return {
36
+ activeNode: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.activeNode
37
+ };
38
+ }).activeNode;
39
+ var _useState = (0, _react.useState)(),
40
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
41
+ position = _useState2[0],
42
+ setPosition = _useState2[1];
43
+ var animationFrameRef = (0, _react.useRef)(undefined);
44
+ var components = (_api$uiControlRegistr = (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(_surfaceKeys.BLOCK_CONTROLS_LEFT_SURFACE)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
45
+ var blockControlsContext = (0, _react.useMemo)(function () {
46
+ return (0, _blockControlsSurfaceContext.createBlockControlsSurfaceContext)(editorView, activeNode);
47
+ }, [activeNode, editorView]);
48
+ var surfaceContext = (0, _react.useMemo)(function () {
49
+ return blockControlsContext ? (0, _types.createSurfaceContext)(_blockControlUiContext.BLOCK_CONTROL_UI_CONTEXT, blockControlsContext) : undefined;
50
+ }, [blockControlsContext]);
51
+ (0, _react.useLayoutEffect)(function () {
52
+ var _getDocument;
53
+ if (!blockControlsContext) {
54
+ setPosition(undefined);
55
+ return;
56
+ }
57
+ var rootNodeElement = editorView.nodeDOM(blockControlsContext.rootNode.pos);
58
+ var rootElement = rootNodeElement instanceof HTMLElement ? rootNodeElement : rootNodeElement === null || rootNodeElement === void 0 ? void 0 : rootNodeElement.parentElement;
59
+ if (!rootElement) {
60
+ setPosition(undefined);
61
+ return;
62
+ }
63
+ var targetElement = (0, _getNodeContentElement.getNodeContentElement)(rootElement, blockControlsContext.rootNode.type.name);
64
+ var offsetParent = editorView.dom.offsetParent;
65
+ var isDocumentOffsetParent = !offsetParent || offsetParent === ((_getDocument = (0, _browserApis.getDocument)()) === null || _getDocument === void 0 ? void 0 : _getDocument.body);
66
+ var scrollingOffsetParent = offsetParent instanceof HTMLElement && !isDocumentOffsetParent ? offsetParent : undefined;
67
+ var updatePosition = function updatePosition() {
68
+ var _rootElement$getAttri, _scrollingOffsetParen, _scrollingOffsetParen2;
69
+ animationFrameRef.current = undefined;
70
+ if (!rootElement.isConnected || !targetElement.isConnected) {
71
+ setPosition(undefined);
72
+ return;
73
+ }
74
+ var placement = (0, _getSurfacePlacement.getSurfacePlacement)({
75
+ layout: (_rootElement$getAttri = rootElement.getAttribute('layout')) !== null && _rootElement$getAttri !== void 0 ? _rootElement$getAttri : '',
76
+ nodeRect: targetElement.getBoundingClientRect(),
77
+ nodeType: blockControlsContext.rootNode.type.name,
78
+ nodeTypeWithLevel: (0, _decorationsCommon.getNodeTypeWithLevel)(blockControlsContext.rootNode.node),
79
+ parentNodeType: blockControlsContext.rootNode.parentType === 'doc' ? undefined : blockControlsContext.rootNode.parentType
80
+ });
81
+ var offsetParentRect = offsetParent === null || offsetParent === void 0 ? void 0 : offsetParent.getBoundingClientRect();
82
+ var offsetParentScrollTop = (_scrollingOffsetParen = scrollingOffsetParent === null || scrollingOffsetParent === void 0 ? void 0 : scrollingOffsetParent.scrollTop) !== null && _scrollingOffsetParen !== void 0 ? _scrollingOffsetParen : window.scrollY;
83
+ var offsetParentScrollLeft = (_scrollingOffsetParen2 = scrollingOffsetParent === null || scrollingOffsetParent === void 0 ? void 0 : scrollingOffsetParent.scrollLeft) !== null && _scrollingOffsetParen2 !== void 0 ? _scrollingOffsetParen2 : window.scrollX;
84
+ setPosition((0, _getSurfacePlacement.getAbsoluteSurfacePlacement)({
85
+ offsetParentRect: offsetParentRect,
86
+ offsetParentScrollLeft: offsetParentScrollLeft,
87
+ offsetParentScrollTop: offsetParentScrollTop,
88
+ placement: placement
89
+ }));
90
+ };
91
+ var schedulePositionUpdate = function schedulePositionUpdate() {
92
+ if (animationFrameRef.current === undefined) {
93
+ animationFrameRef.current = requestAnimationFrame(updatePosition);
94
+ }
95
+ };
96
+ updatePosition();
97
+ var resizeObserver = new ResizeObserver(schedulePositionUpdate);
98
+ resizeObserver.observe(editorView.dom);
99
+ if (targetElement && targetElement !== editorView.dom) {
100
+ resizeObserver.observe(targetElement);
101
+ }
102
+ if (offsetParent instanceof HTMLElement && offsetParent !== editorView.dom) {
103
+ resizeObserver.observe(offsetParent);
104
+ }
105
+ var unbindWindowResize = (0, _bindEventListener.bind)(window, {
106
+ type: 'resize',
107
+ listener: schedulePositionUpdate
108
+ });
109
+ var unbindWindowScroll = (0, _bindEventListener.bind)(window, {
110
+ type: 'scroll',
111
+ listener: schedulePositionUpdate,
112
+ options: {
113
+ capture: true,
114
+ passive: true
115
+ }
116
+ });
117
+ var visualViewport = window.visualViewport;
118
+ var unbindVisualViewportResize = visualViewport ? (0, _bindEventListener.bind)(visualViewport, {
119
+ type: 'resize',
120
+ listener: schedulePositionUpdate
121
+ }) : undefined;
122
+ var unbindVisualViewportScroll = visualViewport ? (0, _bindEventListener.bind)(visualViewport, {
123
+ type: 'scroll',
124
+ listener: schedulePositionUpdate
125
+ }) : undefined;
126
+ var unbindTransitionEnd = (0, _bindEventListener.bind)(targetElement, {
127
+ type: 'transitionend',
128
+ listener: schedulePositionUpdate
129
+ });
130
+ return function () {
131
+ if (animationFrameRef.current !== undefined) {
132
+ cancelAnimationFrame(animationFrameRef.current);
133
+ animationFrameRef.current = undefined;
134
+ }
135
+ resizeObserver.disconnect();
136
+ unbindWindowResize();
137
+ unbindWindowScroll();
138
+ unbindVisualViewportResize === null || unbindVisualViewportResize === void 0 || unbindVisualViewportResize();
139
+ unbindVisualViewportScroll === null || unbindVisualViewportScroll === void 0 || unbindVisualViewportScroll();
140
+ unbindTransitionEnd();
141
+ };
142
+ }, [blockControlsContext, editorView]);
143
+ if (components.length === 0 || !blockControlsContext || !surfaceContext || !position || !(0, _surfaceRenderer.willSurfaceRender)(components, _surfaceKeys.BLOCK_CONTROLS_LEFT_SURFACE, surfaceContext)) {
144
+ return null;
145
+ }
146
+ return /*#__PURE__*/_react.default.createElement("div", {
147
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Placement is resolved from the active node's runtime DOM geometry.
148
+ style: position,
149
+ "data-testid": "block-controls-left-surface",
150
+ className: (0, _runtime.ax)(["_1e0c1txw _kqswstnw _1pbyb4wl"])
151
+ }, /*#__PURE__*/_react.default.createElement(_visibilityContainer.VisibilityContainer, {
152
+ api: api,
153
+ controlSide: "left",
154
+ shouldUseDisplayContents: true
155
+ }, /*#__PURE__*/_react.default.createElement(_surfaceRenderer.SurfaceRenderer, {
156
+ components: components,
157
+ surface: _surfaceKeys.BLOCK_CONTROLS_LEFT_SURFACE,
158
+ surfaceContext: surfaceContext
159
+ })));
160
+ };
@@ -159,6 +159,15 @@ var getQuickInsertAnchorReference = function getQuickInsertAnchorReference(_ref)
159
159
  }
160
160
  return "anchor(".concat(safeAnchorName, " ").concat(edge, ")");
161
161
  };
162
+
163
+ /**
164
+ * Legacy widget-decoration Quick Insert implementation.
165
+ *
166
+ * Its behavior is intentionally duplicated by the registry-backed control in
167
+ * `editor-plugin-quick-insert`. Remove this implementation when
168
+ * `platform_editor_block_control_migration` is cleaned up; until then this path remains unchanged
169
+ * for users outside the experiment.
170
+ */
162
171
  var TypeAheadControl = exports.TypeAheadControl = function TypeAheadControl(_ref2) {
163
172
  var view = _ref2.view,
164
173
  api = _ref2.api,
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getNodeContentElement = void 0;
7
+ var _styles = require("@atlaskit/editor-common/styles");
8
+ var INNER_CONTAINER_SELECTORS = {
9
+ blockCard: '.datasourceView-content-inner-wrap',
10
+ bodiedExtension: '.extension-container[data-layout]',
11
+ embedCard: '.rich-media-item',
12
+ extension: '.extension-container[data-layout]',
13
+ mediaSingle: ".".concat(_styles.resizerItemClassName),
14
+ multiBodiedExtension: '.extension-container[data-layout]',
15
+ table: ".".concat(_styles.resizerItemClassName)
16
+ };
17
+ var getNodeContentElement = exports.getNodeContentElement = function getNodeContentElement(nodeElement, nodeType) {
18
+ var _nodeElement$querySel;
19
+ var selector = INNER_CONTAINER_SELECTORS[nodeType];
20
+ if (!selector) {
21
+ return nodeElement;
22
+ }
23
+ return (_nodeElement$querySel = nodeElement.querySelector(selector)) !== null && _nodeElement$querySel !== void 0 ? _nodeElement$querySel : nodeElement;
24
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getSurfacePlacement = exports.getAbsoluteSurfacePlacement = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _consts = require("../consts");
10
+ 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; }
11
+ 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; }
12
+ var getAbsoluteSurfacePlacement = exports.getAbsoluteSurfacePlacement = function getAbsoluteSurfacePlacement(_ref) {
13
+ var _offsetParentRect$lef, _offsetParentRect$top;
14
+ var offsetParentRect = _ref.offsetParentRect,
15
+ offsetParentScrollLeft = _ref.offsetParentScrollLeft,
16
+ offsetParentScrollTop = _ref.offsetParentScrollTop,
17
+ placement = _ref.placement;
18
+ return _objectSpread(_objectSpread({}, placement), {}, {
19
+ left: placement.left - ((_offsetParentRect$lef = offsetParentRect === null || offsetParentRect === void 0 ? void 0 : offsetParentRect.left) !== null && _offsetParentRect$lef !== void 0 ? _offsetParentRect$lef : 0) + offsetParentScrollLeft,
20
+ top: placement.top - ((_offsetParentRect$top = offsetParentRect === null || offsetParentRect === void 0 ? void 0 : offsetParentRect.top) !== null && _offsetParentRect$top !== void 0 ? _offsetParentRect$top : 0) + offsetParentScrollTop
21
+ });
22
+ };
23
+
24
+ /**
25
+ * Positions the Task 1 left surface beside the legacy drag-handle slot.
26
+ * The surface's own width is handled by the transform, so later controls do not require measuring it.
27
+ */
28
+ var getSurfacePlacement = exports.getSurfacePlacement = function getSurfacePlacement(_ref2) {
29
+ var layout = _ref2.layout,
30
+ nodeRect = _ref2.nodeRect,
31
+ nodeType = _ref2.nodeType,
32
+ nodeTypeWithLevel = _ref2.nodeTypeWithLevel,
33
+ parentNodeType = _ref2.parentNodeType;
34
+ return {
35
+ left: nodeRect.left,
36
+ top: nodeRect.top + (0, _consts.topPositionAdjustment)(nodeTypeWithLevel, layout),
37
+ transform: "translateX(calc(-100% - ".concat((0, _consts.dragHandleGap)(nodeType, parentNodeType) + _consts.QUICK_INSERT_LEFT_OFFSET, "px))")
38
+ };
39
+ };
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { BLOCK_CONTROLS_LEFT_GROUP, BLOCK_CONTROLS_LEFT_SECTION, BLOCK_CONTROLS_LEFT_SURFACE } from '@atlaskit/editor-common/block-controls/surface-keys';
2
3
  import { expandSelectionBounds } from '@atlaskit/editor-common/selection';
3
4
  import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
4
5
  import { TextSelection } from '@atlaskit/editor-prosemirror/state';
@@ -21,6 +22,7 @@ import { selectionPreservationPluginKey } from './pm-plugins/selection-preservat
21
22
  import { createSelectionPreservationPlugin } from './pm-plugins/selection-preservation/pm-plugin';
22
23
  import { expandAndUpdateSelection } from './pm-plugins/utils/expand-and-update-selection';
23
24
  import { selectNode } from './pm-plugins/utils/getSelection';
25
+ import { BlockControlsSurface } from './ui/block-controls-surface';
24
26
  import { GlobalStylesWrapper } from './ui/global-styles';
25
27
  export const blockControlsPlugin = ({
26
28
  api,
@@ -30,6 +32,23 @@ export const blockControlsPlugin = ({
30
32
  const nodeDecorationRegistry = [];
31
33
  const rightSideControlsEnabled = (_config$rightSideCont = config === null || config === void 0 ? void 0 : config.rightSideControlsEnabled) !== null && _config$rightSideCont !== void 0 ? _config$rightSideCont : false;
32
34
  const quickInsertButtonEnabled = (_config$quickInsertBu = config === null || config === void 0 ? void 0 : config.quickInsertButtonEnabled) !== null && _config$quickInsertBu !== void 0 ? _config$quickInsertBu : true;
35
+ const blockControlMigrationEnabled = isExperimentEnabled('platform_editor_block_control_migration');
36
+ if (blockControlMigrationEnabled) {
37
+ var _api$uiControlRegistr;
38
+ api === null || api === void 0 ? void 0 : (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.register([BLOCK_CONTROLS_LEFT_SURFACE, {
39
+ ...BLOCK_CONTROLS_LEFT_SECTION,
40
+ parents: [{
41
+ ...BLOCK_CONTROLS_LEFT_SURFACE,
42
+ rank: 100
43
+ }]
44
+ }, {
45
+ ...BLOCK_CONTROLS_LEFT_GROUP,
46
+ parents: [{
47
+ ...BLOCK_CONTROLS_LEFT_SECTION,
48
+ rank: 100
49
+ }]
50
+ }]);
51
+ }
33
52
  return {
34
53
  name: 'blockControls',
35
54
  actions: {
@@ -98,7 +117,7 @@ export const blockControlsPlugin = ({
98
117
  plugin: ({
99
118
  getIntl,
100
119
  nodeViewPortalProviderAPI
101
- }) => createPlugin(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled)
120
+ }) => createPlugin(api, getIntl, nodeViewPortalProviderAPI, nodeDecorationRegistry, rightSideControlsEnabled, quickInsertButtonEnabled && !blockControlMigrationEnabled)
102
121
  }];
103
122
  if (editorExperiment('platform_editor_controls', 'variant1')) {
104
123
  pmPlugins.push({
@@ -407,10 +426,15 @@ export const blockControlsPlugin = ({
407
426
  }
408
427
  return sharedState;
409
428
  },
410
- contentComponent() {
411
- return /*#__PURE__*/React.createElement(GlobalStylesWrapper, {
429
+ contentComponent({
430
+ editorView
431
+ }) {
432
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(GlobalStylesWrapper, {
412
433
  api: api
413
- });
434
+ }), blockControlMigrationEnabled && editorView && api ? /*#__PURE__*/React.createElement(BlockControlsSurface, {
435
+ api: api,
436
+ editorView: editorView
437
+ }) : null);
414
438
  }
415
439
  };
416
440
  };
@@ -1,5 +1,4 @@
1
1
  import { createElement } from 'react';
2
- import { bind } from 'bind-event-listener';
3
2
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
3
  import uuid from 'uuid';
5
4
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
@@ -49,7 +48,6 @@ export const dragHandleDecoration = ({
49
48
  editorState
50
49
  }) => {
51
50
  unmountDecorations(nodeViewPortalProviderAPI, 'data-blocks-drag-handle-container', 'data-blocks-drag-handle-key');
52
- let unbind;
53
51
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
54
52
  const key = uuid();
55
53
  const widgetSpec = editorExperiment('platform_editor_breakout_resizing', true) ? {
@@ -62,19 +60,13 @@ export const dragHandleDecoration = ({
62
60
  * Exclude 'breakout' on purpose, so the widgets render at the top of the document to avoid z-index issues
63
61
  * Other block marks must be added, otherwise PM will split the DOM elements causing mutations and re-draws
64
62
  */
65
- marks: expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getMatchingBlockMarks(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
66
- destroy: node => {
67
- unbind && unbind();
68
- }
63
+ marks: expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getMatchingBlockMarks(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : []
69
64
  } : {
70
65
  side: -1,
71
66
  type: TYPE_HANDLE_DEC,
72
67
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
73
68
  testid: `${TYPE_HANDLE_DEC}-${uuid()}`,
74
- marks: expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getMatchingBlockMarks(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
75
- destroy: node => {
76
- unbind && unbind();
77
- }
69
+ marks: expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getMatchingBlockMarks(editorState, pos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : []
78
70
  };
79
71
  return Decoration.widget(pos, (view, getPosUnsafe) => {
80
72
  const element = document.createElement('span');
@@ -105,18 +97,9 @@ export const dragHandleDecoration = ({
105
97
  * However, the tooltip for nested drag handle is no long working.
106
98
  */
107
99
  if (newPos === undefined || !isTopLevelNode) {
108
- if (fg('platform_editor_fix_widget_destroy')) {
109
- element.onmouseover = e => {
110
- e.stopPropagation();
111
- };
112
- } else {
113
- unbind = bind(element, {
114
- type: 'mouseover',
115
- listener: e => {
116
- e.stopPropagation();
117
- }
118
- });
119
- }
100
+ element.onmouseover = e => {
101
+ e.stopPropagation();
102
+ };
120
103
  }
121
104
 
122
105
  // There are times when global clear: "both" styles are applied to this decoration causing jumpiness
@@ -50,9 +50,7 @@ export const quickInsertButtonDecoration = ({
50
50
 
51
51
  marks: expValEquals('platform_editor_small_font_size', 'isEnabled', true) ? getMatchingBlockMarks(editorState, rootPos, [editorState.schema.marks.alignment, editorState.schema.marks.fontSize]) : [],
52
52
  destroy: _ => {
53
- if (fg('platform_editor_fix_widget_destroy')) {
54
- nodeViewPortalProviderAPI.remove(key);
55
- }
53
+ nodeViewPortalProviderAPI.remove(key);
56
54
  cleanupCallbacks.forEach(cb => {
57
55
  cb();
58
56
  });
@@ -61,9 +59,7 @@ export const quickInsertButtonDecoration = ({
61
59
  side: -2,
62
60
  type: TYPE_QUICK_INSERT,
63
61
  destroy: _ => {
64
- if (fg('platform_editor_fix_widget_destroy')) {
65
- nodeViewPortalProviderAPI.remove(key);
66
- }
62
+ nodeViewPortalProviderAPI.remove(key);
67
63
  cleanupCallbacks.forEach(cb => {
68
64
  cb();
69
65
  });