@atlaskit/editor-plugin-paste 15.0.2 → 15.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.
- package/CHANGELOG.md +26 -0
- package/dist/cjs/pastePlugin.js +4 -5
- package/dist/cjs/pm-plugins/main.js +6 -4
- package/dist/cjs/pm-plugins/reducer.js +0 -5
- package/dist/cjs/pm-plugins/util/get-markdown-slice.js +40 -0
- package/dist/cjs/pm-plugins/util/index.js +5 -2
- package/dist/cjs/pm-plugins/util/sync-block.js +1 -1
- package/dist/es2019/pastePlugin.js +4 -5
- package/dist/es2019/pm-plugins/main.js +6 -4
- package/dist/es2019/pm-plugins/reducer.js +0 -5
- package/dist/es2019/pm-plugins/util/get-markdown-slice.js +35 -0
- package/dist/es2019/pm-plugins/util/index.js +5 -2
- package/dist/es2019/pm-plugins/util/sync-block.js +1 -1
- package/dist/esm/pastePlugin.js +4 -5
- package/dist/esm/pm-plugins/main.js +6 -4
- package/dist/esm/pm-plugins/reducer.js +0 -5
- package/dist/esm/pm-plugins/util/get-markdown-slice.js +35 -0
- package/dist/esm/pm-plugins/util/index.js +5 -2
- package/dist/esm/pm-plugins/util/sync-block.js +1 -1
- package/dist/types/entry-points/paste-plugin-type.d.ts +1 -1
- package/dist/types/pastePluginType.d.ts +11 -1
- package/dist/types/pm-plugins/main.d.ts +2 -2
- package/dist/types/pm-plugins/util/get-markdown-slice.d.ts +14 -0
- package/dist/types/pm-plugins/util/index.d.ts +3 -1
- package/package.json +5 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste
|
|
2
2
|
|
|
3
|
+
## 15.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`0b4753c0a8c07`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0b4753c0a8c07) -
|
|
8
|
+
Clean up feature gates from completed rollout
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 15.1.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`a006cb2cc79f9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a006cb2cc79f9) -
|
|
16
|
+
Use the GFM markdown transformer for Cmd+V plain-text paste when
|
|
17
|
+
`platform_editor_paste_as_md_use_gfm` is enabled, matching the existing paste-as-markdown
|
|
18
|
+
(Shift+Cmd+V) path.
|
|
19
|
+
|
|
20
|
+
Consumers can inject a converter via `PastePluginOptions.markdownToPmConverter` and gate usage
|
|
21
|
+
with:
|
|
22
|
+
|
|
23
|
+
`expValEquals('platform_editor_paste_as_md_use_gfm', 'isEnabled', true)`.
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies
|
|
28
|
+
|
|
3
29
|
## 15.0.2
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/dist/cjs/pastePlugin.js
CHANGED
|
@@ -6,8 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
});
|
|
7
7
|
exports.pastePlugin = void 0;
|
|
8
8
|
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
10
|
-
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
11
9
|
var _main = require("./pm-plugins/main");
|
|
12
10
|
var _plugin = require("./pm-plugins/move-analytics/plugin");
|
|
13
11
|
var _pluginFactory = require("./pm-plugins/plugin-factory");
|
|
@@ -20,7 +18,8 @@ var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
|
|
|
20
18
|
cardOptions = _ref2.cardOptions,
|
|
21
19
|
sanitizePrivateContent = _ref2.sanitizePrivateContent,
|
|
22
20
|
isFullPage = _ref2.isFullPage,
|
|
23
|
-
pasteWarningOptions = _ref2.pasteWarningOptions
|
|
21
|
+
pasteWarningOptions = _ref2.pasteWarningOptions,
|
|
22
|
+
markdownToPmConverter = _ref2.markdownToPmConverter;
|
|
24
23
|
var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
25
24
|
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
26
25
|
return {
|
|
@@ -34,7 +33,7 @@ var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
|
|
|
34
33
|
dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent,
|
|
35
34
|
dispatch = _ref3.dispatch,
|
|
36
35
|
getIntl = _ref3.getIntl;
|
|
37
|
-
return (0, _main.createPlugin)(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions);
|
|
36
|
+
return (0, _main.createPlugin)(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter);
|
|
38
37
|
}
|
|
39
38
|
}, {
|
|
40
39
|
name: 'moveAnalyticsPlugin',
|
|
@@ -44,7 +43,7 @@ var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
|
|
|
44
43
|
}
|
|
45
44
|
}];
|
|
46
45
|
},
|
|
47
|
-
contentComponent:
|
|
46
|
+
contentComponent: function contentComponent() {
|
|
48
47
|
if (!pasteWarningOptions) {
|
|
49
48
|
return null;
|
|
50
49
|
}
|
|
@@ -40,6 +40,7 @@ var _createClipboardTextSerializer = require("./create-clipboard-text-serializer
|
|
|
40
40
|
var _pluginFactory = require("./plugin-factory");
|
|
41
41
|
var _util = require("./util");
|
|
42
42
|
var _handleVSCodeBlock = require("./util/edge-cases/handleVSCodeBlock");
|
|
43
|
+
var _getMarkdownSlice = require("./util/get-markdown-slice");
|
|
43
44
|
var _handlers = require("./util/handlers");
|
|
44
45
|
var _normalizePastedCodeBlockAttrs = require("./util/normalize-pasted-code-block-attrs");
|
|
45
46
|
var _syncBlock2 = require("./util/sync-block");
|
|
@@ -85,11 +86,14 @@ function isSharePointUrl(url) {
|
|
|
85
86
|
return false;
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
|
-
function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions) {
|
|
89
|
+
function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter) {
|
|
89
90
|
var _pluginInjectionApi$a;
|
|
90
91
|
var editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
|
|
91
92
|
var atlassianMarkDownParser = new _editorMarkdownTransformer.MarkdownTransformer(schema, _paste.md);
|
|
92
93
|
function getMarkdownSlice(text, openStart, openEnd) {
|
|
94
|
+
if (markdownToPmConverter && (0, _expValEquals.expValEquals)('platform_editor_paste_as_md_use_gfm', 'isEnabled', true)) {
|
|
95
|
+
return (0, _getMarkdownSlice.getMarkdownSliceViaGfm)(text, schema, openStart, openEnd, markdownToPmConverter);
|
|
96
|
+
}
|
|
93
97
|
var escapedTextInput = (0, _util.escapeBackslashAndLinksExceptCodeBlock)(text);
|
|
94
98
|
var doc = atlassianMarkDownParser.parse(escapedTextInput);
|
|
95
99
|
if (doc && doc.content) {
|
|
@@ -375,9 +379,7 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
|
|
|
375
379
|
event: event,
|
|
376
380
|
text: text
|
|
377
381
|
});
|
|
378
|
-
|
|
379
|
-
slice = (0, _syncBlock2.handleSyncBlocksPaste)(slice, schema, (0, _util.getPasteSource)(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
380
|
-
}
|
|
382
|
+
slice = (0, _syncBlock2.handleSyncBlocksPaste)(slice, schema, (0, _util.getPasteSource)(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
381
383
|
var plainTextPasteSlice = (0, _utils.linkifyContent)(state.schema)(slice);
|
|
382
384
|
if ((0, _analytics2.handlePasteAsPlainTextWithAnalytics)(editorAnalyticsAPI)(view, event, plainTextPasteSlice)(state, dispatch, view)) {
|
|
383
385
|
return true;
|
|
@@ -7,8 +7,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.reducer = void 0;
|
|
8
8
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
9
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
11
|
-
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
12
10
|
var _actions = require("../editor-actions/actions");
|
|
13
11
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
14
12
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -39,9 +37,6 @@ var reducer = exports.reducer = function reducer(state, action) {
|
|
|
39
37
|
}
|
|
40
38
|
case _actions.PastePluginActionTypes.SET_ACTIVE_FLAG:
|
|
41
39
|
{
|
|
42
|
-
if (!(0, _experiments.editorExperiment)('platform_synced_block', true) && !(0, _platformFeatureFlags.fg)('platform_synced_block_unsupported_products')) {
|
|
43
|
-
return state;
|
|
44
|
-
}
|
|
45
40
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
46
41
|
activeFlag: action.activeFlag
|
|
47
42
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getMarkdownSliceViaGfm = getMarkdownSliceViaGfm;
|
|
7
|
+
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
8
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
9
|
+
var _index = require("./index");
|
|
10
|
+
/**
|
|
11
|
+
* Convert plain-text markdown to a ProseMirror Slice using the GFM converter.
|
|
12
|
+
*
|
|
13
|
+
* Only called when `platform_editor_paste_as_md_use_gfm` is enabled AND a
|
|
14
|
+
* `markdownToPmConverter` is provided. Returns `undefined` if the converter
|
|
15
|
+
* throws or produces an empty document — the caller will propagate `undefined`
|
|
16
|
+
* without falling back to the legacy MarkdownTransformer.
|
|
17
|
+
*/
|
|
18
|
+
function getMarkdownSliceViaGfm(text, schema, openStart, openEnd, markdownToPmConverter) {
|
|
19
|
+
// GFM parsers (e.g. markdownToAdf) natively recognise raw URLs as autolinks per
|
|
20
|
+
// the CommonMark spec — they do not need the `<url>` angle-bracket wrapping that
|
|
21
|
+
// the legacy MarkdownTransformer requires. Passing skipLinkEscaping: true avoids
|
|
22
|
+
// double-processing URLs and lets the GFM parser handle them correctly.
|
|
23
|
+
var escapedTextInput = (0, _index.escapeBackslashAndLinksExceptCodeBlock)(text, {
|
|
24
|
+
skipLinkEscaping: true
|
|
25
|
+
});
|
|
26
|
+
try {
|
|
27
|
+
var doc = schema.nodes.doc.createAndFill({}, markdownToPmConverter({
|
|
28
|
+
markdown: escapedTextInput,
|
|
29
|
+
schema: schema
|
|
30
|
+
}));
|
|
31
|
+
if (doc && doc.content) {
|
|
32
|
+
return new _model.Slice(doc.content, openStart, openEnd);
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
void (0, _monitoring.logException)(e instanceof Error ? e : new Error(String(e)), {
|
|
36
|
+
location: 'editor-plugin-paste/getMarkdownSlice'
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
@@ -140,7 +140,8 @@ function escapeLinks(text) {
|
|
|
140
140
|
* const input = 'This is a link: https://example.com and a backslash: \\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```';
|
|
141
141
|
* const output = escapeBackslashAndLinksExceptCodeBlock(input); // 'This is a link: <https://example.com> and a backslash: \\\\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```'
|
|
142
142
|
*/
|
|
143
|
-
function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
143
|
+
function escapeBackslashAndLinksExceptCodeBlock(textInput, options) {
|
|
144
|
+
var shouldEscapeLinks = !(options !== null && options !== void 0 && options.skipLinkEscaping);
|
|
144
145
|
// ref: https://spec.commonmark.org/0.31.2/#fenced-code-blocks
|
|
145
146
|
var isInsideCodeBlock = false;
|
|
146
147
|
var lines = textInput.split('\n');
|
|
@@ -162,7 +163,9 @@ function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
|
162
163
|
// Ignored via go/ees005
|
|
163
164
|
// eslint-disable-next-line require-unicode-regexp, @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
|
|
164
165
|
var escaped = line.replace(/\\/g, '\\\\');
|
|
165
|
-
|
|
166
|
+
if (shouldEscapeLinks) {
|
|
167
|
+
escaped = escapeLinks(escaped);
|
|
168
|
+
}
|
|
166
169
|
return escaped;
|
|
167
170
|
}
|
|
168
171
|
}).join('\n');
|
|
@@ -72,7 +72,7 @@ var showWarningFlag = function showWarningFlag(_ref) {
|
|
|
72
72
|
// Check if rawHtml contains a synced block
|
|
73
73
|
// example: "<meta charset='utf-8'><html><head></head><body><div data-sync-block=\"\" data-local-id=\"\" data-resource-id=\"d64883c8-1270-431d-a1d3-51d36a1ed5f4\" data-prosemirror-content-type=\"node\" data-prosemirror-node-name=\"syncBlock\" data-prosemirror-node-block=\"true\" data-pm-slice=\"0 0 []\"></div></body></html>"
|
|
74
74
|
var hasSyncedBlockInRawHtml = function hasSyncedBlockInRawHtml(rawHtml) {
|
|
75
|
-
return rawHtml.includes('data-sync-block="');
|
|
75
|
+
return Boolean(rawHtml === null || rawHtml === void 0 ? void 0 : rawHtml.includes('data-sync-block="'));
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
2
|
import { createPlugin } from './pm-plugins/main';
|
|
5
3
|
import { createPlugin as createMoveAnalyticsPlugin } from './pm-plugins/move-analytics/plugin';
|
|
6
4
|
import { pluginKey } from './pm-plugins/plugin-factory';
|
|
@@ -14,7 +12,8 @@ export const pastePlugin = ({
|
|
|
14
12
|
cardOptions,
|
|
15
13
|
sanitizePrivateContent,
|
|
16
14
|
isFullPage,
|
|
17
|
-
pasteWarningOptions
|
|
15
|
+
pasteWarningOptions,
|
|
16
|
+
markdownToPmConverter
|
|
18
17
|
} = config !== null && config !== void 0 ? config : {};
|
|
19
18
|
const featureFlags = (api === null || api === void 0 ? void 0 : (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
20
19
|
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
@@ -29,7 +28,7 @@ export const pastePlugin = ({
|
|
|
29
28
|
dispatchAnalyticsEvent,
|
|
30
29
|
dispatch,
|
|
31
30
|
getIntl
|
|
32
|
-
}) => createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions)
|
|
31
|
+
}) => createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter)
|
|
33
32
|
}, {
|
|
34
33
|
name: 'moveAnalyticsPlugin',
|
|
35
34
|
plugin: ({
|
|
@@ -39,7 +38,7 @@ export const pastePlugin = ({
|
|
|
39
38
|
}
|
|
40
39
|
}];
|
|
41
40
|
},
|
|
42
|
-
contentComponent:
|
|
41
|
+
contentComponent: () => {
|
|
43
42
|
if (!pasteWarningOptions) {
|
|
44
43
|
return null;
|
|
45
44
|
}
|
|
@@ -30,6 +30,7 @@ import { createClipboardTextSerializer } from './create-clipboard-text-serialize
|
|
|
30
30
|
import { createPluginState, pluginKey as stateKey } from './plugin-factory';
|
|
31
31
|
import { escapeBackslashAndLinksExceptCodeBlock, getPasteSource, htmlContainsSingleFile, htmlHasInvalidLinkTags, isPastedFromExcel, isPastedFromWord, removeDuplicateInvalidLinks, transformUnsupportedBlockCardToInline } from './util';
|
|
32
32
|
import { handleVSCodeBlock } from './util/edge-cases/handleVSCodeBlock';
|
|
33
|
+
import { getMarkdownSliceViaGfm } from './util/get-markdown-slice';
|
|
33
34
|
import { applyContainerNodeTransformToSlice, splitTablesOutOfPanelHtml, handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handlePasteExpand, handleTableContentPasteInBodiedExtension } from './util/handlers';
|
|
34
35
|
import { normalizePastedCodeBlockAttrs } from './util/normalize-pasted-code-block-attrs';
|
|
35
36
|
import { handleSyncBlocksPaste } from './util/sync-block';
|
|
@@ -74,11 +75,14 @@ export function isSharePointUrl(url) {
|
|
|
74
75
|
return false;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
|
-
export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions) {
|
|
78
|
+
export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter) {
|
|
78
79
|
var _pluginInjectionApi$a;
|
|
79
80
|
const editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
|
|
80
81
|
const atlassianMarkDownParser = new MarkdownTransformer(schema, md);
|
|
81
82
|
function getMarkdownSlice(text, openStart, openEnd) {
|
|
83
|
+
if (markdownToPmConverter && expValEquals('platform_editor_paste_as_md_use_gfm', 'isEnabled', true)) {
|
|
84
|
+
return getMarkdownSliceViaGfm(text, schema, openStart, openEnd, markdownToPmConverter);
|
|
85
|
+
}
|
|
82
86
|
const escapedTextInput = escapeBackslashAndLinksExceptCodeBlock(text);
|
|
83
87
|
const doc = atlassianMarkDownParser.parse(escapedTextInput);
|
|
84
88
|
if (doc && doc.content) {
|
|
@@ -334,9 +338,7 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
334
338
|
event,
|
|
335
339
|
text
|
|
336
340
|
});
|
|
337
|
-
|
|
338
|
-
slice = handleSyncBlocksPaste(slice, schema, getPasteSource(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
339
|
-
}
|
|
341
|
+
slice = handleSyncBlocksPaste(slice, schema, getPasteSource(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
340
342
|
const plainTextPasteSlice = linkifyContent(state.schema)(slice);
|
|
341
343
|
if (handlePasteAsPlainTextWithAnalytics(editorAnalyticsAPI)(view, event, plainTextPasteSlice)(state, dispatch, view)) {
|
|
342
344
|
return true;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
3
1
|
import { PastePluginActionTypes as ActionTypes } from '../editor-actions/actions';
|
|
4
2
|
export const reducer = (state, action) => {
|
|
5
3
|
switch (action.type) {
|
|
@@ -30,9 +28,6 @@ export const reducer = (state, action) => {
|
|
|
30
28
|
}
|
|
31
29
|
case ActionTypes.SET_ACTIVE_FLAG:
|
|
32
30
|
{
|
|
33
|
-
if (!editorExperiment('platform_synced_block', true) && !fg('platform_synced_block_unsupported_products')) {
|
|
34
|
-
return state;
|
|
35
|
-
}
|
|
36
31
|
return {
|
|
37
32
|
...state,
|
|
38
33
|
activeFlag: action.activeFlag
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
2
|
+
import { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import { escapeBackslashAndLinksExceptCodeBlock } from './index';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert plain-text markdown to a ProseMirror Slice using the GFM converter.
|
|
7
|
+
*
|
|
8
|
+
* Only called when `platform_editor_paste_as_md_use_gfm` is enabled AND a
|
|
9
|
+
* `markdownToPmConverter` is provided. Returns `undefined` if the converter
|
|
10
|
+
* throws or produces an empty document — the caller will propagate `undefined`
|
|
11
|
+
* without falling back to the legacy MarkdownTransformer.
|
|
12
|
+
*/
|
|
13
|
+
export function getMarkdownSliceViaGfm(text, schema, openStart, openEnd, markdownToPmConverter) {
|
|
14
|
+
// GFM parsers (e.g. markdownToAdf) natively recognise raw URLs as autolinks per
|
|
15
|
+
// the CommonMark spec — they do not need the `<url>` angle-bracket wrapping that
|
|
16
|
+
// the legacy MarkdownTransformer requires. Passing skipLinkEscaping: true avoids
|
|
17
|
+
// double-processing URLs and lets the GFM parser handle them correctly.
|
|
18
|
+
const escapedTextInput = escapeBackslashAndLinksExceptCodeBlock(text, {
|
|
19
|
+
skipLinkEscaping: true
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
const doc = schema.nodes.doc.createAndFill({}, markdownToPmConverter({
|
|
23
|
+
markdown: escapedTextInput,
|
|
24
|
+
schema
|
|
25
|
+
}));
|
|
26
|
+
if (doc && doc.content) {
|
|
27
|
+
return new Slice(doc.content, openStart, openEnd);
|
|
28
|
+
}
|
|
29
|
+
} catch (e) {
|
|
30
|
+
void logException(e instanceof Error ? e : new Error(String(e)), {
|
|
31
|
+
location: 'editor-plugin-paste/getMarkdownSlice'
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
@@ -119,7 +119,8 @@ export function escapeLinks(text) {
|
|
|
119
119
|
* const input = 'This is a link: https://example.com and a backslash: \\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```';
|
|
120
120
|
* const output = escapeBackslashAndLinksExceptCodeBlock(input); // 'This is a link: <https://example.com> and a backslash: \\\\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```'
|
|
121
121
|
*/
|
|
122
|
-
export function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
122
|
+
export function escapeBackslashAndLinksExceptCodeBlock(textInput, options) {
|
|
123
|
+
const shouldEscapeLinks = !(options !== null && options !== void 0 && options.skipLinkEscaping);
|
|
123
124
|
// ref: https://spec.commonmark.org/0.31.2/#fenced-code-blocks
|
|
124
125
|
let isInsideCodeBlock = false;
|
|
125
126
|
const lines = textInput.split('\n');
|
|
@@ -141,7 +142,9 @@ export function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
|
141
142
|
// Ignored via go/ees005
|
|
142
143
|
// eslint-disable-next-line require-unicode-regexp, @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
|
|
143
144
|
let escaped = line.replace(/\\/g, '\\\\');
|
|
144
|
-
|
|
145
|
+
if (shouldEscapeLinks) {
|
|
146
|
+
escaped = escapeLinks(escaped);
|
|
147
|
+
}
|
|
145
148
|
return escaped;
|
|
146
149
|
}
|
|
147
150
|
}).join('\n');
|
|
@@ -65,7 +65,7 @@ const showWarningFlag = ({
|
|
|
65
65
|
// Check if rawHtml contains a synced block
|
|
66
66
|
// example: "<meta charset='utf-8'><html><head></head><body><div data-sync-block=\"\" data-local-id=\"\" data-resource-id=\"d64883c8-1270-431d-a1d3-51d36a1ed5f4\" data-prosemirror-content-type=\"node\" data-prosemirror-node-name=\"syncBlock\" data-prosemirror-node-block=\"true\" data-pm-slice=\"0 0 []\"></div></body></html>"
|
|
67
67
|
const hasSyncedBlockInRawHtml = rawHtml => {
|
|
68
|
-
return rawHtml.includes('data-sync-block="');
|
|
68
|
+
return Boolean(rawHtml === null || rawHtml === void 0 ? void 0 : rawHtml.includes('data-sync-block="'));
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
/**
|
package/dist/esm/pastePlugin.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
4
2
|
import { createPlugin } from './pm-plugins/main';
|
|
5
3
|
import { createPlugin as createMoveAnalyticsPlugin } from './pm-plugins/move-analytics/plugin';
|
|
6
4
|
import { pluginKey } from './pm-plugins/plugin-factory';
|
|
@@ -13,7 +11,8 @@ export var pastePlugin = function pastePlugin(_ref) {
|
|
|
13
11
|
cardOptions = _ref2.cardOptions,
|
|
14
12
|
sanitizePrivateContent = _ref2.sanitizePrivateContent,
|
|
15
13
|
isFullPage = _ref2.isFullPage,
|
|
16
|
-
pasteWarningOptions = _ref2.pasteWarningOptions
|
|
14
|
+
pasteWarningOptions = _ref2.pasteWarningOptions,
|
|
15
|
+
markdownToPmConverter = _ref2.markdownToPmConverter;
|
|
17
16
|
var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
18
17
|
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
19
18
|
return {
|
|
@@ -27,7 +26,7 @@ export var pastePlugin = function pastePlugin(_ref) {
|
|
|
27
26
|
dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent,
|
|
28
27
|
dispatch = _ref3.dispatch,
|
|
29
28
|
getIntl = _ref3.getIntl;
|
|
30
|
-
return createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions);
|
|
29
|
+
return createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter);
|
|
31
30
|
}
|
|
32
31
|
}, {
|
|
33
32
|
name: 'moveAnalyticsPlugin',
|
|
@@ -37,7 +36,7 @@ export var pastePlugin = function pastePlugin(_ref) {
|
|
|
37
36
|
}
|
|
38
37
|
}];
|
|
39
38
|
},
|
|
40
|
-
contentComponent:
|
|
39
|
+
contentComponent: function contentComponent() {
|
|
41
40
|
if (!pasteWarningOptions) {
|
|
42
41
|
return null;
|
|
43
42
|
}
|
|
@@ -35,6 +35,7 @@ import { createClipboardTextSerializer } from './create-clipboard-text-serialize
|
|
|
35
35
|
import { createPluginState, pluginKey as stateKey } from './plugin-factory';
|
|
36
36
|
import { escapeBackslashAndLinksExceptCodeBlock, getPasteSource, htmlContainsSingleFile, htmlHasInvalidLinkTags, isPastedFromExcel, isPastedFromWord, removeDuplicateInvalidLinks, transformUnsupportedBlockCardToInline } from './util';
|
|
37
37
|
import { handleVSCodeBlock } from './util/edge-cases/handleVSCodeBlock';
|
|
38
|
+
import { getMarkdownSliceViaGfm } from './util/get-markdown-slice';
|
|
38
39
|
import { applyContainerNodeTransformToSlice, splitTablesOutOfPanelHtml, handleMacroAutoConvert, handleMention, handleParagraphBlockMarks, handlePasteExpand, handleTableContentPasteInBodiedExtension } from './util/handlers';
|
|
39
40
|
import { normalizePastedCodeBlockAttrs } from './util/normalize-pasted-code-block-attrs';
|
|
40
41
|
import { handleSyncBlocksPaste } from './util/sync-block';
|
|
@@ -77,11 +78,14 @@ export function isSharePointUrl(url) {
|
|
|
77
78
|
return false;
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions) {
|
|
81
|
+
export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pluginInjectionApi, getIntl, cardOptions, sanitizePrivateContent, providerFactory, pasteWarningOptions, markdownToPmConverter) {
|
|
81
82
|
var _pluginInjectionApi$a;
|
|
82
83
|
var editorAnalyticsAPI = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions;
|
|
83
84
|
var atlassianMarkDownParser = new MarkdownTransformer(schema, md);
|
|
84
85
|
function getMarkdownSlice(text, openStart, openEnd) {
|
|
86
|
+
if (markdownToPmConverter && expValEquals('platform_editor_paste_as_md_use_gfm', 'isEnabled', true)) {
|
|
87
|
+
return getMarkdownSliceViaGfm(text, schema, openStart, openEnd, markdownToPmConverter);
|
|
88
|
+
}
|
|
85
89
|
var escapedTextInput = escapeBackslashAndLinksExceptCodeBlock(text);
|
|
86
90
|
var doc = atlassianMarkDownParser.parse(escapedTextInput);
|
|
87
91
|
if (doc && doc.content) {
|
|
@@ -367,9 +371,7 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
|
|
|
367
371
|
event: event,
|
|
368
372
|
text: text
|
|
369
373
|
});
|
|
370
|
-
|
|
371
|
-
slice = handleSyncBlocksPaste(slice, schema, getPasteSource(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
372
|
-
}
|
|
374
|
+
slice = handleSyncBlocksPaste(slice, schema, getPasteSource(event), html, pasteWarningOptions, pluginInjectionApi);
|
|
373
375
|
var plainTextPasteSlice = linkifyContent(state.schema)(slice);
|
|
374
376
|
if (handlePasteAsPlainTextWithAnalytics(editorAnalyticsAPI)(view, event, plainTextPasteSlice)(state, dispatch, view)) {
|
|
375
377
|
return true;
|
|
@@ -2,8 +2,6 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
3
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
4
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
|
-
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
7
5
|
import { PastePluginActionTypes as ActionTypes } from '../editor-actions/actions';
|
|
8
6
|
export var reducer = function reducer(state, action) {
|
|
9
7
|
switch (action.type) {
|
|
@@ -32,9 +30,6 @@ export var reducer = function reducer(state, action) {
|
|
|
32
30
|
}
|
|
33
31
|
case ActionTypes.SET_ACTIVE_FLAG:
|
|
34
32
|
{
|
|
35
|
-
if (!editorExperiment('platform_synced_block', true) && !fg('platform_synced_block_unsupported_products')) {
|
|
36
|
-
return state;
|
|
37
|
-
}
|
|
38
33
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
39
34
|
activeFlag: action.activeFlag
|
|
40
35
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
2
|
+
import { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import { escapeBackslashAndLinksExceptCodeBlock } from './index';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Convert plain-text markdown to a ProseMirror Slice using the GFM converter.
|
|
7
|
+
*
|
|
8
|
+
* Only called when `platform_editor_paste_as_md_use_gfm` is enabled AND a
|
|
9
|
+
* `markdownToPmConverter` is provided. Returns `undefined` if the converter
|
|
10
|
+
* throws or produces an empty document — the caller will propagate `undefined`
|
|
11
|
+
* without falling back to the legacy MarkdownTransformer.
|
|
12
|
+
*/
|
|
13
|
+
export function getMarkdownSliceViaGfm(text, schema, openStart, openEnd, markdownToPmConverter) {
|
|
14
|
+
// GFM parsers (e.g. markdownToAdf) natively recognise raw URLs as autolinks per
|
|
15
|
+
// the CommonMark spec — they do not need the `<url>` angle-bracket wrapping that
|
|
16
|
+
// the legacy MarkdownTransformer requires. Passing skipLinkEscaping: true avoids
|
|
17
|
+
// double-processing URLs and lets the GFM parser handle them correctly.
|
|
18
|
+
var escapedTextInput = escapeBackslashAndLinksExceptCodeBlock(text, {
|
|
19
|
+
skipLinkEscaping: true
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
var doc = schema.nodes.doc.createAndFill({}, markdownToPmConverter({
|
|
23
|
+
markdown: escapedTextInput,
|
|
24
|
+
schema: schema
|
|
25
|
+
}));
|
|
26
|
+
if (doc && doc.content) {
|
|
27
|
+
return new Slice(doc.content, openStart, openEnd);
|
|
28
|
+
}
|
|
29
|
+
} catch (e) {
|
|
30
|
+
void logException(e instanceof Error ? e : new Error(String(e)), {
|
|
31
|
+
location: 'editor-plugin-paste/getMarkdownSlice'
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
@@ -120,7 +120,8 @@ export function escapeLinks(text) {
|
|
|
120
120
|
* const input = 'This is a link: https://example.com and a backslash: \\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```';
|
|
121
121
|
* const output = escapeBackslashAndLinksExceptCodeBlock(input); // 'This is a link: <https://example.com> and a backslash: \\\\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```'
|
|
122
122
|
*/
|
|
123
|
-
export function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
123
|
+
export function escapeBackslashAndLinksExceptCodeBlock(textInput, options) {
|
|
124
|
+
var shouldEscapeLinks = !(options !== null && options !== void 0 && options.skipLinkEscaping);
|
|
124
125
|
// ref: https://spec.commonmark.org/0.31.2/#fenced-code-blocks
|
|
125
126
|
var isInsideCodeBlock = false;
|
|
126
127
|
var lines = textInput.split('\n');
|
|
@@ -142,7 +143,9 @@ export function escapeBackslashAndLinksExceptCodeBlock(textInput) {
|
|
|
142
143
|
// Ignored via go/ees005
|
|
143
144
|
// eslint-disable-next-line require-unicode-regexp, @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
|
|
144
145
|
var escaped = line.replace(/\\/g, '\\\\');
|
|
145
|
-
|
|
146
|
+
if (shouldEscapeLinks) {
|
|
147
|
+
escaped = escapeLinks(escaped);
|
|
148
|
+
}
|
|
146
149
|
return escaped;
|
|
147
150
|
}
|
|
148
151
|
}).join('\n');
|
|
@@ -66,7 +66,7 @@ var showWarningFlag = function showWarningFlag(_ref) {
|
|
|
66
66
|
// Check if rawHtml contains a synced block
|
|
67
67
|
// example: "<meta charset='utf-8'><html><head></head><body><div data-sync-block=\"\" data-local-id=\"\" data-resource-id=\"d64883c8-1270-431d-a1d3-51d36a1ed5f4\" data-prosemirror-content-type=\"node\" data-prosemirror-node-name=\"syncBlock\" data-prosemirror-node-block=\"true\" data-pm-slice=\"0 0 []\"></div></body></html>"
|
|
68
68
|
var hasSyncedBlockInRawHtml = function hasSyncedBlockInRawHtml(rawHtml) {
|
|
69
|
-
return rawHtml.includes('data-sync-block="');
|
|
69
|
+
return Boolean(rawHtml === null || rawHtml === void 0 ? void 0 : rawHtml.includes('data-sync-block="'));
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { PastePlugin, PastePluginOptions, PastePluginState, LastContentPasted, PastePluginDependencies, ActiveFlag, } from '../pastePluginType';
|
|
1
|
+
export type { PastePlugin, PastePluginOptions, PastePluginState, LastContentPasted, PastePluginDependencies, ActiveFlag, MarkdownToPmConverter, } from '../pastePluginType';
|
|
@@ -12,7 +12,7 @@ import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
|
|
|
12
12
|
import type { ListPlugin } from '@atlaskit/editor-plugin-list';
|
|
13
13
|
import type { MediaPlugin } from '@atlaskit/editor-plugin-media';
|
|
14
14
|
import type { MentionsPlugin } from '@atlaskit/editor-plugin-mentions';
|
|
15
|
-
import type { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
15
|
+
import type { Fragment, Schema, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
16
16
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
17
17
|
export declare enum FLAG_TYPE {
|
|
18
18
|
WARNING = "warning",
|
|
@@ -62,9 +62,19 @@ export type LastContentPasted = {
|
|
|
62
62
|
sourcePastedSlice?: Slice;
|
|
63
63
|
text?: string;
|
|
64
64
|
};
|
|
65
|
+
export type MarkdownToPmConverter = (params: {
|
|
66
|
+
markdown: string;
|
|
67
|
+
schema: Schema;
|
|
68
|
+
}) => Fragment;
|
|
65
69
|
export type PastePluginOptions = {
|
|
66
70
|
cardOptions?: CardOptions;
|
|
67
71
|
isFullPage?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Optional markdown → ProseMirror fragment converter used for plain-text
|
|
74
|
+
* Cmd+V paste when `platform_editor_paste_as_md_use_gfm` is enabled.
|
|
75
|
+
* When omitted or the experiment is off, the legacy MarkdownTransformer is used.
|
|
76
|
+
*/
|
|
77
|
+
markdownToPmConverter?: MarkdownToPmConverter;
|
|
68
78
|
pasteWarningOptions?: PasteWarningOptions;
|
|
69
79
|
sanitizePrivateContent?: boolean;
|
|
70
80
|
};
|
|
@@ -8,7 +8,7 @@ import type { ExtractInjectionAPI, FeatureFlags, PasteWarningOptions } from '@at
|
|
|
8
8
|
import type { Schema } from '@atlaskit/editor-prosemirror/model';
|
|
9
9
|
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
10
10
|
import type { PastePlugin } from '../index';
|
|
11
|
-
import type { PastePluginState } from '../pastePluginType';
|
|
11
|
+
import type { MarkdownToPmConverter, PastePluginState } from '../pastePluginType';
|
|
12
12
|
export declare const isInsideBlockQuote: (state: EditorState) => boolean;
|
|
13
13
|
export declare function isSharePointUrl(url: string | undefined): boolean;
|
|
14
|
-
export declare function createPlugin(schema: Schema, dispatchAnalyticsEvent: DispatchAnalyticsEvent, dispatch: Dispatch, featureFlags: FeatureFlags, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined, getIntl: () => IntlShape, cardOptions?: CardOptions, sanitizePrivateContent?: boolean, providerFactory?: ProviderFactory, pasteWarningOptions?: PasteWarningOptions): SafePlugin<PastePluginState>;
|
|
14
|
+
export declare function createPlugin(schema: Schema, dispatchAnalyticsEvent: DispatchAnalyticsEvent, dispatch: Dispatch, featureFlags: FeatureFlags, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined, getIntl: () => IntlShape, cardOptions?: CardOptions, sanitizePrivateContent?: boolean, providerFactory?: ProviderFactory, pasteWarningOptions?: PasteWarningOptions, markdownToPmConverter?: MarkdownToPmConverter): SafePlugin<PastePluginState>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Fragment, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Convert plain-text markdown to a ProseMirror Slice using the GFM converter.
|
|
5
|
+
*
|
|
6
|
+
* Only called when `platform_editor_paste_as_md_use_gfm` is enabled AND a
|
|
7
|
+
* `markdownToPmConverter` is provided. Returns `undefined` if the converter
|
|
8
|
+
* throws or produces an empty document — the caller will propagate `undefined`
|
|
9
|
+
* without falling back to the legacy MarkdownTransformer.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getMarkdownSliceViaGfm(text: string, schema: Schema, openStart: number, openEnd: number, markdownToPmConverter: (params: {
|
|
12
|
+
markdown: string;
|
|
13
|
+
schema: Schema;
|
|
14
|
+
}) => Fragment): Slice | undefined;
|
|
@@ -33,7 +33,9 @@ export declare function escapeLinks(text: string): string;
|
|
|
33
33
|
* const input = 'This is a link: https://example.com and a backslash: \\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```';
|
|
34
34
|
* const output = escapeBackslashAndLinksExceptCodeBlock(input); // 'This is a link: <https://example.com> and a backslash: \\\\\n```\ncode block https://example.com not escaped\ncode block \\ not escaped\n```'
|
|
35
35
|
*/
|
|
36
|
-
export declare function escapeBackslashAndLinksExceptCodeBlock(textInput: string
|
|
36
|
+
export declare function escapeBackslashAndLinksExceptCodeBlock(textInput: string, options?: {
|
|
37
|
+
skipLinkEscaping?: boolean;
|
|
38
|
+
}): string;
|
|
37
39
|
export declare function hasOnlyNodesOfType(...nodeTypes: NodeType[]): (slice: Slice) => boolean;
|
|
38
40
|
export declare function applyTextMarksToSlice(schema: Schema, marks?: readonly Mark[]): (slice: Slice) => Slice;
|
|
39
41
|
export declare function isEmptyNode(node: PMNode | null | undefined): boolean | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-paste",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.1.1",
|
|
4
4
|
"description": "Paste plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@atlaskit/editor-plugin-feature-flags": "^13.0.0",
|
|
32
32
|
"@atlaskit/editor-plugin-list": "^16.0.0",
|
|
33
33
|
"@atlaskit/editor-plugin-media": "^16.0.0",
|
|
34
|
-
"@atlaskit/editor-plugin-mentions": "^16.
|
|
34
|
+
"@atlaskit/editor-plugin-mentions": "^16.1.0",
|
|
35
35
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
36
36
|
"@atlaskit/editor-tables": "^3.0.0",
|
|
37
37
|
"@atlaskit/flag": "^18.2.0",
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
43
43
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
44
44
|
"@atlaskit/prosemirror-history": "^1.1.0",
|
|
45
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
46
|
-
"@atlaskit/tokens": "^16.
|
|
45
|
+
"@atlaskit/tmp-editor-statsig": "^145.0.0",
|
|
46
|
+
"@atlaskit/tokens": "^16.5.0",
|
|
47
47
|
"@babel/runtime": "^7.0.0",
|
|
48
48
|
"lodash": "^4.17.21",
|
|
49
49
|
"uuid": "^3.1.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@atlaskit/editor-common": "^118.
|
|
52
|
+
"@atlaskit/editor-common": "^118.2.0",
|
|
53
53
|
"react": "^18.2.0 || ^19.2.0",
|
|
54
54
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
55
55
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -116,9 +116,6 @@
|
|
|
116
116
|
"platform_media_cross_client_copy_with_auth": {
|
|
117
117
|
"type": "boolean"
|
|
118
118
|
},
|
|
119
|
-
"platform_synced_block_unsupported_products": {
|
|
120
|
-
"type": "boolean"
|
|
121
|
-
},
|
|
122
119
|
"platform_editor_agent_mentions": {
|
|
123
120
|
"type": "experiment"
|
|
124
121
|
},
|