@atlaskit/editor-plugin-extension 19.1.10 → 19.2.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,28 @@
1
1
  # @atlaskit/editor-plugin-extension
2
2
 
3
+ ## 19.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`dfe761c33db5a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dfe761c33db5a) -
8
+ Add `copyEnabled` and `deleteEnabled` plugin options, both defaulting to `true`, behind
9
+ `platform_editor_extension_hide_toolbar_actions`. Setting either to `false` hides the matching
10
+ button on the extension floating toolbar, along with the separators that would otherwise be left
11
+ orphaned. This mirrors the existing `breakoutEnabled` option and lets a product whose page
12
+ structure is fixed stop offering actions its document would refuse.
13
+
14
+ Inert until that gate is enabled, so the options are a no-op on rollout even for a host that sets
15
+ them. The gate is read only once a host has opted in — the option check short-circuits before it —
16
+ so it is not exposed on toolbars it cannot affect.
17
+
18
+ `copyEnabled` applies to every extension in the editor; the manifest node's `hideCopyButton`
19
+ remains the way to hide copy on a single extension type and is not behind this gate. Hosts that
20
+ set neither option are unaffected in either gate state.
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+
3
26
  ## 19.1.10
4
27
 
5
28
  ### Patch Changes
@@ -199,6 +199,8 @@ var extensionPlugin = exports.extensionPlugin = function extensionPlugin(_ref) {
199
199
  pluginsOptions: {
200
200
  floatingToolbar: (0, _toolbar.getToolbarConfig)({
201
201
  breakoutEnabled: options.breakoutEnabled,
202
+ copyEnabled: options.copyEnabled,
203
+ deleteEnabled: options.deleteEnabled,
202
204
  extensionApi: _api,
203
205
  getUnsupportedContent: options.getUnsupportedContent
204
206
  }),
@@ -342,6 +342,10 @@ var createOnClickCopyButton = exports.createOnClickCopyButton = function createO
342
342
  var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref2) {
343
343
  var _ref2$breakoutEnabled = _ref2.breakoutEnabled,
344
344
  breakoutEnabled = _ref2$breakoutEnabled === void 0 ? true : _ref2$breakoutEnabled,
345
+ _ref2$copyEnabled = _ref2.copyEnabled,
346
+ copyEnabled = _ref2$copyEnabled === void 0 ? true : _ref2$copyEnabled,
347
+ _ref2$deleteEnabled = _ref2.deleteEnabled,
348
+ deleteEnabled = _ref2$deleteEnabled === void 0 ? true : _ref2$deleteEnabled,
345
349
  extensionApi = _ref2.extensionApi,
346
350
  getUnsupportedContent = _ref2.getUnsupportedContent;
347
351
  return function (state, intl) {
@@ -391,9 +395,19 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
391
395
  };
392
396
  }
393
397
 
394
- // Hide the copy button when the extension's manifest node opts out via
398
+ // Hide the copy button when the host disables it for every extension
399
+ // (`copyEnabled`), when the extension's manifest node opts out via
395
400
  // `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';
401
+ //
402
+ // The host check is deliberately evaluated before the gate, so the gate is
403
+ // only read — and so only exposed — for hosts that opted in. Reading it
404
+ // unconditionally would report an exposure on every extension toolbar in
405
+ // every product, drowning the rollout metric in traffic it cannot affect.
406
+ var shouldHideCopyButton = !copyEnabled && (0, _fg.fg)('platform_editor_extension_hide_toolbar_actions') || !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';
407
+ var shouldHideDeleteButton = !deleteEnabled && (0, _fg.fg)('platform_editor_extension_hide_toolbar_actions');
408
+ // With both trailing actions gone the toolbar ends after the breakout
409
+ // options, so the divider that used to introduce them would be an orphan.
410
+ var hasTrailingActions = !shouldHideCopyButton || !shouldHideDeleteButton;
397
411
  return {
398
412
  title: 'Extension floating controls',
399
413
  // Ignored via go/ees005
@@ -407,7 +421,7 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
407
421
  },
408
422
  items: [].concat((0, _toConsumableArray2.default)(editButtonItems), (0, _toConsumableArray2.default)(breakoutItems), [{
409
423
  type: 'separator',
410
- hidden: editButtonItems.length === 0 && breakoutItems.length === 0
424
+ hidden: editButtonItems.length === 0 && breakoutItems.length === 0 || !hasTrailingActions
411
425
  }, {
412
426
  type: 'extensions-placeholder',
413
427
  separator: 'end'
@@ -429,12 +443,14 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
429
443
  }, shouldHideCopyButton && {
430
444
  hidden: shouldHideCopyButton
431
445
  }),
432
- // Hide this separator when the copy button is hidden, otherwise it
433
- // renders as an orphaned divider before the delete button.
446
+ // Hide this separator when either neighbour is hidden, otherwise it
447
+ // renders as an orphaned divider before or after the delete button.
434
448
  {
435
449
  type: 'separator',
436
- hidden: shouldHideCopyButton
437
- }, {
450
+ hidden: shouldHideCopyButton || shouldHideDeleteButton
451
+ }, _objectSpread(_objectSpread({}, shouldHideDeleteButton && {
452
+ hidden: true
453
+ }), {}, {
438
454
  id: 'editor.extension.delete',
439
455
  type: 'button',
440
456
  icon: _delete.default,
@@ -449,7 +465,7 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
449
465
  title: formatMessage(_messages.default.remove),
450
466
  tabIndex: null,
451
467
  confirmDialog: confirmDialog
452
- }]),
468
+ })]),
453
469
  scrollable: true
454
470
  };
455
471
  };
@@ -185,6 +185,8 @@ export const extensionPlugin = ({
185
185
  pluginsOptions: {
186
186
  floatingToolbar: getToolbarConfig({
187
187
  breakoutEnabled: options.breakoutEnabled,
188
+ copyEnabled: options.copyEnabled,
189
+ deleteEnabled: options.deleteEnabled,
188
190
  extensionApi: api,
189
191
  getUnsupportedContent: options.getUnsupportedContent
190
192
  }),
@@ -344,6 +344,8 @@ export const createOnClickCopyButton = ({
344
344
  };
345
345
  export const getToolbarConfig = ({
346
346
  breakoutEnabled = true,
347
+ copyEnabled = true,
348
+ deleteEnabled = true,
347
349
  extensionApi,
348
350
  getUnsupportedContent
349
351
  }) => (state, intl) => {
@@ -392,9 +394,19 @@ export const getToolbarConfig = ({
392
394
  };
393
395
  }
394
396
 
395
- // Hide the copy button when the extension's manifest node opts out via
397
+ // Hide the copy button when the host disables it for every extension
398
+ // (`copyEnabled`), when the extension's manifest node opts out via
396
399
  // `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';
400
+ //
401
+ // The host check is deliberately evaluated before the gate, so the gate is
402
+ // only read — and so only exposed — for hosts that opted in. Reading it
403
+ // unconditionally would report an exposure on every extension toolbar in
404
+ // every product, drowning the rollout metric in traffic it cannot affect.
405
+ const shouldHideCopyButton = !copyEnabled && fg('platform_editor_extension_hide_toolbar_actions') || !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';
406
+ const shouldHideDeleteButton = !deleteEnabled && fg('platform_editor_extension_hide_toolbar_actions');
407
+ // With both trailing actions gone the toolbar ends after the breakout
408
+ // options, so the divider that used to introduce them would be an orphan.
409
+ const hasTrailingActions = !shouldHideCopyButton || !shouldHideDeleteButton;
398
410
  return {
399
411
  title: 'Extension floating controls',
400
412
  // Ignored via go/ees005
@@ -404,7 +416,7 @@ export const getToolbarConfig = ({
404
416
  onPositionCalculated: (editorView, nextPos) => calculateToolbarPosition(editorView, nextPos, state, extensionObj),
405
417
  items: [...editButtonItems, ...breakoutItems, {
406
418
  type: 'separator',
407
- hidden: editButtonItems.length === 0 && breakoutItems.length === 0
419
+ hidden: editButtonItems.length === 0 && breakoutItems.length === 0 || !hasTrailingActions
408
420
  }, {
409
421
  type: 'extensions-placeholder',
410
422
  separator: 'end'
@@ -427,12 +439,15 @@ export const getToolbarConfig = ({
427
439
  hidden: shouldHideCopyButton
428
440
  })
429
441
  },
430
- // Hide this separator when the copy button is hidden, otherwise it
431
- // renders as an orphaned divider before the delete button.
442
+ // Hide this separator when either neighbour is hidden, otherwise it
443
+ // renders as an orphaned divider before or after the delete button.
432
444
  {
433
445
  type: 'separator',
434
- hidden: shouldHideCopyButton
446
+ hidden: shouldHideCopyButton || shouldHideDeleteButton
435
447
  }, {
448
+ ...(shouldHideDeleteButton && {
449
+ hidden: true
450
+ }),
436
451
  id: 'editor.extension.delete',
437
452
  type: 'button',
438
453
  icon: DeleteIcon,
@@ -190,6 +190,8 @@ export var extensionPlugin = function extensionPlugin(_ref) {
190
190
  pluginsOptions: {
191
191
  floatingToolbar: getToolbarConfig({
192
192
  breakoutEnabled: options.breakoutEnabled,
193
+ copyEnabled: options.copyEnabled,
194
+ deleteEnabled: options.deleteEnabled,
193
195
  extensionApi: _api,
194
196
  getUnsupportedContent: options.getUnsupportedContent
195
197
  }),
@@ -336,6 +336,10 @@ export var createOnClickCopyButton = function createOnClickCopyButton(_ref) {
336
336
  export var getToolbarConfig = function getToolbarConfig(_ref2) {
337
337
  var _ref2$breakoutEnabled = _ref2.breakoutEnabled,
338
338
  breakoutEnabled = _ref2$breakoutEnabled === void 0 ? true : _ref2$breakoutEnabled,
339
+ _ref2$copyEnabled = _ref2.copyEnabled,
340
+ copyEnabled = _ref2$copyEnabled === void 0 ? true : _ref2$copyEnabled,
341
+ _ref2$deleteEnabled = _ref2.deleteEnabled,
342
+ deleteEnabled = _ref2$deleteEnabled === void 0 ? true : _ref2$deleteEnabled,
339
343
  extensionApi = _ref2.extensionApi,
340
344
  getUnsupportedContent = _ref2.getUnsupportedContent;
341
345
  return function (state, intl) {
@@ -385,9 +389,19 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
385
389
  };
386
390
  }
387
391
 
388
- // Hide the copy button when the extension's manifest node opts out via
392
+ // Hide the copy button when the host disables it for every extension
393
+ // (`copyEnabled`), when the extension's manifest node opts out via
389
394
  // `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';
395
+ //
396
+ // The host check is deliberately evaluated before the gate, so the gate is
397
+ // only read — and so only exposed — for hosts that opted in. Reading it
398
+ // unconditionally would report an exposure on every extension toolbar in
399
+ // every product, drowning the rollout metric in traffic it cannot affect.
400
+ var shouldHideCopyButton = !copyEnabled && fg('platform_editor_extension_hide_toolbar_actions') || !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';
401
+ var shouldHideDeleteButton = !deleteEnabled && fg('platform_editor_extension_hide_toolbar_actions');
402
+ // With both trailing actions gone the toolbar ends after the breakout
403
+ // options, so the divider that used to introduce them would be an orphan.
404
+ var hasTrailingActions = !shouldHideCopyButton || !shouldHideDeleteButton;
391
405
  return {
392
406
  title: 'Extension floating controls',
393
407
  // Ignored via go/ees005
@@ -401,7 +415,7 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
401
415
  },
402
416
  items: [].concat(_toConsumableArray(editButtonItems), _toConsumableArray(breakoutItems), [{
403
417
  type: 'separator',
404
- hidden: editButtonItems.length === 0 && breakoutItems.length === 0
418
+ hidden: editButtonItems.length === 0 && breakoutItems.length === 0 || !hasTrailingActions
405
419
  }, {
406
420
  type: 'extensions-placeholder',
407
421
  separator: 'end'
@@ -423,12 +437,14 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
423
437
  }, shouldHideCopyButton && {
424
438
  hidden: shouldHideCopyButton
425
439
  }),
426
- // Hide this separator when the copy button is hidden, otherwise it
427
- // renders as an orphaned divider before the delete button.
440
+ // Hide this separator when either neighbour is hidden, otherwise it
441
+ // renders as an orphaned divider before or after the delete button.
428
442
  {
429
443
  type: 'separator',
430
- hidden: shouldHideCopyButton
431
- }, {
444
+ hidden: shouldHideCopyButton || shouldHideDeleteButton
445
+ }, _objectSpread(_objectSpread({}, shouldHideDeleteButton && {
446
+ hidden: true
447
+ }), {}, {
432
448
  id: 'editor.extension.delete',
433
449
  type: 'button',
434
450
  icon: DeleteIcon,
@@ -443,7 +459,7 @@ export var getToolbarConfig = function getToolbarConfig(_ref2) {
443
459
  title: formatMessage(commonMessages.remove),
444
460
  tabIndex: null,
445
461
  confirmDialog: confirmDialog
446
- }]),
462
+ })]),
447
463
  scrollable: true
448
464
  };
449
465
  };
@@ -54,6 +54,24 @@ export interface ExtensionPluginOptions extends LongPressSelectionPluginOptions
54
54
  };
55
55
  appearance?: EditorAppearance;
56
56
  breakoutEnabled?: boolean;
57
+ /**
58
+ * Whether the extension floating toolbar offers a copy button. Defaults to
59
+ * `true`. Set `false` for content whose structure the product fixes, so the
60
+ * toolbar does not offer an action the document will refuse.
61
+ *
62
+ * Gated on `platform_editor_extension_hide_toolbar_actions`: until that gate
63
+ * is on, setting this has no effect.
64
+ *
65
+ * For hiding copy on a single extension type instead, use the manifest node's
66
+ * `hideCopyButton`, which is not gated on the above.
67
+ */
68
+ copyEnabled?: boolean;
69
+ /**
70
+ * Whether the extension floating toolbar offers a delete button. Defaults to
71
+ * `true`, and gated on `platform_editor_extension_hide_toolbar_actions` the
72
+ * same way `copyEnabled` is.
73
+ */
74
+ deleteEnabled?: boolean;
57
75
  extensionHandlers?: ExtensionHandlers;
58
76
  /**
59
77
  * Helps optimize layout shift while rendering by setting minimum heights before the extension content loads.
@@ -23,6 +23,8 @@ export declare const createOnClickCopyButton: ({ formatMessage, extensionApi, ex
23
23
  }) => Command | undefined;
24
24
  interface GetToolbarConfigProps {
25
25
  breakoutEnabled: boolean | undefined;
26
+ copyEnabled?: boolean | undefined;
27
+ deleteEnabled?: boolean | undefined;
26
28
  extensionApi?: PublicPluginAPI<[
27
29
  ContextPanelPlugin,
28
30
  AnalyticsPlugin,
@@ -33,5 +35,5 @@ interface GetToolbarConfigProps {
33
35
  ]> | undefined;
34
36
  getUnsupportedContent?: ExtensionPluginOptions['getUnsupportedContent'];
35
37
  }
36
- export declare const getToolbarConfig: ({ breakoutEnabled, extensionApi, getUnsupportedContent, }: GetToolbarConfigProps) => FloatingToolbarHandler;
38
+ export declare const getToolbarConfig: ({ breakoutEnabled, copyEnabled, deleteEnabled, extensionApi, getUnsupportedContent, }: GetToolbarConfigProps) => FloatingToolbarHandler;
37
39
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-extension",
3
- "version": "19.1.10",
3
+ "version": "19.2.0",
4
4
  "description": "editor-plugin-extension plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -97,6 +97,9 @@
97
97
  },
98
98
  "platform_editor_extension_hide_copy_button": {
99
99
  "type": "boolean"
100
+ },
101
+ "platform_editor_extension_hide_toolbar_actions": {
102
+ "type": "boolean"
100
103
  }
101
104
  }
102
105
  }