@atlaskit/editor-plugin-paste-options-toolbar 13.2.9 → 13.3.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,23 @@
1
1
  # @atlaskit/editor-plugin-paste-options-toolbar
2
2
 
3
+ ## 13.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`24fdd04e3b469`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/24fdd04e3b469) -
8
+ Switch Paste as Markdown to the markdown-plus parser behind existing gates, with legacy fallback
9
+ retained. Wire the converter through Confluence preset configuration for the gated path.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 13.2.10
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+
3
21
  ## 13.2.9
4
22
 
5
23
  ### Patch Changes
@@ -107,13 +107,13 @@ var changeToRichTextWithAnalytics = exports.changeToRichTextWithAnalytics = func
107
107
  return (0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, payloadCallback)(changeToRichText());
108
108
  };
109
109
  };
110
- var changeToMarkDown = exports.changeToMarkDown = function changeToMarkDown() {
110
+ var changeToMarkDown = exports.changeToMarkDown = function changeToMarkDown(markdownToPmConverter) {
111
111
  var markdownTransformer = function markdownTransformer(tr, state) {
112
112
  var pluginState = _types.pasteOptionsPluginKey.getState(state);
113
113
  if (pluginState.selectedOption === _types.ToolbarDropdownOption.Markdown) {
114
114
  return tr;
115
115
  }
116
- return (0, _formatHandlers.formatMarkdown)(tr, pluginState);
116
+ return (0, _formatHandlers.formatMarkdown)(tr, pluginState, markdownToPmConverter);
117
117
  };
118
118
  var commandAction = function commandAction(_editorState) {
119
119
  return {
@@ -125,7 +125,7 @@ var changeToMarkDown = exports.changeToMarkDown = function changeToMarkDown() {
125
125
  };
126
126
  return (0, _pluginFactory.createCommand)(commandAction, markdownTransformer);
127
127
  };
128
- var changeToMarkdownWithAnalytics = exports.changeToMarkdownWithAnalytics = function changeToMarkdownWithAnalytics(editorAnalyticsAPI, sliceSize, invokedFrom) {
128
+ var changeToMarkdownWithAnalytics = exports.changeToMarkdownWithAnalytics = function changeToMarkdownWithAnalytics(editorAnalyticsAPI, sliceSize, invokedFrom, markdownToPmConverter) {
129
129
  return function () {
130
130
  return (0, _editorAnalytics.withAnalytics)(editorAnalyticsAPI, {
131
131
  action: _analytics.ACTION.PASTED,
@@ -138,7 +138,7 @@ var changeToMarkdownWithAnalytics = exports.changeToMarkdownWithAnalytics = func
138
138
  pasteSize: sliceSize,
139
139
  invokedFrom: invokedFrom
140
140
  }
141
- })(changeToMarkDown());
141
+ })(changeToMarkDown(markdownToPmConverter));
142
142
  };
143
143
  };
144
144
  var highlightContent = exports.highlightContent = function highlightContent() {
@@ -49,7 +49,8 @@ var pasteOptionsToolbarPlugin = exports.pasteOptionsToolbarPlugin = function pas
49
49
  if (config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('platform_editor_paste_actions_menu', 'isEnabled', true)) {
50
50
  var _api$uiControlRegistr;
51
51
  api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register((0, _PasteMenuComponents.getPasteMenuComponents)({
52
- api: api
52
+ api: api,
53
+ markdownToPmConverter: config === null || config === void 0 ? void 0 : config.markdownToPmConverter
53
54
  }));
54
55
  }
55
56
  if (config !== null && config !== void 0 && config.pasteMenuButtonsFactory && config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu) {
@@ -171,7 +172,7 @@ var pasteOptionsToolbarPlugin = exports.pasteOptionsToolbarPlugin = function pas
171
172
  }
172
173
  var pastePluginState = _types.pasteOptionsPluginKey.getState(state);
173
174
  if (pastePluginState.showToolbar) {
174
- return (0, _toolbar.buildToolbar)(state, intl, editorAnalyticsAPI);
175
+ return (0, _toolbar.buildToolbar)(state, intl, editorAnalyticsAPI, config === null || config === void 0 ? void 0 : config.markdownToPmConverter);
175
176
  }
176
177
  return;
177
178
  }
@@ -12,11 +12,13 @@ var _editorMarkdownTransformer = require("@atlaskit/editor-markdown-transformer"
12
12
  var _model = require("@atlaskit/editor-prosemirror/model");
13
13
  var _state = require("@atlaskit/editor-prosemirror/state");
14
14
  var _transform = require("@atlaskit/editor-prosemirror/transform");
15
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
15
17
  var _index = require("./index");
16
18
  // Ignored via go/ees005
17
19
  // eslint-disable-next-line require-unicode-regexp
18
20
  var CODE_BLOCK_FENCE_REGEX = /```/;
19
- var formatMarkdown = exports.formatMarkdown = function formatMarkdown(tr, pluginState) {
21
+ var formatMarkdown = exports.formatMarkdown = function formatMarkdown(tr, pluginState, markdownToPmConverter) {
20
22
  var pasteStartPos = pluginState.pasteStartPos;
21
23
  var pasteEndPos = pluginState.pasteEndPos;
22
24
  var plaintext = pluginState.plaintext;
@@ -28,7 +30,7 @@ var formatMarkdown = exports.formatMarkdown = function formatMarkdown(tr, plugin
28
30
  if (parentOffset === 0 && resolvedPasteStartPos.depth > 0) {
29
31
  pasteStartPos = resolvedPasteStartPos.before();
30
32
  }
31
- var markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection);
33
+ var markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection, markdownToPmConverter);
32
34
  if (!markdownSlice) {
33
35
  return tr;
34
36
  }
@@ -148,7 +150,12 @@ function richTextSliceTransactionWithSelectionAdjust(_ref2) {
148
150
  tr.setSelection(nextSelection);
149
151
  }
150
152
  }
151
- function getMarkdownSlice(text, schema, selection) {
153
+
154
+ /**
155
+ * Parse markdown text into a slice for paste replacement, using markdown-plus
156
+ * only when both markdown-mode experiment and paste parser gate are enabled.
157
+ */
158
+ function getMarkdownSlice(text, schema, selection, markdownToPmConverter) {
152
159
  var targetOpenStartNode = selection.$from.parent;
153
160
  var targetOpenEndNode = selection.$to.parent;
154
161
  try {
@@ -163,8 +170,10 @@ function getMarkdownSlice(text, schema, selection) {
163
170
  }
164
171
  }
165
172
  textInput = textSplitByCodeBlock.join('```');
166
- var atlassianMarkDownParser = new _editorMarkdownTransformer.MarkdownTransformer(schema, _paste.md);
167
- var doc = atlassianMarkDownParser.parse((0, _index.escapeLinks)(textInput));
173
+ var doc = markdownToPmConverter && (0, _expValEquals.expValEquals)('cc-markdown-mode', 'isEnabled', true) && (0, _platformFeatureFlags.fg)('platform_editor_paste_as_md_use_gfm_transformer') ? schema.nodes.doc.createAndFill({}, markdownToPmConverter({
174
+ markdown: textInput,
175
+ schema: schema
176
+ })) : new _editorMarkdownTransformer.MarkdownTransformer(schema, _paste.md).parse((0, _index.escapeLinks)(textInput));
168
177
  if (!doc || !doc.content) {
169
178
  return;
170
179
  }
@@ -43,7 +43,8 @@ var isPasteOptionSelected = exports.isPasteOptionSelected = function isPasteOpti
43
43
  var PasteMenuItem = function PasteMenuItem(_ref) {
44
44
  var _api$analytics;
45
45
  var api = _ref.api,
46
- pasteType = _ref.pasteType;
46
+ pasteType = _ref.pasteType,
47
+ markdownToPmConverter = _ref.markdownToPmConverter;
47
48
  var intl = (0, _reactIntl.useIntl)();
48
49
  var _useEditorToolbar = (0, _toolbar.useEditorToolbar)(),
49
50
  editorView = _useEditorToolbar.editorView;
@@ -82,13 +83,13 @@ var PasteMenuItem = function PasteMenuItem(_ref) {
82
83
  (0, _commands.changeToRichTextWithAnalytics)(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
83
84
  break;
84
85
  case 'markdown':
85
- (0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
86
+ (0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, plaintextLength, 'pasteMenu', markdownToPmConverter)()(editorView.state, editorView.dispatch);
86
87
  break;
87
88
  case 'plain-text':
88
89
  (0, _commands.changeToPlainTextWithAnalytics)(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
89
90
  break;
90
91
  }
91
- }, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
92
+ }, [editorView, editorAnalyticsAPI, markdownToPmConverter, plaintextLength, pasteType]);
92
93
  if (pasteType === 'rich-text' && isPlainText) {
93
94
  return null;
94
95
  }
@@ -146,7 +147,8 @@ var getHasVisibleAiActions = function getHasVisibleAiActions(api) {
146
147
  return (0, _hasVisibleButton.getVisibleKeys)(aiMenuItems, ['menu-item']).length > 0;
147
148
  };
148
149
  var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteMenuComponents(_ref3) {
149
- var api = _ref3.api;
150
+ var api = _ref3.api,
151
+ markdownToPmConverter = _ref3.markdownToPmConverter;
150
152
  return [{
151
153
  type: _toolbar.PASTE_MENU.type,
152
154
  key: _toolbar.PASTE_MENU.key
@@ -221,6 +223,7 @@ var getPasteMenuComponents = exports.getPasteMenuComponents = function getPasteM
221
223
  component: function component() {
222
224
  return /*#__PURE__*/_react.default.createElement(PasteMenuItem, {
223
225
  api: api,
226
+ markdownToPmConverter: markdownToPmConverter,
224
227
  pasteType: "markdown"
225
228
  });
226
229
  },
@@ -32,7 +32,7 @@ var isToolbarVisible = exports.isToolbarVisible = function isToolbarVisible(stat
32
32
  }
33
33
  return false;
34
34
  };
35
- var getToolbarMenuConfig = exports.getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI) {
35
+ var getToolbarMenuConfig = exports.getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI, markdownToPmConverter) {
36
36
  var options = [{
37
37
  id: 'editor.paste.richText',
38
38
  title: intl.formatMessage(_messages.pasteOptionsToolbarMessages.richText),
@@ -43,7 +43,7 @@ var getToolbarMenuConfig = exports.getToolbarMenuConfig = function getToolbarMen
43
43
  id: 'editor.paste.markdown',
44
44
  title: intl.formatMessage(_messages.pasteOptionsToolbarMessages.markdown),
45
45
  selected: pluginState.selectedOption === _types.ToolbarDropdownOption.Markdown,
46
- onClick: (0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, pluginState.plaintext.length)()
46
+ onClick: (0, _commands.changeToMarkdownWithAnalytics)(editorAnalyticsAPI, pluginState.plaintext.length, undefined, markdownToPmConverter)()
47
47
  }, {
48
48
  id: 'editor.paste.plainText',
49
49
  title: intl.formatMessage(_messages.pasteOptionsToolbarMessages.plainText),
@@ -63,11 +63,11 @@ var getToolbarMenuConfig = exports.getToolbarMenuConfig = function getToolbarMen
63
63
  var onToggleHandler = function onToggleHandler(state, dispatch) {
64
64
  return (0, _commands.dropdownClickHandler)()(state, dispatch);
65
65
  };
66
- var buildToolbar = exports.buildToolbar = function buildToolbar(state, intl, editorAnalyticsAPI) {
66
+ var buildToolbar = exports.buildToolbar = function buildToolbar(state, intl, editorAnalyticsAPI, markdownToPmConverter) {
67
67
  var schema = state.schema;
68
68
  var validNodes = Object.values(schema.nodes);
69
69
  var pluginState = _types.pasteOptionsPluginKey.getState(state);
70
- var menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI);
70
+ var menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI, markdownToPmConverter);
71
71
  return {
72
72
  title: intl.formatMessage(_messages.pasteOptionsToolbarMessages.pasteOptions),
73
73
  nodeType: validNodes,
@@ -95,13 +95,13 @@ export const changeToRichTextWithAnalytics = (editorAnalyticsAPI, invokedFrom) =
95
95
  };
96
96
  return withAnalytics(editorAnalyticsAPI, payloadCallback)(changeToRichText());
97
97
  };
98
- export const changeToMarkDown = () => {
98
+ export const changeToMarkDown = markdownToPmConverter => {
99
99
  const markdownTransformer = (tr, state) => {
100
100
  const pluginState = pasteOptionsPluginKey.getState(state);
101
101
  if (pluginState.selectedOption === ToolbarDropdownOption.Markdown) {
102
102
  return tr;
103
103
  }
104
- return formatMarkdown(tr, pluginState);
104
+ return formatMarkdown(tr, pluginState, markdownToPmConverter);
105
105
  };
106
106
  const commandAction = _editorState => {
107
107
  return {
@@ -113,7 +113,7 @@ export const changeToMarkDown = () => {
113
113
  };
114
114
  return createCommand(commandAction, markdownTransformer);
115
115
  };
116
- export const changeToMarkdownWithAnalytics = (editorAnalyticsAPI, sliceSize, invokedFrom) => () => {
116
+ export const changeToMarkdownWithAnalytics = (editorAnalyticsAPI, sliceSize, invokedFrom, markdownToPmConverter) => () => {
117
117
  return withAnalytics(editorAnalyticsAPI, {
118
118
  action: ACTION.PASTED,
119
119
  actionSubject: ACTION_SUBJECT.DOCUMENT,
@@ -125,7 +125,7 @@ export const changeToMarkdownWithAnalytics = (editorAnalyticsAPI, sliceSize, inv
125
125
  pasteSize: sliceSize,
126
126
  invokedFrom
127
127
  }
128
- })(changeToMarkDown());
128
+ })(changeToMarkDown(markdownToPmConverter));
129
129
  };
130
130
  export const highlightContent = () => {
131
131
  const commandAction = _editorState => {
@@ -40,7 +40,8 @@ export const pasteOptionsToolbarPlugin = ({
40
40
  if (config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu && expValEqualsNoExposure('platform_editor_paste_actions_menu', 'isEnabled', true)) {
41
41
  var _api$uiControlRegistr;
42
42
  api === null || api === void 0 ? void 0 : (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.register(getPasteMenuComponents({
43
- api
43
+ api,
44
+ markdownToPmConverter: config === null || config === void 0 ? void 0 : config.markdownToPmConverter
44
45
  }));
45
46
  }
46
47
  if (config !== null && config !== void 0 && config.pasteMenuButtonsFactory && config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu) {
@@ -157,7 +158,7 @@ export const pasteOptionsToolbarPlugin = ({
157
158
  }
158
159
  const pastePluginState = pasteOptionsPluginKey.getState(state);
159
160
  if (pastePluginState.showToolbar) {
160
- return buildToolbar(state, intl, editorAnalyticsAPI);
161
+ return buildToolbar(state, intl, editorAnalyticsAPI, config === null || config === void 0 ? void 0 : config.markdownToPmConverter);
161
162
  }
162
163
  return;
163
164
  }
@@ -5,12 +5,14 @@ import { MarkdownTransformer } from '@atlaskit/editor-markdown-transformer';
5
5
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
6
6
  import { Selection } from '@atlaskit/editor-prosemirror/state';
7
7
  import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
9
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
10
  import { escapeLinks } from './index';
9
11
 
10
12
  // Ignored via go/ees005
11
13
  // eslint-disable-next-line require-unicode-regexp
12
14
  const CODE_BLOCK_FENCE_REGEX = /```/;
13
- export const formatMarkdown = (tr, pluginState) => {
15
+ export const formatMarkdown = (tr, pluginState, markdownToPmConverter) => {
14
16
  let pasteStartPos = pluginState.pasteStartPos;
15
17
  const pasteEndPos = pluginState.pasteEndPos;
16
18
  const plaintext = pluginState.plaintext;
@@ -22,7 +24,7 @@ export const formatMarkdown = (tr, pluginState) => {
22
24
  if (parentOffset === 0 && resolvedPasteStartPos.depth > 0) {
23
25
  pasteStartPos = resolvedPasteStartPos.before();
24
26
  }
25
- const markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection);
27
+ const markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection, markdownToPmConverter);
26
28
  if (!markdownSlice) {
27
29
  return tr;
28
30
  }
@@ -144,7 +146,12 @@ function richTextSliceTransactionWithSelectionAdjust({
144
146
  tr.setSelection(nextSelection);
145
147
  }
146
148
  }
147
- export function getMarkdownSlice(text, schema, selection) {
149
+
150
+ /**
151
+ * Parse markdown text into a slice for paste replacement, using markdown-plus
152
+ * only when both markdown-mode experiment and paste parser gate are enabled.
153
+ */
154
+ export function getMarkdownSlice(text, schema, selection, markdownToPmConverter) {
148
155
  const targetOpenStartNode = selection.$from.parent;
149
156
  const targetOpenEndNode = selection.$to.parent;
150
157
  try {
@@ -159,8 +166,10 @@ export function getMarkdownSlice(text, schema, selection) {
159
166
  }
160
167
  }
161
168
  textInput = textSplitByCodeBlock.join('```');
162
- const atlassianMarkDownParser = new MarkdownTransformer(schema, md);
163
- const doc = atlassianMarkDownParser.parse(escapeLinks(textInput));
169
+ const doc = markdownToPmConverter && expValEquals('cc-markdown-mode', 'isEnabled', true) && fg('platform_editor_paste_as_md_use_gfm_transformer') ? schema.nodes.doc.createAndFill({}, markdownToPmConverter({
170
+ markdown: textInput,
171
+ schema
172
+ })) : new MarkdownTransformer(schema, md).parse(escapeLinks(textInput));
164
173
  if (!doc || !doc.content) {
165
174
  return;
166
175
  }
@@ -33,7 +33,8 @@ export const isPasteOptionSelected = (pasteType, selectedOption) => {
33
33
  };
34
34
  const PasteMenuItem = ({
35
35
  api,
36
- pasteType
36
+ pasteType,
37
+ markdownToPmConverter
37
38
  }) => {
38
39
  var _api$analytics;
39
40
  const intl = useIntl();
@@ -76,13 +77,13 @@ const PasteMenuItem = ({
76
77
  changeToRichTextWithAnalytics(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
77
78
  break;
78
79
  case 'markdown':
79
- changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
80
+ changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu', markdownToPmConverter)()(editorView.state, editorView.dispatch);
80
81
  break;
81
82
  case 'plain-text':
82
83
  changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
83
84
  break;
84
85
  }
85
- }, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
86
+ }, [editorView, editorAnalyticsAPI, markdownToPmConverter, plaintextLength, pasteType]);
86
87
  if (pasteType === 'rich-text' && isPlainText) {
87
88
  return null;
88
89
  }
@@ -139,7 +140,8 @@ const getHasVisibleAiActions = api => {
139
140
  return getVisibleKeys(aiMenuItems, ['menu-item']).length > 0;
140
141
  };
141
142
  export const getPasteMenuComponents = ({
142
- api
143
+ api,
144
+ markdownToPmConverter
143
145
  }) => [{
144
146
  type: PASTE_MENU.type,
145
147
  key: PASTE_MENU.key
@@ -209,6 +211,7 @@ export const getPasteMenuComponents = ({
209
211
  type: PASTE_MARKDOWN_MENU_ITEM.type,
210
212
  component: () => /*#__PURE__*/React.createElement(PasteMenuItem, {
211
213
  api: api,
214
+ markdownToPmConverter: markdownToPmConverter,
212
215
  pasteType: "markdown"
213
216
  }),
214
217
  parents: [{
@@ -25,7 +25,7 @@ export const isToolbarVisible = (state, lastContentPasted) => {
25
25
  }
26
26
  return false;
27
27
  };
28
- export const getToolbarMenuConfig = (pluginState, intl, editorAnalyticsAPI) => {
28
+ export const getToolbarMenuConfig = (pluginState, intl, editorAnalyticsAPI, markdownToPmConverter) => {
29
29
  const options = [{
30
30
  id: 'editor.paste.richText',
31
31
  title: intl.formatMessage(messages.richText),
@@ -36,7 +36,7 @@ export const getToolbarMenuConfig = (pluginState, intl, editorAnalyticsAPI) => {
36
36
  id: 'editor.paste.markdown',
37
37
  title: intl.formatMessage(messages.markdown),
38
38
  selected: pluginState.selectedOption === ToolbarDropdownOption.Markdown,
39
- onClick: changeToMarkdownWithAnalytics(editorAnalyticsAPI, pluginState.plaintext.length)()
39
+ onClick: changeToMarkdownWithAnalytics(editorAnalyticsAPI, pluginState.plaintext.length, undefined, markdownToPmConverter)()
40
40
  }, {
41
41
  id: 'editor.paste.plainText',
42
42
  title: intl.formatMessage(messages.plainText),
@@ -56,13 +56,13 @@ export const getToolbarMenuConfig = (pluginState, intl, editorAnalyticsAPI) => {
56
56
  const onToggleHandler = (state, dispatch) => {
57
57
  return dropdownClickHandler()(state, dispatch);
58
58
  };
59
- export const buildToolbar = (state, intl, editorAnalyticsAPI) => {
59
+ export const buildToolbar = (state, intl, editorAnalyticsAPI, markdownToPmConverter) => {
60
60
  const {
61
61
  schema
62
62
  } = state;
63
63
  const validNodes = Object.values(schema.nodes);
64
64
  const pluginState = pasteOptionsPluginKey.getState(state);
65
- const menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI);
65
+ const menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI, markdownToPmConverter);
66
66
  return {
67
67
  title: intl.formatMessage(messages.pasteOptions),
68
68
  nodeType: validNodes,
@@ -101,13 +101,13 @@ export var changeToRichTextWithAnalytics = function changeToRichTextWithAnalytic
101
101
  return withAnalytics(editorAnalyticsAPI, payloadCallback)(changeToRichText());
102
102
  };
103
103
  };
104
- export var changeToMarkDown = function changeToMarkDown() {
104
+ export var changeToMarkDown = function changeToMarkDown(markdownToPmConverter) {
105
105
  var markdownTransformer = function markdownTransformer(tr, state) {
106
106
  var pluginState = pasteOptionsPluginKey.getState(state);
107
107
  if (pluginState.selectedOption === ToolbarDropdownOption.Markdown) {
108
108
  return tr;
109
109
  }
110
- return formatMarkdown(tr, pluginState);
110
+ return formatMarkdown(tr, pluginState, markdownToPmConverter);
111
111
  };
112
112
  var commandAction = function commandAction(_editorState) {
113
113
  return {
@@ -119,7 +119,7 @@ export var changeToMarkDown = function changeToMarkDown() {
119
119
  };
120
120
  return createCommand(commandAction, markdownTransformer);
121
121
  };
122
- export var changeToMarkdownWithAnalytics = function changeToMarkdownWithAnalytics(editorAnalyticsAPI, sliceSize, invokedFrom) {
122
+ export var changeToMarkdownWithAnalytics = function changeToMarkdownWithAnalytics(editorAnalyticsAPI, sliceSize, invokedFrom, markdownToPmConverter) {
123
123
  return function () {
124
124
  return withAnalytics(editorAnalyticsAPI, {
125
125
  action: ACTION.PASTED,
@@ -132,7 +132,7 @@ export var changeToMarkdownWithAnalytics = function changeToMarkdownWithAnalytic
132
132
  pasteSize: sliceSize,
133
133
  invokedFrom: invokedFrom
134
134
  }
135
- })(changeToMarkDown());
135
+ })(changeToMarkDown(markdownToPmConverter));
136
136
  };
137
137
  };
138
138
  export var highlightContent = function highlightContent() {
@@ -41,7 +41,8 @@ export var pasteOptionsToolbarPlugin = function pasteOptionsToolbarPlugin(_ref)
41
41
  if (config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu && expValEqualsNoExposure('platform_editor_paste_actions_menu', 'isEnabled', true)) {
42
42
  var _api$uiControlRegistr;
43
43
  api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register(getPasteMenuComponents({
44
- api: api
44
+ api: api,
45
+ markdownToPmConverter: config === null || config === void 0 ? void 0 : config.markdownToPmConverter
45
46
  }));
46
47
  }
47
48
  if (config !== null && config !== void 0 && config.pasteMenuButtonsFactory && config !== null && config !== void 0 && config.usePopupBasedPasteActionsMenu) {
@@ -163,7 +164,7 @@ export var pasteOptionsToolbarPlugin = function pasteOptionsToolbarPlugin(_ref)
163
164
  }
164
165
  var pastePluginState = pasteOptionsPluginKey.getState(state);
165
166
  if (pastePluginState.showToolbar) {
166
- return buildToolbar(state, intl, editorAnalyticsAPI);
167
+ return buildToolbar(state, intl, editorAnalyticsAPI, config === null || config === void 0 ? void 0 : config.markdownToPmConverter);
167
168
  }
168
169
  return;
169
170
  }
@@ -5,12 +5,14 @@ import { MarkdownTransformer } from '@atlaskit/editor-markdown-transformer';
5
5
  import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
6
6
  import { Selection } from '@atlaskit/editor-prosemirror/state';
7
7
  import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
9
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
8
10
  import { escapeLinks } from './index';
9
11
 
10
12
  // Ignored via go/ees005
11
13
  // eslint-disable-next-line require-unicode-regexp
12
14
  var CODE_BLOCK_FENCE_REGEX = /```/;
13
- export var formatMarkdown = function formatMarkdown(tr, pluginState) {
15
+ export var formatMarkdown = function formatMarkdown(tr, pluginState, markdownToPmConverter) {
14
16
  var pasteStartPos = pluginState.pasteStartPos;
15
17
  var pasteEndPos = pluginState.pasteEndPos;
16
18
  var plaintext = pluginState.plaintext;
@@ -22,7 +24,7 @@ export var formatMarkdown = function formatMarkdown(tr, pluginState) {
22
24
  if (parentOffset === 0 && resolvedPasteStartPos.depth > 0) {
23
25
  pasteStartPos = resolvedPasteStartPos.before();
24
26
  }
25
- var markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection);
27
+ var markdownSlice = getMarkdownSlice(plaintext, tr.doc.type.schema, tr.selection, markdownToPmConverter);
26
28
  if (!markdownSlice) {
27
29
  return tr;
28
30
  }
@@ -142,7 +144,12 @@ function richTextSliceTransactionWithSelectionAdjust(_ref2) {
142
144
  tr.setSelection(nextSelection);
143
145
  }
144
146
  }
145
- export function getMarkdownSlice(text, schema, selection) {
147
+
148
+ /**
149
+ * Parse markdown text into a slice for paste replacement, using markdown-plus
150
+ * only when both markdown-mode experiment and paste parser gate are enabled.
151
+ */
152
+ export function getMarkdownSlice(text, schema, selection, markdownToPmConverter) {
146
153
  var targetOpenStartNode = selection.$from.parent;
147
154
  var targetOpenEndNode = selection.$to.parent;
148
155
  try {
@@ -157,8 +164,10 @@ export function getMarkdownSlice(text, schema, selection) {
157
164
  }
158
165
  }
159
166
  textInput = textSplitByCodeBlock.join('```');
160
- var atlassianMarkDownParser = new MarkdownTransformer(schema, md);
161
- var doc = atlassianMarkDownParser.parse(escapeLinks(textInput));
167
+ var doc = markdownToPmConverter && expValEquals('cc-markdown-mode', 'isEnabled', true) && fg('platform_editor_paste_as_md_use_gfm_transformer') ? schema.nodes.doc.createAndFill({}, markdownToPmConverter({
168
+ markdown: textInput,
169
+ schema: schema
170
+ })) : new MarkdownTransformer(schema, md).parse(escapeLinks(textInput));
162
171
  if (!doc || !doc.content) {
163
172
  return;
164
173
  }
@@ -34,7 +34,8 @@ export var isPasteOptionSelected = function isPasteOptionSelected(pasteType, sel
34
34
  var PasteMenuItem = function PasteMenuItem(_ref) {
35
35
  var _api$analytics;
36
36
  var api = _ref.api,
37
- pasteType = _ref.pasteType;
37
+ pasteType = _ref.pasteType,
38
+ markdownToPmConverter = _ref.markdownToPmConverter;
38
39
  var intl = useIntl();
39
40
  var _useEditorToolbar = useEditorToolbar(),
40
41
  editorView = _useEditorToolbar.editorView;
@@ -73,13 +74,13 @@ var PasteMenuItem = function PasteMenuItem(_ref) {
73
74
  changeToRichTextWithAnalytics(editorAnalyticsAPI, 'pasteMenu')()(editorView.state, editorView.dispatch);
74
75
  break;
75
76
  case 'markdown':
76
- changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
77
+ changeToMarkdownWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu', markdownToPmConverter)()(editorView.state, editorView.dispatch);
77
78
  break;
78
79
  case 'plain-text':
79
80
  changeToPlainTextWithAnalytics(editorAnalyticsAPI, plaintextLength, 'pasteMenu')()(editorView.state, editorView.dispatch);
80
81
  break;
81
82
  }
82
- }, [editorView, editorAnalyticsAPI, plaintextLength, pasteType]);
83
+ }, [editorView, editorAnalyticsAPI, markdownToPmConverter, plaintextLength, pasteType]);
83
84
  if (pasteType === 'rich-text' && isPlainText) {
84
85
  return null;
85
86
  }
@@ -137,7 +138,8 @@ var getHasVisibleAiActions = function getHasVisibleAiActions(api) {
137
138
  return getVisibleKeys(aiMenuItems, ['menu-item']).length > 0;
138
139
  };
139
140
  export var getPasteMenuComponents = function getPasteMenuComponents(_ref3) {
140
- var api = _ref3.api;
141
+ var api = _ref3.api,
142
+ markdownToPmConverter = _ref3.markdownToPmConverter;
141
143
  return [{
142
144
  type: PASTE_MENU.type,
143
145
  key: PASTE_MENU.key
@@ -212,6 +214,7 @@ export var getPasteMenuComponents = function getPasteMenuComponents(_ref3) {
212
214
  component: function component() {
213
215
  return /*#__PURE__*/React.createElement(PasteMenuItem, {
214
216
  api: api,
217
+ markdownToPmConverter: markdownToPmConverter,
215
218
  pasteType: "markdown"
216
219
  });
217
220
  },
@@ -25,7 +25,7 @@ export var isToolbarVisible = function isToolbarVisible(state, lastContentPasted
25
25
  }
26
26
  return false;
27
27
  };
28
- export var getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI) {
28
+ export var getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI, markdownToPmConverter) {
29
29
  var options = [{
30
30
  id: 'editor.paste.richText',
31
31
  title: intl.formatMessage(messages.richText),
@@ -36,7 +36,7 @@ export var getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, int
36
36
  id: 'editor.paste.markdown',
37
37
  title: intl.formatMessage(messages.markdown),
38
38
  selected: pluginState.selectedOption === ToolbarDropdownOption.Markdown,
39
- onClick: changeToMarkdownWithAnalytics(editorAnalyticsAPI, pluginState.plaintext.length)()
39
+ onClick: changeToMarkdownWithAnalytics(editorAnalyticsAPI, pluginState.plaintext.length, undefined, markdownToPmConverter)()
40
40
  }, {
41
41
  id: 'editor.paste.plainText',
42
42
  title: intl.formatMessage(messages.plainText),
@@ -56,11 +56,11 @@ export var getToolbarMenuConfig = function getToolbarMenuConfig(pluginState, int
56
56
  var onToggleHandler = function onToggleHandler(state, dispatch) {
57
57
  return dropdownClickHandler()(state, dispatch);
58
58
  };
59
- export var buildToolbar = function buildToolbar(state, intl, editorAnalyticsAPI) {
59
+ export var buildToolbar = function buildToolbar(state, intl, editorAnalyticsAPI, markdownToPmConverter) {
60
60
  var schema = state.schema;
61
61
  var validNodes = Object.values(schema.nodes);
62
62
  var pluginState = pasteOptionsPluginKey.getState(state);
63
- var menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI);
63
+ var menu = getToolbarMenuConfig(pluginState, intl, editorAnalyticsAPI, markdownToPmConverter);
64
64
  return {
65
65
  title: intl.formatMessage(messages.pasteOptions),
66
66
  nodeType: validNodes,
@@ -2,6 +2,7 @@ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
2
2
  import type { Command } from '@atlaskit/editor-common/types';
3
3
  import type { LastContentPasted } from '@atlaskit/editor-plugin-paste';
4
4
  import type { EditorView } from '@atlaskit/editor-prosemirror/view';
5
+ import type { MarkdownToPmConverter } from '../pasteOptionsToolbarPluginType';
5
6
  import { ToolbarDropdownOption } from '../types/types';
6
7
  export declare const showToolbar: (lastContentPasted: LastContentPasted, selectedOption: ToolbarDropdownOption, showLegacyOptions?: boolean, pasteAncestorNodeNames?: string[]) => Command;
7
8
  export declare const changeToPlainText: () => Command;
@@ -9,8 +10,8 @@ export declare const changeToPlainTextWithAnalytics: (editorAnalyticsAPI: Editor
9
10
  export declare const dropdownClickHandler: () => Command;
10
11
  export declare const changeToRichText: () => Command;
11
12
  export declare const changeToRichTextWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined, invokedFrom?: string) => () => Command;
12
- export declare const changeToMarkDown: () => Command;
13
- export declare const changeToMarkdownWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined, sliceSize: number, invokedFrom?: string) => () => Command;
13
+ export declare const changeToMarkDown: (markdownToPmConverter?: MarkdownToPmConverter) => Command;
14
+ export declare const changeToMarkdownWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined, sliceSize: number, invokedFrom?: string, markdownToPmConverter?: MarkdownToPmConverter) => () => Command;
14
15
  export declare const highlightContent: () => Command;
15
16
  export declare const hideToolbar: () => Command;
16
17
  export declare const checkAndHideToolbar: (view: EditorView) => void;
@@ -2,6 +2,7 @@ import type { NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/t
2
2
  import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
3
3
  import type { PastePlugin } from '@atlaskit/editor-plugin-paste';
4
4
  import type { UiControlRegistryPlugin } from '@atlaskit/editor-plugin-ui-control-registry';
5
+ import type { Fragment, Schema } from '@atlaskit/editor-prosemirror/model';
5
6
  import type { RegisterComponent } from '@atlaskit/editor-ui-control-model';
6
7
  import type { ToolbarDropdownOption } from './types/types';
7
8
  import type { PasteMenuRuleFactories } from './ui/utils/paste-menu-rules/types';
@@ -27,7 +28,12 @@ export type PasteOptionsToolbarPasteMenuContext = {
27
28
  pasteStartPos: number;
28
29
  } | undefined;
29
30
  };
31
+ export type MarkdownToPmConverter = (params: {
32
+ markdown: string;
33
+ schema: Schema;
34
+ }) => Fragment;
30
35
  export type PasteOptionsToolbarPluginConfiguration = {
36
+ markdownToPmConverter?: MarkdownToPmConverter;
31
37
  /**
32
38
  * Optional factory for composing product-specific paste menu buttons.
33
39
  * Called with the pre-bound rule factories so products can compose
@@ -2,8 +2,13 @@ import type { Schema } from '@atlaskit/editor-prosemirror/model';
2
2
  import { Slice } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
4
4
  import { Selection } from '@atlaskit/editor-prosemirror/state';
5
+ import type { MarkdownToPmConverter } from '../../pasteOptionsToolbarPluginType';
5
6
  import type { PasteOptionsPluginState } from '../../types/types';
6
- export declare const formatMarkdown: (tr: Transaction, pluginState: PasteOptionsPluginState) => Transaction;
7
+ export declare const formatMarkdown: (tr: Transaction, pluginState: PasteOptionsPluginState, markdownToPmConverter?: MarkdownToPmConverter) => Transaction;
7
8
  export declare const formatRichText: (tr: Transaction, pluginState: PasteOptionsPluginState) => Transaction;
8
9
  export declare const formatPlainText: (tr: Transaction, pluginState: PasteOptionsPluginState) => Transaction;
9
- export declare function getMarkdownSlice(text: string, schema: Schema, selection: Selection): Slice | undefined;
10
+ /**
11
+ * Parse markdown text into a slice for paste replacement, using markdown-plus
12
+ * only when both markdown-mode experiment and paste parser gate are enabled.
13
+ */
14
+ export declare function getMarkdownSlice(text: string, schema: Schema, selection: Selection, markdownToPmConverter?: MarkdownToPmConverter): Slice | undefined;
@@ -1,10 +1,11 @@
1
1
  import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
2
2
  import type { RegisterComponent } from '@atlaskit/editor-ui-control-model';
3
- import type { PasteOptionsToolbarPlugin } from '../../pasteOptionsToolbarPluginType';
3
+ import type { MarkdownToPmConverter, PasteOptionsToolbarPlugin } from '../../pasteOptionsToolbarPluginType';
4
4
  import { ToolbarDropdownOption, type PasteType } from '../../types/types';
5
5
  export declare const isPasteOptionSelected: (pasteType: PasteType, selectedOption: ToolbarDropdownOption) => boolean;
6
6
  interface PasteMenuComponentsConfig {
7
7
  api: ExtractInjectionAPI<PasteOptionsToolbarPlugin> | undefined;
8
+ markdownToPmConverter?: MarkdownToPmConverter;
8
9
  }
9
- export declare const getPasteMenuComponents: ({ api }: PasteMenuComponentsConfig) => RegisterComponent[];
10
+ export declare const getPasteMenuComponents: ({ api, markdownToPmConverter, }: PasteMenuComponentsConfig) => RegisterComponent[];
10
11
  export {};
@@ -3,7 +3,7 @@ import type { RegisterComponent } from '@atlaskit/editor-ui-control-model';
3
3
  * Returns the keys of visible button/menu-item components in the list.
4
4
  * A component is visible when neither it nor any of its ancestors are hidden.
5
5
  */
6
- export declare const getVisibleKeys: (components: RegisterComponent[], types?: RegisterComponent["type"][]) => string[];
6
+ export declare const getVisibleKeys: (components: RegisterComponent[], types?: RegisterComponent['type'][]) => string[];
7
7
  /**
8
8
  * Returns true when at least one menu-item button in the list is visible.
9
9
  * A button is visible when neither it nor any of its ancestors are hidden.
@@ -3,7 +3,8 @@ import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
3
3
  import type { Command, FloatingToolbarConfig, FloatingToolbarDropdown } from '@atlaskit/editor-common/types';
4
4
  import type { LastContentPasted } from '@atlaskit/editor-plugin-paste';
5
5
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
6
+ import type { MarkdownToPmConverter } from '../pasteOptionsToolbarPluginType';
6
7
  import type { PasteOptionsPluginState } from '../types/types';
7
8
  export declare const isToolbarVisible: (state: EditorState, lastContentPasted: LastContentPasted) => boolean;
8
- export declare const getToolbarMenuConfig: (pluginState: PasteOptionsPluginState, intl: IntlShape, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => FloatingToolbarDropdown<Command>;
9
- export declare const buildToolbar: (state: EditorState, intl: IntlShape, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => FloatingToolbarConfig | undefined;
9
+ export declare const getToolbarMenuConfig: (pluginState: PasteOptionsPluginState, intl: IntlShape, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, markdownToPmConverter?: MarkdownToPmConverter) => FloatingToolbarDropdown<Command>;
10
+ export declare const buildToolbar: (state: EditorState, intl: IntlShape, editorAnalyticsAPI: EditorAnalyticsAPI | undefined, markdownToPmConverter?: MarkdownToPmConverter) => FloatingToolbarConfig | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-paste-options-toolbar",
3
- "version": "13.2.9",
3
+ "version": "13.3.0",
4
4
  "description": "Paste options toolbar for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -22,7 +22,7 @@
22
22
  "atlaskit:src": "src/index.ts",
23
23
  "dependencies": {
24
24
  "@atlaskit/css": "^1.0.0",
25
- "@atlaskit/dropdown-menu": "^17.1.0",
25
+ "@atlaskit/dropdown-menu": "^17.2.0",
26
26
  "@atlaskit/editor-markdown-transformer": "^6.0.0",
27
27
  "@atlaskit/editor-plugin-analytics": "^12.0.0",
28
28
  "@atlaskit/editor-plugin-paste": "^13.4.0",
@@ -31,17 +31,17 @@
31
31
  "@atlaskit/editor-shared-styles": "^4.0.0",
32
32
  "@atlaskit/editor-toolbar": "^2.3.0",
33
33
  "@atlaskit/editor-ui-control-model": "^2.2.0",
34
- "@atlaskit/icon": "^37.1.0",
34
+ "@atlaskit/icon": "^37.2.0",
35
35
  "@atlaskit/platform-feature-flags": "^2.1.0",
36
36
  "@atlaskit/primitives": "^22.2.0",
37
- "@atlaskit/tmp-editor-statsig": "^133.0.0",
37
+ "@atlaskit/tmp-editor-statsig": "^135.0.0",
38
38
  "@atlaskit/tokens": "^16.3.0",
39
39
  "@babel/runtime": "^7.0.0",
40
40
  "@compiled/react": "^1.0.0",
41
41
  "@emotion/react": "^11.7.1"
42
42
  },
43
43
  "peerDependencies": {
44
- "@atlaskit/editor-common": "^116.39.0",
44
+ "@atlaskit/editor-common": "^116.41.0",
45
45
  "react": "^18.2.0",
46
46
  "react-dom": "^18.2.0",
47
47
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
@@ -65,6 +65,9 @@
65
65
  },
66
66
  "platform_editor_paste_actions_menu_v2_exposure": {
67
67
  "type": "boolean"
68
+ },
69
+ "platform_editor_paste_as_md_use_gfm_transformer": {
70
+ "type": "boolean"
68
71
  }
69
72
  },
70
73
  "techstack": {