@atlaskit/editor-plugin-card 35.0.1 → 35.1.1

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 (47) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/cjs/actions/cardRegistry.js +65 -0
  3. package/dist/cjs/actions/useCardRegistry.js +19 -0
  4. package/dist/cjs/cardPlugin.js +6 -0
  5. package/dist/cjs/nodeviews/blockCard.js +45 -21
  6. package/dist/cjs/nodeviews/embedCard.js +50 -26
  7. package/dist/cjs/nodeviews/inlineCardBase.js +41 -20
  8. package/dist/cjs/nodeviews/inlineCardWithAwareness.js +14 -10
  9. package/dist/cjs/pm-plugins/doc.js +1 -1
  10. package/dist/cjs/pm-plugins/main.js +11 -9
  11. package/dist/cjs/pm-plugins/utils.js +19 -7
  12. package/dist/cjs/ui/EditLinkToolbar.js +5 -3
  13. package/dist/cjs/ui/PasteDisplayAsMenu.js +15 -4
  14. package/dist/cjs/ui/toolbar.js +37 -21
  15. package/dist/es2019/actions/cardRegistry.js +58 -0
  16. package/dist/es2019/actions/useCardRegistry.js +9 -0
  17. package/dist/es2019/cardPlugin.js +6 -0
  18. package/dist/es2019/nodeviews/blockCard.js +42 -16
  19. package/dist/es2019/nodeviews/embedCard.js +42 -16
  20. package/dist/es2019/nodeviews/inlineCardBase.js +43 -22
  21. package/dist/es2019/nodeviews/inlineCardWithAwareness.js +12 -8
  22. package/dist/es2019/pm-plugins/doc.js +1 -1
  23. package/dist/es2019/pm-plugins/main.js +11 -9
  24. package/dist/es2019/pm-plugins/utils.js +15 -5
  25. package/dist/es2019/ui/EditLinkToolbar.js +5 -3
  26. package/dist/es2019/ui/PasteDisplayAsMenu.js +11 -4
  27. package/dist/es2019/ui/toolbar.js +35 -19
  28. package/dist/esm/actions/cardRegistry.js +58 -0
  29. package/dist/esm/actions/useCardRegistry.js +13 -0
  30. package/dist/esm/cardPlugin.js +6 -0
  31. package/dist/esm/nodeviews/blockCard.js +45 -21
  32. package/dist/esm/nodeviews/embedCard.js +50 -26
  33. package/dist/esm/nodeviews/inlineCardBase.js +41 -20
  34. package/dist/esm/nodeviews/inlineCardWithAwareness.js +14 -10
  35. package/dist/esm/pm-plugins/doc.js +1 -1
  36. package/dist/esm/pm-plugins/main.js +11 -9
  37. package/dist/esm/pm-plugins/utils.js +19 -7
  38. package/dist/esm/ui/EditLinkToolbar.js +5 -3
  39. package/dist/esm/ui/PasteDisplayAsMenu.js +15 -4
  40. package/dist/esm/ui/toolbar.js +37 -21
  41. package/dist/types/actions/cardRegistry.d.ts +37 -0
  42. package/dist/types/actions/useCardRegistry.d.ts +3 -0
  43. package/dist/types/nodeviews/blockCard.d.ts +2 -2
  44. package/dist/types/nodeviews/embedCard.d.ts +2 -2
  45. package/dist/types/nodeviews/genericCard.d.ts +2 -4
  46. package/dist/types/pm-plugins/utils.d.ts +2 -1
  47. package/package.json +8 -5
@@ -35,6 +35,7 @@ var _edit = _interopRequireDefault(require("@atlaskit/icon/core/edit"));
35
35
  var _linkBroken = _interopRequireDefault(require("@atlaskit/icon/core/link-broken"));
36
36
  var _linkExternal = _interopRequireDefault(require("@atlaskit/icon/core/link-external"));
37
37
  var _settings = _interopRequireDefault(require("@atlaskit/icon/core/settings"));
38
+ var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
38
39
  var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment");
39
40
  var _doc = require("../pm-plugins/doc");
40
41
  var _pluginKey = require("../pm-plugins/plugin-key");
@@ -131,6 +132,7 @@ var openLinkSettings = exports.openLinkSettings = function openLinkSettings(edit
131
132
  };
132
133
  var floatingToolbar = exports.floatingToolbar = function floatingToolbar(cardOptions, lpLinkPicker, linkPickerOptions, pluginInjectionApi, disableFloatingToolbar) {
133
134
  return function (state, intl, providerFactory) {
135
+ var _pluginInjectionApi$c;
134
136
  if (disableFloatingToolbar) {
135
137
  return;
136
138
  }
@@ -159,6 +161,10 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(cardOpt
159
161
  var isLinkPickerEnabled = !!lpLinkPicker;
160
162
  return _objectSpread(_objectSpread({
161
163
  title: intl.formatMessage(_card.messages.card),
164
+ externalStore: (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2') ? (pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.actions) && {
165
+ getSnapshot: pluginInjectionApi.card.actions.getCardRegistrations,
166
+ subscribe: pluginInjectionApi.card.actions.subscribeToCardRegistry
167
+ } : undefined,
162
168
  className: className,
163
169
  nodeType: nodeType,
164
170
  preventPopupOverflow: isLinkPickerEnabled
@@ -190,17 +196,27 @@ var floatingToolbar = exports.floatingToolbar = function floatingToolbar(cardOpt
190
196
  }, (0, _EditLinkToolbar.editLinkToolbarConfig)(Boolean(pluginState === null || pluginState === void 0 ? void 0 : pluginState.showLinkingToolbar), isLinkPickerEnabled, linkPickerOptions));
191
197
  };
192
198
  };
193
- var unlinkCard = function unlinkCard(node, state, editorAnalyticsApi) {
194
- var displayInfo = (0, _utils4.displayInfoForCard)(node, (0, _utils4.findCardInfo)(state));
195
- var text = displayInfo.title || displayInfo.url;
196
- if (text) {
197
- return (0, _utils.commandWithMetadata)((0, _doc.changeSelectedCardToText)(text, editorAnalyticsApi), {
198
- action: _enums.ACTION.UNLINK
199
- });
199
+ var unlinkCard = function unlinkCard(node, state, editorAnalyticsApi, pluginInjectionApi) {
200
+ if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2')) {
201
+ return function (currentState, dispatch, view) {
202
+ var displayInfo = (0, _utils4.displayInfoForCard)(node, (0, _utils4.findCardInfo)(currentState, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions));
203
+ var text = displayInfo.title || displayInfo.url;
204
+ return text ? (0, _utils.commandWithMetadata)((0, _doc.changeSelectedCardToText)(text, editorAnalyticsApi), {
205
+ action: _enums.ACTION.UNLINK
206
+ })(currentState, dispatch, view) : false;
207
+ };
208
+ } else {
209
+ var displayInfo = (0, _utils4.displayInfoForCard)(node, (0, _utils4.findCardInfo)(state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions));
210
+ var text = displayInfo.title || displayInfo.url;
211
+ if (text) {
212
+ return (0, _utils.commandWithMetadata)((0, _doc.changeSelectedCardToText)(text, editorAnalyticsApi), {
213
+ action: _enums.ACTION.UNLINK
214
+ });
215
+ }
216
+ return function () {
217
+ return false;
218
+ };
200
219
  }
201
- return function () {
202
- return false;
203
- };
204
220
  };
205
221
  var buildAlignmentOptions = function buildAlignmentOptions(state, intl, widthPluginDependencyApi, analyticsApi, cardOptions, areAnyNewToolbarFlagsEnabled) {
206
222
  if (areAnyNewToolbarFlagsEnabled) {
@@ -241,7 +257,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
241
257
  if (url && !(0, _isSafeUrl.isSafeUrl)(url)) {
242
258
  return [];
243
259
  } else {
244
- var _displayInfoForCard = (0, _utils4.displayInfoForCard)(node, (0, _utils4.findCardInfo)(state)),
260
+ var _displayInfoForCard = (0, _utils4.displayInfoForCard)(node, (0, _utils4.findCardInfo)(state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions)),
245
261
  title = _displayInfoForCard.title;
246
262
  metadata = {
247
263
  url: url,
@@ -291,7 +307,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
291
307
  } else if (shouldRenderDatasourceToolbar) {
292
308
  return getDatasourceButtonGroup(metadata, intl, editorAnalyticsApi, node, hoverDecoration, node.attrs.datasource.id, state, cardOptions, currentAppearance, pluginInjectionApi);
293
309
  } else {
294
- var _pluginInjectionApi$c, _pluginState$resolved;
310
+ var _pluginInjectionApi$c2, _pluginState$resolved;
295
311
  var inlineCard = state.schema.nodes.inlineCard;
296
312
  var editItems = cardOptions.allowDatasource ? [{
297
313
  type: 'custom',
@@ -329,7 +345,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
329
345
  title: intl.formatMessage(_annotation.annotationMessages.createComment),
330
346
  showTitle: (0, _editorExperiment.editorExperiment)('platform_editor_controls', 'control') ? undefined : true,
331
347
  onClick: onCommentButtonClick,
332
- disabled: (0, _isOfflineMode.isOfflineMode)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.connectivity) === null || _pluginInjectionApi$c === void 0 || (_pluginInjectionApi$c = _pluginInjectionApi$c.sharedState) === null || _pluginInjectionApi$c === void 0 || (_pluginInjectionApi$c = _pluginInjectionApi$c.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.mode)
348
+ disabled: (0, _isOfflineMode.isOfflineMode)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.connectivity) === null || _pluginInjectionApi$c2 === void 0 || (_pluginInjectionApi$c2 = _pluginInjectionApi$c2.sharedState) === null || _pluginInjectionApi$c2 === void 0 || (_pluginInjectionApi$c2 = _pluginInjectionApi$c2.currentState()) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.mode)
333
349
  }, {
334
350
  type: 'separator'
335
351
  }] : [];
@@ -399,7 +415,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
399
415
  };
400
416
  var toolbarItems = areAllNewToolbarFlagsDisabled ? [].concat(editItems, commentItems, openPreviewPanelItems, [openLinkToolbarItem, {
401
417
  type: 'separator'
402
- }], (0, _toConsumableArray2.default)(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled)), [{
418
+ }], (0, _toConsumableArray2.default)(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled, pluginInjectionApi)), [{
403
419
  type: 'copy-button',
404
420
  items: [{
405
421
  state: state,
@@ -423,7 +439,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
423
439
  onBlur: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(node.type, false),
424
440
  title: intl.formatMessage(_messages.default.remove),
425
441
  onClick: withToolbarMetadata(removeCard(editorAnalyticsApi))
426
- }]) : [].concat(editButtonItems, (0, _toConsumableArray2.default)([].concat((0, _toConsumableArray2.default)(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled)), [{
442
+ }]) : [].concat(editButtonItems, (0, _toConsumableArray2.default)([].concat((0, _toConsumableArray2.default)(getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, !areAllNewToolbarFlagsDisabled, pluginInjectionApi)), [{
427
443
  type: 'separator',
428
444
  fullHeight: true
429
445
  }])), openPreviewPanelItems, [openLinkToolbarItem], (0, _toConsumableArray2.default)(commentItems.length > 1 ? [{
@@ -518,8 +534,8 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
518
534
  options: [_objectSpread({
519
535
  title: intl.formatMessage(_messages.default.copyToClipboard),
520
536
  onClick: function onClick() {
521
- var _pluginInjectionApi$c2, _pluginInjectionApi$f;
522
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.core) === null || _pluginInjectionApi$c2 === void 0 || _pluginInjectionApi$c2.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f === void 0 ? void 0 : _pluginInjectionApi$f.commands.copyNode(node.type, _enums.INPUT_METHOD.FLOATING_TB));
537
+ var _pluginInjectionApi$c3, _pluginInjectionApi$f;
538
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.core) === null || _pluginInjectionApi$c3 === void 0 || _pluginInjectionApi$c3.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f === void 0 ? void 0 : _pluginInjectionApi$f.commands.copyNode(node.type, _enums.INPUT_METHOD.FLOATING_TB));
523
539
  return true;
524
540
  },
525
541
  icon: /*#__PURE__*/_react.default.createElement(_copy.default, {
@@ -539,7 +555,7 @@ var generateToolbarItems = function generateToolbarItems(state, intl, providerFa
539
555
  }
540
556
  };
541
557
  };
542
- var getUnlinkButtonGroup = function getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, areAnyNewToolbarFlagsEnabled) {
558
+ var getUnlinkButtonGroup = function getUnlinkButtonGroup(state, intl, node, inlineCard, editorAnalyticsApi, areAnyNewToolbarFlagsEnabled, pluginInjectionApi) {
543
559
  return node.type === inlineCard ? [{
544
560
  id: 'editor.link.unlink',
545
561
  focusEditoronEnter: true,
@@ -547,7 +563,7 @@ var getUnlinkButtonGroup = function getUnlinkButtonGroup(state, intl, node, inli
547
563
  title: intl.formatMessage(_linkToolbar.linkToolbarMessages.unlink),
548
564
  icon: _linkBroken.default,
549
565
  iconFallback: _linkBroken.default,
550
- onClick: withToolbarMetadata(unlinkCard(node, state, editorAnalyticsApi))
566
+ onClick: withToolbarMetadata(unlinkCard(node, state, editorAnalyticsApi, pluginInjectionApi))
551
567
  }].concat((0, _toConsumableArray2.default)(areAnyNewToolbarFlagsEnabled ? [] : [{
552
568
  type: 'separator'
553
569
  }])) : [];
@@ -747,8 +763,8 @@ var getDatasourceButtonGroup = function getDatasourceButtonGroup(metadata, intl,
747
763
  options: [{
748
764
  title: intl.formatMessage(_messages.default.copyToClipboard),
749
765
  onClick: function onClick() {
750
- var _pluginInjectionApi$c3, _pluginInjectionApi$f2;
751
- pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.core) === null || _pluginInjectionApi$c3 === void 0 || _pluginInjectionApi$c3.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.commands.copyNode(node.type, _enums.INPUT_METHOD.FLOATING_TB));
766
+ var _pluginInjectionApi$c4, _pluginInjectionApi$f2;
767
+ pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c4 = pluginInjectionApi.core) === null || _pluginInjectionApi$c4 === void 0 || _pluginInjectionApi$c4.actions.execute(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$f2 = pluginInjectionApi.floatingToolbar) === null || _pluginInjectionApi$f2 === void 0 ? void 0 : _pluginInjectionApi$f2.commands.copyNode(node.type, _enums.INPUT_METHOD.FLOATING_TB));
752
768
  return true;
753
769
  },
754
770
  onMouseEnter: hoverDecoration === null || hoverDecoration === void 0 ? void 0 : hoverDecoration(node.type, true, _constants.akEditorSelectedNodeClassName),
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Creates a registry of resolved cards, for use with editor actions.
3
+ * Registration changes (insertion, deletion, and id/title/url updates) notify subscribers; live position changes do not.
4
+ *
5
+ * @returns A registry object with the following methods:
6
+ * - `getCardRegistrations`: Returns the current registrations, keyed by card ID.
7
+ * - `registerCard`: Adds or updates a card.
8
+ * - `removeCard`: Removes a card by ID.
9
+ * - `subscribe`: Registers a change listener and returns an unsubscribe function.
10
+ */
11
+ export const createCardRegistry = () => {
12
+ // Replace registrations on each change to notify subscribers and trigger React updates.
13
+ let registrations = {};
14
+ const listeners = new Set();
15
+ const getCardRegistrations = () => registrations;
16
+ const notify = () => {
17
+ Array.from(listeners).forEach(listener => listener());
18
+ };
19
+ const registerCard = info => {
20
+ if (info.getPos() === undefined) {
21
+ return;
22
+ }
23
+ const previous = registrations[info.id];
24
+ if (previous && previous.getPos === info.getPos && previous.title === info.title && previous.url === info.url) {
25
+ return; // Don't mutate registrations if no change
26
+ }
27
+ registrations = {
28
+ ...registrations,
29
+ [info.id]: {
30
+ ...info
31
+ }
32
+ };
33
+ notify();
34
+ };
35
+ const removeCard = id => {
36
+ if (!registrations[id]) {
37
+ return;
38
+ }
39
+ const next = {
40
+ ...registrations
41
+ };
42
+ delete next[id];
43
+ registrations = next;
44
+ notify();
45
+ };
46
+ const subscribe = listener => {
47
+ listeners.add(listener);
48
+ return () => {
49
+ listeners.delete(listener);
50
+ };
51
+ };
52
+ return {
53
+ registerCard,
54
+ removeCard,
55
+ subscribe,
56
+ getCardRegistrations
57
+ };
58
+ };
@@ -0,0 +1,9 @@
1
+ import { useSyncExternalStore } from 'react';
2
+ const emptySnapshot = () => undefined;
3
+ const emptySubscription = () => () => {};
4
+
5
+ /** Subscribe to resolved card metadata without observing every editor transaction. */
6
+ export const useCardRegistry = actions => {
7
+ var _actions$subscribeToC, _actions$getCardRegis;
8
+ return useSyncExternalStore((_actions$subscribeToC = actions === null || actions === void 0 ? void 0 : actions.subscribeToCardRegistry) !== null && _actions$subscribeToC !== void 0 ? _actions$subscribeToC : emptySubscription, (_actions$getCardRegis = actions === null || actions === void 0 ? void 0 : actions.getCardRegistrations) !== null && _actions$getCardRegis !== void 0 ? _actions$getCardRegis : emptySnapshot, emptySnapshot);
9
+ };
@@ -8,6 +8,7 @@ import { SmartCardContext } from '@atlaskit/link-provider/context';
8
8
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
9
9
  import { fg } from '@atlaskit/platform-feature-flags/fg';
10
10
  import { expValNoExposure } from '@atlaskit/tmp-editor-statsig/expVal';
11
+ import { createCardRegistry } from './actions/cardRegistry';
11
12
  import { blockCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/blockCard';
12
13
  import { embedCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/embedCard';
13
14
  import { inlineCardSpecWithFixedToDOM } from './nodeviews/toDOM-fixes/inlineCard';
@@ -44,6 +45,7 @@ export const cardPlugin = ({
44
45
  api
45
46
  }) => {
46
47
  var _api$base, _options$lpLinkPicker;
48
+ const cardRegistry = createCardRegistry();
47
49
  let previousCardProvider;
48
50
  const cardPluginEvents = createEventsQueue();
49
51
  const isRegisteredSlashCommandEnabled = isExperimentEnabled('platform_editor_slash_command');
@@ -207,6 +209,10 @@ export const cardPlugin = ({
207
209
  }, tr, from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance)
208
210
  },
209
211
  actions: {
212
+ registerCard: cardRegistry.registerCard,
213
+ removeRegisteredCard: cardRegistry.removeCard,
214
+ getCardRegistrations: cardRegistry.getCardRegistrations,
215
+ subscribeToCardRegistry: cardRegistry.subscribe,
210
216
  setProvider: async providerPromise => {
211
217
  var _api$core$actions$exe;
212
218
  const provider = await providerPromise;
@@ -39,16 +39,33 @@ export class BlockCardComponent extends React.PureComponent {
39
39
  // don't dispatch immediately since we might be in the middle of
40
40
  // rendering a nodeview
41
41
  const scheduleRegisterCard = rafSchedule(() => {
42
- const pos = getPos();
43
- if (typeof pos !== 'number') {
44
- return;
42
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
43
+ var _pluginInjectionApi$c;
44
+ if (this.removeCardDispatched || getPos() === undefined) {
45
+ return;
46
+ }
47
+ const {
48
+ pluginInjectionApi,
49
+ id
50
+ } = this.props;
51
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.registerCard({
52
+ id,
53
+ title,
54
+ url,
55
+ getPos
56
+ });
57
+ } else {
58
+ const pos = getPos();
59
+ if (typeof pos !== 'number') {
60
+ return;
61
+ }
62
+ view.dispatch(registerCard({
63
+ title,
64
+ url,
65
+ pos,
66
+ id: this.props.id
67
+ })(view.state.tr));
45
68
  }
46
- view.dispatch(registerCard({
47
- title,
48
- url,
49
- pos,
50
- id: this.props.id
51
- })(view.state.tr));
52
69
  });
53
70
  if (isExperimentEnabled('platform_editor_reduce_memory_leaks')) {
54
71
  this.pendingRegisterCard = scheduleRegisterCard;
@@ -94,13 +111,22 @@ export class BlockCardComponent extends React.PureComponent {
94
111
  return;
95
112
  }
96
113
  this.removeCardDispatched = true;
97
- const {
98
- tr
99
- } = this.props.view.state;
100
- removeCard({
101
- id: this.props.id
102
- })(tr);
103
- this.props.view.dispatch(tr);
114
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
115
+ var _pluginInjectionApi$c2;
116
+ const {
117
+ pluginInjectionApi,
118
+ id
119
+ } = this.props;
120
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c2 = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.removeRegisteredCard(id);
121
+ } else {
122
+ const {
123
+ tr
124
+ } = this.props.view.state;
125
+ removeCard({
126
+ id: this.props.id
127
+ })(tr);
128
+ this.props.view.dispatch(tr);
129
+ }
104
130
  }
105
131
  render() {
106
132
  const {
@@ -178,16 +178,33 @@ export class EmbedCardComponent extends React.PureComponent {
178
178
  // don't dispatch immediately since we might be in the middle of
179
179
  // rendering a nodeview
180
180
  rafSchedule(() => {
181
- const pos = this.getPosSafely();
182
- if (pos === undefined) {
183
- return;
181
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
182
+ var _pluginInjectionApi$c;
183
+ if (this.removeCardDispatched || this.getPosSafely() === undefined) {
184
+ return;
185
+ }
186
+ const {
187
+ pluginInjectionApi,
188
+ id
189
+ } = this.props;
190
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.registerCard({
191
+ id,
192
+ title,
193
+ url,
194
+ getPos: this.getPosSafely
195
+ });
196
+ } else {
197
+ const pos = this.getPosSafely();
198
+ if (pos === undefined) {
199
+ return;
200
+ }
201
+ return view.dispatch(registerCard({
202
+ title,
203
+ url,
204
+ pos,
205
+ id: this.props.id
206
+ })(view.state.tr));
184
207
  }
185
- return view.dispatch(registerCard({
186
- title,
187
- url,
188
- pos,
189
- id: this.props.id
190
- })(view.state.tr));
191
208
  })();
192
209
  try {
193
210
  var _this$props$cardConte, _this$props$cardConte2;
@@ -321,13 +338,22 @@ export class EmbedCardComponent extends React.PureComponent {
321
338
  return;
322
339
  }
323
340
  this.removeCardDispatched = true;
324
- const {
325
- tr
326
- } = this.props.view.state;
327
- removeCard({
328
- id: this.props.id
329
- })(tr);
330
- this.props.view.dispatch(tr);
341
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
342
+ var _pluginInjectionApi$c2;
343
+ const {
344
+ pluginInjectionApi,
345
+ id
346
+ } = this.props;
347
+ pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c2 = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.removeRegisteredCard(id);
348
+ } else {
349
+ const {
350
+ tr
351
+ } = this.props.view.state;
352
+ removeCard({
353
+ id: this.props.id
354
+ })(tr);
355
+ this.props.view.dispatch(tr);
356
+ }
331
357
  }
332
358
  render() {
333
359
  const {
@@ -45,6 +45,9 @@ export const InlineCard = /*#__PURE__*/memo(({
45
45
  }
46
46
  };
47
47
  }, []);
48
+ const cardActions = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions;
49
+ const registerResolvedCard = cardActions === null || cardActions === void 0 ? void 0 : cardActions.registerCard;
50
+ const removeRegisteredCard = cardActions === null || cardActions === void 0 ? void 0 : cardActions.removeRegisteredCard;
48
51
  const {
49
52
  getState: getSmartlinkState
50
53
  } = (cardContext === null || cardContext === void 0 ? void 0 : (_cardContext$value = cardContext.value) === null || _cardContext$value === void 0 ? void 0 : _cardContext$value.store) || {};
@@ -57,15 +60,19 @@ export const InlineCard = /*#__PURE__*/memo(({
57
60
  return;
58
61
  }
59
62
  removeCardDispatched.current = true;
60
- const {
61
- tr
62
- } = view.state;
63
- removeCard({
64
- id
65
- })(tr);
66
- view.dispatch(tr);
63
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
64
+ removeRegisteredCard === null || removeRegisteredCard === void 0 ? void 0 : removeRegisteredCard(id);
65
+ } else {
66
+ const {
67
+ tr
68
+ } = view.state;
69
+ removeCard({
70
+ id
71
+ })(tr);
72
+ view.dispatch(tr);
73
+ }
67
74
  };
68
- }, [getPos, view]);
75
+ }, [getPos, isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? undefined : view, isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? removeRegisteredCard : undefined]);
69
76
  const scrollContainer = useMemo(() => isExperimentEnabled('platform_editor_reduce_forced_layout_2') && isIntersectionObserverSupported() ? undefined :
70
77
  // eslint-disable-next-line @atlaskit/editor/no-as-casting
71
78
  findOverflowScrollParent(view.dom) || undefined, [view.dom]);
@@ -80,26 +87,40 @@ export const InlineCard = /*#__PURE__*/memo(({
80
87
  // don't dispatch immediately since we might be in the middle of
81
88
  // rendering a nodeview
82
89
  const scheduleRegisterCard = rafSchedule(() => {
83
- // prosemirror-bump-fix
84
- const pos = getPos();
85
- if (typeof pos !== 'number') {
86
- return;
90
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
91
+ if (removeCardDispatched.current || getPos() === undefined) {
92
+ return;
93
+ }
94
+ const id = refId.current;
95
+ registerResolvedCard === null || registerResolvedCard === void 0 ? void 0 : registerResolvedCard({
96
+ id,
97
+ title,
98
+ url,
99
+ getPos
100
+ });
101
+ onRes === null || onRes === void 0 ? void 0 : onRes(undefined, title);
102
+ } else {
103
+ // prosemirror-bump-fix
104
+ const pos = getPos();
105
+ if (typeof pos !== 'number') {
106
+ return;
107
+ }
108
+ const tr = view.state.tr;
109
+ registerCard({
110
+ title,
111
+ url,
112
+ pos,
113
+ id: refId.current
114
+ })(tr);
115
+ onRes === null || onRes === void 0 ? void 0 : onRes(tr, title);
116
+ view.dispatch(tr);
87
117
  }
88
- const tr = view.state.tr;
89
- registerCard({
90
- title,
91
- url,
92
- pos,
93
- id: refId.current
94
- })(tr);
95
- onRes === null || onRes === void 0 ? void 0 : onRes(tr, title);
96
- view.dispatch(tr);
97
118
  });
98
119
  if (isExperimentEnabled('platform_editor_reduce_memory_leaks')) {
99
120
  pendingRegisterCard.current = scheduleRegisterCard;
100
121
  }
101
122
  scheduleRegisterCard();
102
- }, [getPos, view, onRes]);
123
+ }, [getPos, isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? undefined : view, onRes, isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? registerResolvedCard : undefined]);
103
124
  const onError = useCallback(data => {
104
125
  const {
105
126
  url,
@@ -57,23 +57,27 @@ export const InlineCardWithAwareness = /*#__PURE__*/memo(({
57
57
  const [isResolvedViewRendered, setIsResolvedViewRendered] = useState(false);
58
58
  const editorAppearance = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$c = pluginInjectionApi.card.sharedState.currentState()) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.editorAppearance;
59
59
  const destinationUrl = useSmartLinkDestinationUrl(node.attrs.url);
60
+
61
+ // Remove tr: Transaction | undefined parameter with platform_editor_reduce_forced_layout_2 cleanup.
60
62
  const onResolve = useCallback((tr, title) => {
61
- const metadata = tr.getMeta(pluginKey);
62
- const removeOverlay = isExperimentEnabled('platform_editor_reduce_memory_leaks') ? createRemoveOverlay(setIsInsertedRef) : () => setIsInserted(false);
63
- if (metadata && metadata.type === 'REGISTER') {
64
- registerRemoveOverlay(removeOverlay, metadata.info)(tr);
65
- } else {
66
- registerRemoveOverlay(removeOverlay)(tr);
63
+ if (tr) {
64
+ const metadata = tr.getMeta(pluginKey);
65
+ const removeOverlay = isExperimentEnabled('platform_editor_reduce_memory_leaks') ? createRemoveOverlay(setIsInsertedRef) : () => setIsInserted(false);
66
+ if (metadata && metadata.type === 'REGISTER') {
67
+ registerRemoveOverlay(removeOverlay, metadata.info)(tr);
68
+ } else {
69
+ registerRemoveOverlay(removeOverlay)(tr);
70
+ }
67
71
  }
68
72
  if (title) {
69
73
  setIsResolvedViewRendered(true);
70
74
  }
71
75
  }, []);
72
76
  const markMostRecentlyInsertedLink = useCallback(isLinkMostRecentlyInserted => {
73
- if (isOverlayEnabled) {
77
+ if (isOverlayEnabled && !isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
74
78
  setIsInserted(isLinkMostRecentlyInserted);
75
79
  }
76
- }, [isOverlayEnabled]);
80
+ }, [isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? undefined : isOverlayEnabled]);
77
81
  const setOverlayHoveredStyles = useCallback(isHovered => {
78
82
  if (isOverlayEnabled) {
79
83
  setIsHovered(isHovered);
@@ -75,7 +75,7 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, editorA
75
75
 
76
76
  // If an embed card transformer is provided and the resolved card is an embedCard,
77
77
  // attempt to transform it into an alternative node representation first.
78
- if (cardData.type === 'embedCard' && embedCardNodeTransformer && fg('platform_native_embeds_rollout_non_maui_experience')) {
78
+ if (cardData.type === 'embedCard' && embedCardNodeTransformer && (fg('platform_native_embeds_rollout_non_maui_experience') || fg('platform_native_embeds_rollout_all_products'))) {
79
79
  const transformResult = embedCardNodeTransformer(schema, cardData.attrs);
80
80
  // The transformer may return a Promise for async transformations (e.g. short-link expansion).
81
81
  // When async, we snapshot the current requests and positions now (before any dispatch),
@@ -24,14 +24,16 @@ const LOCAL_STORAGE_DISCOVERY_KEY_SMART_LINK = 'smart-link-upgrade-pulse';
24
24
  // Only the first resolved inline smart link is needed for PO spotlight targeting
25
25
  const MAX_RESOLVED_INLINE_SMART_LINKS = 1;
26
26
  const handleAwarenessOverlay = view => {
27
- const currentState = getPluginState(view.state);
28
- const overlayCandidatePos = currentState === null || currentState === void 0 ? void 0 : currentState.overlayCandidatePosition;
29
- if (overlayCandidatePos) {
30
- var _currentState$removeO;
31
- (_currentState$removeO = currentState.removeOverlay) === null || _currentState$removeO === void 0 ? void 0 : _currentState$removeO.call(currentState);
32
- const tr = view.state.tr;
33
- clearOverlayCandidate(tr);
34
- view.dispatch(tr);
27
+ if (!isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
28
+ const currentState = getPluginState(view.state);
29
+ const overlayCandidatePos = currentState === null || currentState === void 0 ? void 0 : currentState.overlayCandidatePosition;
30
+ if (overlayCandidatePos) {
31
+ var _currentState$removeO;
32
+ (_currentState$removeO = currentState.removeOverlay) === null || _currentState$removeO === void 0 ? void 0 : _currentState$removeO.call(currentState);
33
+ const tr = view.state.tr;
34
+ clearOverlayCandidate(tr);
35
+ view.dispatch(tr);
36
+ }
35
37
  }
36
38
  };
37
39
  export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryParams => {
@@ -147,7 +149,7 @@ export const createPlugin = (options, pluginInjectionApi) => pmPluginFactoryPara
147
149
  const linkPosition = pluginState.requests[0].pos;
148
150
  const canBeUpgradedToBlock = allowBlockCards && isBlockSupportedAtPosition(linkPosition, prevEditorState, 'inline');
149
151
  const canBeUpgradedToEmbed = allowEmbeds && isEmbedSupportedAtPosition(linkPosition, prevEditorState, 'inline');
150
- if (canBeUpgradedToBlock || canBeUpgradedToEmbed) {
152
+ if (!isExperimentEnabled('platform_editor_reduce_forced_layout_2') && (canBeUpgradedToBlock || canBeUpgradedToEmbed)) {
151
153
  newState.overlayCandidatePosition = linkPosition;
152
154
  }
153
155
  if (!isSmartLinkPulseDiscovered && canBeUpgradedToEmbed) {
@@ -4,6 +4,7 @@ import { getResolvedAttributes } from '@atlaskit/link-analytics/get-resolved-att
4
4
  import { ASSETS_LIST_OF_LINKS_DATASOURCE_ID } from '@atlaskit/link-datasource/assets-modal';
5
5
  import { CONFLUENCE_SEARCH_DATASOURCE_ID } from '@atlaskit/link-datasource/confluence-search-modal';
6
6
  import { JIRA_LIST_OF_LINKS_DATASOURCE_ID } from '@atlaskit/link-datasource/jira-issues-modal';
7
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
7
8
  import { pluginKey } from './plugin-key';
8
9
  export const appearanceForNodeType = spec => {
9
10
  if (spec.name === 'inlineCard') {
@@ -42,12 +43,21 @@ export const mergeCardInfo = (titleUrlPair, info) => {
42
43
  };
43
44
  };
44
45
  export const displayInfoForCard = (node, info) => mergeCardInfo(titleUrlPairFromNode(node), info);
45
- export const findCardInfo = state => {
46
- const pluginState = pluginKey.getState(state);
47
- if (!pluginState) {
48
- return undefined;
46
+ export const findCardInfo = (state, cardActions) => {
47
+ if (isExperimentEnabled('platform_editor_reduce_forced_layout_2')) {
48
+ var _cardActions$getCardR, _cardActions$getCardR2;
49
+ const registrations = (_cardActions$getCardR = cardActions === null || cardActions === void 0 ? void 0 : (_cardActions$getCardR2 = cardActions.getCardRegistrations) === null || _cardActions$getCardR2 === void 0 ? void 0 : _cardActions$getCardR2.call(cardActions)) !== null && _cardActions$getCardR !== void 0 ? _cardActions$getCardR : {};
50
+ const card = Object.values(registrations).find(registration => registration.getPos() === state.selection.from);
51
+ return card ? {
52
+ id: card.id,
53
+ title: card.title,
54
+ url: card.url,
55
+ pos: state.selection.from
56
+ } : undefined;
57
+ } else {
58
+ const pluginState = pluginKey.getState(state);
59
+ return pluginState === null || pluginState === void 0 ? void 0 : pluginState.cards.find(cardInfo => cardInfo.pos === state.selection.from);
49
60
  }
50
- return pluginState.cards.find(cardInfo => cardInfo.pos === state.selection.from);
51
61
  };
52
62
  const isAppearanceSupportedInParent = (currentNodePosition, editorState, fragment, currentAppearance) => {
53
63
  const resolvedPosition = editorState.doc.resolve(currentNodePosition);
@@ -6,6 +6,7 @@ import { LINKPICKER_HEIGHT_IN_PX, RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDT
6
6
  import { HyperlinkAddToolbar as HyperlinkToolbar } from '@atlaskit/editor-common/link/HyperlinkAddToolbar';
7
7
  import { linkToolbarMessages } from '@atlaskit/editor-common/messages/link-toolbar';
8
8
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
9
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
9
10
  import { hideLinkToolbar, showLinkToolbar } from '../pm-plugins/actions';
10
11
  import { changeSelectedCardToLink, updateCard } from '../pm-plugins/doc';
11
12
  import { displayInfoForCard, findCardInfo } from '../pm-plugins/utils';
@@ -147,7 +148,7 @@ export const buildEditLinkToolbar = ({
147
148
  if (!view || !providerFactory) {
148
149
  return null;
149
150
  }
150
- const displayInfo = displayInfoForCard(node, findCardInfo(view.state));
151
+ const displayInfo = displayInfoForCard(node, findCardInfo(view.state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions));
151
152
  return /*#__PURE__*/React.createElement(EditLinkToolbar, {
152
153
  key: idx,
153
154
  view: view,
@@ -161,8 +162,9 @@ export const buildEditLinkToolbar = ({
161
162
  // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
162
163
  ,
163
164
  onSubmit: (newHref, newText, inputMethod, analytic) => {
164
- const urlChanged = newHref !== displayInfo.url;
165
- const titleChanged = newText !== displayInfo.title;
165
+ const currentDisplayInfo = isExperimentEnabled('platform_editor_reduce_forced_layout_2') ? displayInfoForCard(node, findCardInfo(view.state, pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : pluginInjectionApi.card.actions)) : displayInfo;
166
+ const urlChanged = newHref !== currentDisplayInfo.url;
167
+ const titleChanged = newText !== currentDisplayInfo.title;
166
168
 
167
169
  // If the title is changed in a smartlink, convert to standard blue hyperlink
168
170
  // (even if the url was also changed) - we don't want to lose the custom title.