@atlaskit/editor-plugin-extension 17.0.4 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @atlaskit/editor-plugin-extension
2
2
 
3
+ ## 17.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`882186c3b96b6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/882186c3b96b6) -
8
+ Add an optional `hideCopyButton` capability to extension manifest nodes (`ExtensionModuleNode`).
9
+ When set, the extension's selection floating toolbar hides the copy button. Used by the redaction
10
+ extension so redacted content is delete-only (no copy, no configure).
11
+
12
+ The new toolbar behaviour is gated behind `platform_editor_extension_hide_copy_button`. When the
13
+ gate is off, the toolbar renders exactly as before. When the copy button is hidden, the trailing
14
+ toolbar separator is also hidden so delete-only toolbars do not render an orphaned divider.
15
+
16
+ ```ts
17
+ const manifest: ExtensionManifest = {
18
+ // ...
19
+ modules: {
20
+ nodes: {
21
+ default: {
22
+ type: 'inlineExtension',
23
+ render: () => import('./MyExtension'),
24
+ // Hide the copy button on this node's selection toolbar
25
+ hideCopyButton: true,
26
+ },
27
+ },
28
+ },
29
+ };
30
+ ```
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies
35
+
36
+ ## 17.0.5
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies
41
+
3
42
  ## 17.0.4
4
43
 
5
44
  ### Patch Changes
@@ -174,6 +174,10 @@ var handleUpdate = exports.handleUpdate = function handleUpdate(_ref3) {
174
174
  showContextPanel: false,
175
175
  element: newElement,
176
176
  showEditButton: _showEditButton,
177
+ // Default to showing synchronously; the manifest-driven value (if any)
178
+ // is resolved asynchronously via updateEditButton for provider-based
179
+ // extensions.
180
+ showCopyButton: true,
177
181
  updateExtension: updateExtension
178
182
  })(state, dispatch);
179
183
  }
@@ -194,6 +198,7 @@ var createPlugin = exports.createPlugin = function createPlugin(dispatch, provid
194
198
  var intl = arguments.length > 11 ? arguments[11] : undefined;
195
199
  var state = (0, _pluginFactory.createPluginState)(dispatch, {
196
200
  showEditButton: false,
201
+ showCopyButton: true,
197
202
  showContextPanel: false
198
203
  });
199
204
  var extensionNodeViewOptions = {
@@ -21,6 +21,7 @@ var _contentWidthWide = _interopRequireDefault(require("@atlaskit/icon/core/cont
21
21
  var _delete = _interopRequireDefault(require("@atlaskit/icon/core/delete"));
22
22
  var _edit = _interopRequireDefault(require("@atlaskit/icon/core/edit"));
23
23
  var _expandHorizontal = _interopRequireDefault(require("@atlaskit/icon/core/expand-horizontal"));
24
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
24
25
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
25
26
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
26
27
  var _actions = require("../editor-actions/actions");
@@ -390,8 +391,9 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
390
391
  };
391
392
  }
392
393
 
393
- // disable copy button for legacy content macro
394
- var shouldHideCopyButton = (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
394
+ // Hide the copy button when the extension's manifest node opts out via
395
+ // `hideCopyButton` (e.g. redactions), or for the legacy content macro.
396
+ var shouldHideCopyButton = !extensionState.showCopyButton && (0, _fg.fg)('platform_editor_extension_hide_copy_button') || (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
395
397
  return {
396
398
  title: 'Extension floating controls',
397
399
  // Ignored via go/ees005
@@ -426,8 +428,12 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
426
428
  }]
427
429
  }, shouldHideCopyButton && {
428
430
  hidden: shouldHideCopyButton
429
- }), {
430
- type: 'separator'
431
+ }),
432
+ // Hide this separator when the copy button is hidden, otherwise it
433
+ // renders as an orphaned divider before the delete button.
434
+ {
435
+ type: 'separator',
436
+ hidden: shouldHideCopyButton
431
437
  }, {
432
438
  id: 'editor.extension.delete',
433
439
  type: 'button',
@@ -10,7 +10,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _extensions = require("@atlaskit/editor-common/extensions");
11
11
  var _commands = require("../editor-commands/commands");
12
12
  var _utils = require("./utils");
13
- var maybeGetUpdateMethodFromExtensionProvider = /*#__PURE__*/function () {
13
+ var maybeGetExtensionModuleNode = /*#__PURE__*/function () {
14
14
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(view, extensionProvider) {
15
15
  var nodeWithPos, _nodeWithPos$node$att, extensionType, extensionKey, extensionModuleNode, newNodeWithPos;
16
16
  return _regenerator.default.wrap(function (_context) {
@@ -33,30 +33,32 @@ var maybeGetUpdateMethodFromExtensionProvider = /*#__PURE__*/function () {
33
33
  _context.next = 3;
34
34
  break;
35
35
  }
36
- return _context.abrupt("return", extensionModuleNode.update);
36
+ return _context.abrupt("return", extensionModuleNode);
37
37
  case 3:
38
38
  case "end":
39
39
  return _context.stop();
40
40
  }
41
41
  }, _callee);
42
42
  }));
43
- return function maybeGetUpdateMethodFromExtensionProvider(_x, _x2) {
43
+ return function maybeGetExtensionModuleNode(_x, _x2) {
44
44
  return _ref.apply(this, arguments);
45
45
  };
46
46
  }();
47
47
  var updateEditButton = exports.updateEditButton = /*#__PURE__*/function () {
48
48
  var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(view, extensionProvider) {
49
- var updateMethod, _t;
49
+ var extensionModuleNode, updateMethod, _t;
50
50
  return _regenerator.default.wrap(function (_context2) {
51
51
  while (1) switch (_context2.prev = _context2.next) {
52
52
  case 0:
53
53
  _context2.prev = 0;
54
54
  _context2.next = 1;
55
- return maybeGetUpdateMethodFromExtensionProvider(view, extensionProvider);
55
+ return maybeGetExtensionModuleNode(view, extensionProvider);
56
56
  case 1:
57
- updateMethod = _context2.sent;
57
+ extensionModuleNode = _context2.sent;
58
+ updateMethod = extensionModuleNode === null || extensionModuleNode === void 0 ? void 0 : extensionModuleNode.update;
58
59
  (0, _commands.updateState)({
59
60
  showEditButton: !!updateMethod,
61
+ showCopyButton: !(extensionModuleNode !== null && extensionModuleNode !== void 0 && extensionModuleNode.hideCopyButton),
60
62
  updateExtension: updateMethod && Promise.resolve(updateMethod) || undefined
61
63
  })(view.state, view.dispatch);
62
64
  return _context2.abrupt("return", updateMethod);
@@ -115,6 +115,10 @@ export const handleUpdate = ({
115
115
  showContextPanel: false,
116
116
  element: newElement,
117
117
  showEditButton,
118
+ // Default to showing synchronously; the manifest-driven value (if any)
119
+ // is resolved asynchronously via updateEditButton for provider-based
120
+ // extensions.
121
+ showCopyButton: true,
118
122
  updateExtension
119
123
  })(state, dispatch);
120
124
  }
@@ -130,6 +134,7 @@ export const createPlugin = (dispatch, providerFactory, extensionHandlers, exten
130
134
  var _featureFlags$macroIn;
131
135
  const state = createPluginState(dispatch, {
132
136
  showEditButton: false,
137
+ showCopyButton: true,
133
138
  showContextPanel: false
134
139
  });
135
140
  const extensionNodeViewOptions = {
@@ -12,6 +12,7 @@ import ContentWidthWideIcon from '@atlaskit/icon/core/content-width-wide';
12
12
  import DeleteIcon from '@atlaskit/icon/core/delete';
13
13
  import EditIcon from '@atlaskit/icon/core/edit';
14
14
  import ExpandHorizontalIcon from '@atlaskit/icon/core/expand-horizontal';
15
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
15
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
16
17
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
17
18
  import { editExtension } from '../editor-actions/actions';
@@ -391,8 +392,9 @@ export const getToolbarConfig = ({
391
392
  };
392
393
  }
393
394
 
394
- // disable copy button for legacy content macro
395
- const shouldHideCopyButton = (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
395
+ // Hide the copy button when the extension's manifest node opts out via
396
+ // `hideCopyButton` (e.g. redactions), or for the legacy content macro.
397
+ const shouldHideCopyButton = !extensionState.showCopyButton && fg('platform_editor_extension_hide_copy_button') || (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
396
398
  return {
397
399
  title: 'Extension floating controls',
398
400
  // Ignored via go/ees005
@@ -424,8 +426,12 @@ export const getToolbarConfig = ({
424
426
  ...(shouldHideCopyButton && {
425
427
  hidden: shouldHideCopyButton
426
428
  })
427
- }, {
428
- type: 'separator'
429
+ },
430
+ // Hide this separator when the copy button is hidden, otherwise it
431
+ // renders as an orphaned divider before the delete button.
432
+ {
433
+ type: 'separator',
434
+ hidden: shouldHideCopyButton
429
435
  }, {
430
436
  id: 'editor.extension.delete',
431
437
  type: 'button',
@@ -1,7 +1,7 @@
1
1
  import { getExtensionModuleNode } from '@atlaskit/editor-common/extensions';
2
2
  import { updateState } from '../editor-commands/commands';
3
3
  import { getSelectedExtension } from './utils';
4
- const maybeGetUpdateMethodFromExtensionProvider = async (view, extensionProvider) => {
4
+ const maybeGetExtensionModuleNode = async (view, extensionProvider) => {
5
5
  const nodeWithPos = getSelectedExtension(view.state, true);
6
6
  if (!nodeWithPos) {
7
7
  throw new Error('There is no selection');
@@ -13,14 +13,16 @@ const maybeGetUpdateMethodFromExtensionProvider = async (view, extensionProvider
13
13
  const extensionModuleNode = await getExtensionModuleNode(extensionProvider, extensionType, extensionKey);
14
14
  const newNodeWithPos = getSelectedExtension(view.state, true);
15
15
  if (newNodeWithPos && newNodeWithPos.node.attrs.extensionType === extensionType && newNodeWithPos.node.attrs.extensionKey === extensionKey && newNodeWithPos.pos === nodeWithPos.pos && extensionModuleNode) {
16
- return extensionModuleNode.update;
16
+ return extensionModuleNode;
17
17
  }
18
18
  };
19
19
  export const updateEditButton = async (view, extensionProvider) => {
20
20
  try {
21
- const updateMethod = await maybeGetUpdateMethodFromExtensionProvider(view, extensionProvider);
21
+ const extensionModuleNode = await maybeGetExtensionModuleNode(view, extensionProvider);
22
+ const updateMethod = extensionModuleNode === null || extensionModuleNode === void 0 ? void 0 : extensionModuleNode.update;
22
23
  updateState({
23
24
  showEditButton: !!updateMethod,
25
+ showCopyButton: !(extensionModuleNode !== null && extensionModuleNode !== void 0 && extensionModuleNode.hideCopyButton),
24
26
  updateExtension: updateMethod && Promise.resolve(updateMethod) || undefined
25
27
  })(view.state, view.dispatch);
26
28
  return updateMethod;
@@ -167,6 +167,10 @@ export var handleUpdate = function handleUpdate(_ref3) {
167
167
  showContextPanel: false,
168
168
  element: newElement,
169
169
  showEditButton: _showEditButton,
170
+ // Default to showing synchronously; the manifest-driven value (if any)
171
+ // is resolved asynchronously via updateEditButton for provider-based
172
+ // extensions.
173
+ showCopyButton: true,
170
174
  updateExtension: updateExtension
171
175
  })(state, dispatch);
172
176
  }
@@ -187,6 +191,7 @@ export var createPlugin = function createPlugin(dispatch, providerFactory, exten
187
191
  var intl = arguments.length > 11 ? arguments[11] : undefined;
188
192
  var state = createPluginState(dispatch, {
189
193
  showEditButton: false,
194
+ showCopyButton: true,
190
195
  showContextPanel: false
191
196
  });
192
197
  var extensionNodeViewOptions = {
@@ -16,6 +16,7 @@ import ContentWidthWideIcon from '@atlaskit/icon/core/content-width-wide';
16
16
  import DeleteIcon from '@atlaskit/icon/core/delete';
17
17
  import EditIcon from '@atlaskit/icon/core/edit';
18
18
  import ExpandHorizontalIcon from '@atlaskit/icon/core/expand-horizontal';
19
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
19
20
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
20
21
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
21
22
  import { editExtension } from '../editor-actions/actions';
@@ -384,8 +385,9 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
384
385
  };
385
386
  }
386
387
 
387
- // disable copy button for legacy content macro
388
- var shouldHideCopyButton = (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
388
+ // Hide the copy button when the extension's manifest node opts out via
389
+ // `hideCopyButton` (e.g. redactions), or for the legacy content macro.
390
+ var shouldHideCopyButton = !extensionState.showCopyButton && fg('platform_editor_extension_hide_copy_button') || (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionType) === 'com.atlassian.confluence.migration' && (extensionObj === null || extensionObj === void 0 ? void 0 : extensionObj.node.attrs.extensionKey) === 'legacy-content';
389
391
  return {
390
392
  title: 'Extension floating controls',
391
393
  // Ignored via go/ees005
@@ -420,8 +422,12 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
420
422
  }]
421
423
  }, shouldHideCopyButton && {
422
424
  hidden: shouldHideCopyButton
423
- }), {
424
- type: 'separator'
425
+ }),
426
+ // Hide this separator when the copy button is hidden, otherwise it
427
+ // renders as an orphaned divider before the delete button.
428
+ {
429
+ type: 'separator',
430
+ hidden: shouldHideCopyButton
425
431
  }, {
426
432
  id: 'editor.extension.delete',
427
433
  type: 'button',
@@ -3,7 +3,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
3
  import { getExtensionModuleNode } from '@atlaskit/editor-common/extensions';
4
4
  import { updateState } from '../editor-commands/commands';
5
5
  import { getSelectedExtension } from './utils';
6
- var maybeGetUpdateMethodFromExtensionProvider = /*#__PURE__*/function () {
6
+ var maybeGetExtensionModuleNode = /*#__PURE__*/function () {
7
7
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(view, extensionProvider) {
8
8
  var nodeWithPos, _nodeWithPos$node$att, extensionType, extensionKey, extensionModuleNode, newNodeWithPos;
9
9
  return _regeneratorRuntime.wrap(function (_context) {
@@ -26,30 +26,32 @@ var maybeGetUpdateMethodFromExtensionProvider = /*#__PURE__*/function () {
26
26
  _context.next = 3;
27
27
  break;
28
28
  }
29
- return _context.abrupt("return", extensionModuleNode.update);
29
+ return _context.abrupt("return", extensionModuleNode);
30
30
  case 3:
31
31
  case "end":
32
32
  return _context.stop();
33
33
  }
34
34
  }, _callee);
35
35
  }));
36
- return function maybeGetUpdateMethodFromExtensionProvider(_x, _x2) {
36
+ return function maybeGetExtensionModuleNode(_x, _x2) {
37
37
  return _ref.apply(this, arguments);
38
38
  };
39
39
  }();
40
40
  export var updateEditButton = /*#__PURE__*/function () {
41
41
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(view, extensionProvider) {
42
- var updateMethod, _t;
42
+ var extensionModuleNode, updateMethod, _t;
43
43
  return _regeneratorRuntime.wrap(function (_context2) {
44
44
  while (1) switch (_context2.prev = _context2.next) {
45
45
  case 0:
46
46
  _context2.prev = 0;
47
47
  _context2.next = 1;
48
- return maybeGetUpdateMethodFromExtensionProvider(view, extensionProvider);
48
+ return maybeGetExtensionModuleNode(view, extensionProvider);
49
49
  case 1:
50
- updateMethod = _context2.sent;
50
+ extensionModuleNode = _context2.sent;
51
+ updateMethod = extensionModuleNode === null || extensionModuleNode === void 0 ? void 0 : extensionModuleNode.update;
51
52
  updateState({
52
53
  showEditButton: !!updateMethod,
54
+ showCopyButton: !(extensionModuleNode !== null && extensionModuleNode !== void 0 && extensionModuleNode.hideCopyButton),
53
55
  updateExtension: updateMethod && Promise.resolve(updateMethod) || undefined
54
56
  })(view.state, view.dispatch);
55
57
  return _context2.abrupt("return", updateMethod);
@@ -32,6 +32,7 @@ export type ExtensionState<T extends Parameters = Parameters> = {
32
32
  processParametersBefore?: TransformBefore<T>;
33
33
  showContextPanel: boolean;
34
34
  showEditButton: boolean;
35
+ showCopyButton: boolean;
35
36
  updateExtension?: Promise<UpdateExtension<T> | void>;
36
37
  };
37
38
  export type ExtensionAction<T extends Parameters = Parameters> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-extension",
3
- "version": "17.0.4",
3
+ "version": "17.1.0",
4
4
  "description": "editor-plugin-extension plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -61,7 +61,7 @@
61
61
  "@atlaskit/tabs": "^21.0.0",
62
62
  "@atlaskit/textarea": "^10.0.0",
63
63
  "@atlaskit/textfield": "^10.0.0",
64
- "@atlaskit/tmp-editor-statsig": "^145.0.0",
64
+ "@atlaskit/tmp-editor-statsig": "^146.0.0",
65
65
  "@atlaskit/toggle": "^17.1.0",
66
66
  "@atlaskit/tokens": "^16.6.0",
67
67
  "@atlaskit/tooltip": "^24.0.0",
@@ -75,7 +75,7 @@
75
75
  "uuid": "^3.1.0"
76
76
  },
77
77
  "peerDependencies": {
78
- "@atlaskit/editor-common": "^118.4.0",
78
+ "@atlaskit/editor-common": "^118.7.0",
79
79
  "react": "^18.2.0 || ^19.2.0",
80
80
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
81
81
  },
@@ -121,6 +121,9 @@
121
121
  "platform-feature-flags": {
122
122
  "platform_editor_ai_object_sidebar_injection": {
123
123
  "type": "boolean"
124
+ },
125
+ "platform_editor_extension_hide_copy_button": {
126
+ "type": "boolean"
124
127
  }
125
128
  },
126
129
  "stricter": {