@atlaskit/editor-plugin-paste 0.1.22 → 0.2.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/.eslintrc.js +18 -0
- package/CHANGELOG.md +12 -0
- package/dist/cjs/actions.js +12 -0
- package/dist/cjs/commands.js +255 -0
- package/dist/cjs/edge-cases/index.js +88 -0
- package/dist/cjs/edge-cases/lists.js +107 -0
- package/dist/cjs/handlers.js +939 -0
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/plugin.js +43 -0
- package/dist/cjs/plugins/media.js +207 -0
- package/dist/cjs/pm-plugins/analytics.js +376 -0
- package/dist/cjs/pm-plugins/clipboard-text-serializer.js +43 -0
- package/dist/cjs/pm-plugins/main.js +484 -0
- package/dist/cjs/pm-plugins/plugin-factory.js +42 -0
- package/dist/cjs/reducer.js +41 -0
- package/dist/cjs/util/index.js +214 -0
- package/dist/cjs/util/tinyMCE.js +183 -0
- package/dist/es2019/actions.js +6 -0
- package/dist/es2019/commands.js +236 -0
- package/dist/es2019/edge-cases/index.js +87 -0
- package/dist/es2019/edge-cases/lists.js +113 -0
- package/dist/es2019/handlers.js +919 -0
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/plugin.js +38 -0
- package/dist/es2019/plugins/media.js +204 -0
- package/dist/es2019/pm-plugins/analytics.js +332 -0
- package/dist/es2019/pm-plugins/clipboard-text-serializer.js +37 -0
- package/dist/es2019/pm-plugins/main.js +453 -0
- package/dist/es2019/pm-plugins/plugin-factory.js +30 -0
- package/dist/es2019/reducer.js +32 -0
- package/dist/es2019/util/index.js +209 -0
- package/dist/es2019/util/tinyMCE.js +168 -0
- package/dist/esm/actions.js +6 -0
- package/dist/esm/commands.js +249 -0
- package/dist/esm/edge-cases/index.js +81 -0
- package/dist/esm/edge-cases/lists.js +98 -0
- package/dist/esm/handlers.js +918 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/plugin.js +37 -0
- package/dist/esm/plugins/media.js +199 -0
- package/dist/esm/pm-plugins/analytics.js +364 -0
- package/dist/esm/pm-plugins/clipboard-text-serializer.js +37 -0
- package/dist/esm/pm-plugins/main.js +471 -0
- package/dist/esm/pm-plugins/plugin-factory.js +36 -0
- package/dist/esm/reducer.js +34 -0
- package/dist/esm/util/index.js +194 -0
- package/dist/esm/util/tinyMCE.js +176 -0
- package/dist/types/actions.d.ts +21 -0
- package/dist/types/commands.d.ts +29 -0
- package/dist/types/edge-cases/index.d.ts +11 -0
- package/dist/types/edge-cases/lists.d.ts +18 -0
- package/dist/types/handlers.d.ts +55 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/plugin.d.ts +2 -0
- package/dist/types/plugins/media.d.ts +23 -0
- package/dist/types/pm-plugins/analytics.d.ts +44 -0
- package/dist/types/pm-plugins/clipboard-text-serializer.d.ts +13 -0
- package/dist/types/pm-plugins/main.d.ts +12 -0
- package/dist/types/pm-plugins/plugin-factory.d.ts +3 -0
- package/dist/types/reducer.d.ts +3 -0
- package/dist/types/util/index.d.ts +21 -0
- package/dist/types/util/tinyMCE.d.ts +32 -0
- package/dist/types-ts4.5/actions.d.ts +21 -0
- package/dist/types-ts4.5/commands.d.ts +29 -0
- package/dist/types-ts4.5/edge-cases/index.d.ts +11 -0
- package/dist/types-ts4.5/edge-cases/lists.d.ts +18 -0
- package/dist/types-ts4.5/handlers.d.ts +55 -0
- package/dist/types-ts4.5/index.d.ts +1 -0
- package/dist/types-ts4.5/plugin.d.ts +2 -0
- package/dist/types-ts4.5/plugins/media.d.ts +23 -0
- package/dist/types-ts4.5/pm-plugins/analytics.d.ts +44 -0
- package/dist/types-ts4.5/pm-plugins/clipboard-text-serializer.d.ts +13 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +12 -0
- package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +3 -0
- package/dist/types-ts4.5/reducer.d.ts +3 -0
- package/dist/types-ts4.5/util/index.d.ts +21 -0
- package/dist/types-ts4.5/util/tinyMCE.d.ts +32 -0
- package/package.json +18 -6
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import { ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD, TABLE_ACTION } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { sortByOrderWithTypeName } from '@atlaskit/editor-common/legacy-rank-plugins';
|
|
4
|
+
import { isSupportedInParent, mapChildren } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { Fragment, Mark, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
6
|
+
import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
7
|
+
import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
8
|
+
import { getSelectedTableInfo, isTableSelected } from '@atlaskit/editor-tables/utils';
|
|
9
|
+
import { isMediaBlobUrl } from '@atlaskit/media-client';
|
|
10
|
+
export function isPastedFromWord(html) {
|
|
11
|
+
return !!html && html.indexOf('urn:schemas-microsoft-com:office:word') >= 0;
|
|
12
|
+
}
|
|
13
|
+
export function isPastedFromExcel(html) {
|
|
14
|
+
return !!html && html.indexOf('urn:schemas-microsoft-com:office:excel') >= 0;
|
|
15
|
+
}
|
|
16
|
+
function isPastedFromDropboxPaper(html) {
|
|
17
|
+
return !!html && !!html.match(/class=\"\s?author-d-.+"/gim);
|
|
18
|
+
}
|
|
19
|
+
function isPastedFromGoogleDocs(html) {
|
|
20
|
+
return !!html && !!html.match(/id=\"docs-internal-guid-.+"/gim);
|
|
21
|
+
}
|
|
22
|
+
function isPastedFromGoogleSpreadSheets(html) {
|
|
23
|
+
return !!html && !!html.match(/data-sheets-.+=/gim);
|
|
24
|
+
}
|
|
25
|
+
function isPastedFromPages(html) {
|
|
26
|
+
return !!html && html.indexOf('content="Cocoa HTML Writer"') >= 0;
|
|
27
|
+
}
|
|
28
|
+
function isPastedFromFabricEditor(html) {
|
|
29
|
+
return !!html && html.indexOf('data-pm-slice="') >= 0;
|
|
30
|
+
}
|
|
31
|
+
export var isSingleLine = function isSingleLine(text) {
|
|
32
|
+
return !!text && text.trim().split('\n').length === 1;
|
|
33
|
+
};
|
|
34
|
+
export function htmlContainsSingleFile(html) {
|
|
35
|
+
return !!html.match(/<img .*>/) && !isMediaBlobUrl(html);
|
|
36
|
+
}
|
|
37
|
+
export function getPasteSource(event) {
|
|
38
|
+
var html = event.clipboardData.getData('text/html');
|
|
39
|
+
if (isPastedFromDropboxPaper(html)) {
|
|
40
|
+
return 'dropbox-paper';
|
|
41
|
+
} else if (isPastedFromWord(html)) {
|
|
42
|
+
return 'microsoft-word';
|
|
43
|
+
} else if (isPastedFromExcel(html)) {
|
|
44
|
+
return 'microsoft-excel';
|
|
45
|
+
} else if (isPastedFromGoogleDocs(html)) {
|
|
46
|
+
return 'google-docs';
|
|
47
|
+
} else if (isPastedFromGoogleSpreadSheets(html)) {
|
|
48
|
+
return 'google-spreadsheets';
|
|
49
|
+
} else if (isPastedFromPages(html)) {
|
|
50
|
+
return 'apple-pages';
|
|
51
|
+
} else if (isPastedFromFabricEditor(html)) {
|
|
52
|
+
return 'fabric-editor';
|
|
53
|
+
}
|
|
54
|
+
return 'uncategorized';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// @see https://product-fabric.atlassian.net/browse/ED-3159
|
|
58
|
+
// @see https://github.com/markdown-it/markdown-it/issues/38
|
|
59
|
+
export function escapeLinks(text) {
|
|
60
|
+
return text.replace(/(\[([^\]]+)\]\()?((https?|ftp|jamfselfservice):\/\/[^\s"'>]+)/g, function (str) {
|
|
61
|
+
return str.match(/^(https?|ftp|jamfselfservice):\/\/[^\s"'>]+$/) ? "<".concat(str, ">") : str;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
export function hasOnlyNodesOfType() {
|
|
65
|
+
for (var _len = arguments.length, nodeTypes = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
66
|
+
nodeTypes[_key] = arguments[_key];
|
|
67
|
+
}
|
|
68
|
+
return function (slice) {
|
|
69
|
+
var hasOnlyNodesOfType = true;
|
|
70
|
+
slice.content.descendants(function (node) {
|
|
71
|
+
hasOnlyNodesOfType = hasOnlyNodesOfType && nodeTypes.indexOf(node.type) > -1;
|
|
72
|
+
return hasOnlyNodesOfType;
|
|
73
|
+
});
|
|
74
|
+
return hasOnlyNodesOfType;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function applyTextMarksToSlice(schema, marks) {
|
|
78
|
+
return function (slice) {
|
|
79
|
+
var _schema$marks = schema.marks,
|
|
80
|
+
codeMark = _schema$marks.code,
|
|
81
|
+
linkMark = _schema$marks.link,
|
|
82
|
+
annotationMark = _schema$marks.annotation;
|
|
83
|
+
if (!Array.isArray(marks) || marks.length === 0) {
|
|
84
|
+
return slice;
|
|
85
|
+
}
|
|
86
|
+
var sliceCopy = Slice.fromJSON(schema, slice.toJSON() || {});
|
|
87
|
+
|
|
88
|
+
// allow links and annotations to be pasted
|
|
89
|
+
var allowedMarksToPaste = [linkMark, annotationMark];
|
|
90
|
+
sliceCopy.content.descendants(function (node, _pos, parent) {
|
|
91
|
+
if (node.isText && parent && parent.isBlock) {
|
|
92
|
+
// @ts-ignore - [unblock prosemirror bump] assigning to readonly prop
|
|
93
|
+
node.marks = [].concat(_toConsumableArray(node.marks && !codeMark.isInSet(marks) && node.marks.filter(function (mark) {
|
|
94
|
+
return allowedMarksToPaste.includes(mark.type);
|
|
95
|
+
}) || []), _toConsumableArray(parent.type.allowedMarks(marks).filter(function (mark) {
|
|
96
|
+
return mark.type !== linkMark;
|
|
97
|
+
}))).sort(sortByOrderWithTypeName('marks'));
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
return sliceCopy;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
export function isEmptyNode(node) {
|
|
106
|
+
if (!node) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
var nodeType = node.type;
|
|
110
|
+
var emptyNode = nodeType.createAndFill();
|
|
111
|
+
return emptyNode && emptyNode.nodeSize === node.nodeSize && emptyNode.content.eq(node.content) && Mark.sameSet(emptyNode.marks, node.marks);
|
|
112
|
+
}
|
|
113
|
+
export function isCursorSelectionAtTextStartOrEnd(selection) {
|
|
114
|
+
return selection instanceof TextSelection && selection.empty && selection.$cursor && (!selection.$cursor.nodeBefore || !selection.$cursor.nodeAfter);
|
|
115
|
+
}
|
|
116
|
+
export function isPanelNode(node) {
|
|
117
|
+
return Boolean(node && node.type.name === 'panel');
|
|
118
|
+
}
|
|
119
|
+
export function isSelectionInsidePanel(selection) {
|
|
120
|
+
if (selection instanceof NodeSelection && isPanelNode(selection.node)) {
|
|
121
|
+
return selection.node;
|
|
122
|
+
}
|
|
123
|
+
var panel = selection.$from.doc.type.schema.nodes.panel;
|
|
124
|
+
var panelPosition = findParentNodeOfType(panel)(selection);
|
|
125
|
+
if (panelPosition) {
|
|
126
|
+
return panelPosition.node;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// https://product-fabric.atlassian.net/browse/ED-11714
|
|
132
|
+
// Checks for broken html that comes from links in a list item copied from Notion
|
|
133
|
+
export var htmlHasInvalidLinkTags = function htmlHasInvalidLinkTags(html) {
|
|
134
|
+
return !!html && (html.includes('</a></a>') || html.includes('"></a><a'));
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// https://product-fabric.atlassian.net/browse/ED-11714
|
|
138
|
+
// Example of broken html edge case we're solving
|
|
139
|
+
// <li><a href="http://www.atlassian.com\"<a> href="http://www.atlassian.com\"http://www.atlassian.com</a></a></li>">
|
|
140
|
+
export var removeDuplicateInvalidLinks = function removeDuplicateInvalidLinks(html) {
|
|
141
|
+
if (htmlHasInvalidLinkTags(html)) {
|
|
142
|
+
var htmlArray = html.split(/(?=<a)/);
|
|
143
|
+
var htmlArrayWithoutInvalidLinks = htmlArray.filter(function (item) {
|
|
144
|
+
return !(item.includes('<a') && item.includes('"></a>')) && !(item.includes('<a') && !item.includes('</a>'));
|
|
145
|
+
});
|
|
146
|
+
var fixedHtml = htmlArrayWithoutInvalidLinks.join('').replace(/<\/a><\/a>/gi, '</a>').replace(/<a>/gi, '<a');
|
|
147
|
+
return fixedHtml;
|
|
148
|
+
}
|
|
149
|
+
return html;
|
|
150
|
+
};
|
|
151
|
+
export var addReplaceSelectedTableAnalytics = function addReplaceSelectedTableAnalytics(state, tr, editorAnalyticsAPI) {
|
|
152
|
+
if (isTableSelected(state.selection)) {
|
|
153
|
+
var _getSelectedTableInfo = getSelectedTableInfo(state.selection),
|
|
154
|
+
totalRowCount = _getSelectedTableInfo.totalRowCount,
|
|
155
|
+
totalColumnCount = _getSelectedTableInfo.totalColumnCount;
|
|
156
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
157
|
+
action: TABLE_ACTION.REPLACED,
|
|
158
|
+
actionSubject: ACTION_SUBJECT.TABLE,
|
|
159
|
+
attributes: {
|
|
160
|
+
totalColumnCount: totalColumnCount,
|
|
161
|
+
totalRowCount: totalRowCount,
|
|
162
|
+
inputMethod: INPUT_METHOD.CLIPBOARD
|
|
163
|
+
},
|
|
164
|
+
eventType: EVENT_TYPE.TRACK
|
|
165
|
+
})(tr);
|
|
166
|
+
return tr;
|
|
167
|
+
}
|
|
168
|
+
return state.tr;
|
|
169
|
+
};
|
|
170
|
+
export var transformUnsupportedBlockCardToInline = function transformUnsupportedBlockCardToInline(slice, state, cardOptions) {
|
|
171
|
+
var _state$schema$nodes = state.schema.nodes,
|
|
172
|
+
blockCard = _state$schema$nodes.blockCard,
|
|
173
|
+
inlineCard = _state$schema$nodes.inlineCard;
|
|
174
|
+
var children = [];
|
|
175
|
+
mapChildren(slice.content, function (node, i, frag) {
|
|
176
|
+
var _cardOptions$allowBlo;
|
|
177
|
+
if (node.type === blockCard && !isBlockCardSupported(state, frag, (_cardOptions$allowBlo = cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowBlockCards) !== null && _cardOptions$allowBlo !== void 0 ? _cardOptions$allowBlo : false)) {
|
|
178
|
+
children.push(inlineCard.createChecked(node.attrs, node.content, node.marks));
|
|
179
|
+
} else {
|
|
180
|
+
children.push(node);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
return new Slice(Fragment.fromArray(children), slice.openStart, slice.openEnd);
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Function to determine if a block card is supported by the editor
|
|
187
|
+
* @param state
|
|
188
|
+
* @param frag
|
|
189
|
+
* @param allowBlockCards
|
|
190
|
+
* @returns
|
|
191
|
+
*/
|
|
192
|
+
var isBlockCardSupported = function isBlockCardSupported(state, frag, allowBlockCards) {
|
|
193
|
+
return allowBlockCards && isSupportedInParent(state, frag);
|
|
194
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import chunk from 'lodash/chunk';
|
|
3
|
+
var isPastedFromTinyMCE = function isPastedFromTinyMCE(pasteEvent) {
|
|
4
|
+
var _pasteEvent$clipboard, _pasteEvent$clipboard2;
|
|
5
|
+
return (_pasteEvent$clipboard = pasteEvent === null || pasteEvent === void 0 || (_pasteEvent$clipboard2 = pasteEvent.clipboardData) === null || _pasteEvent$clipboard2 === void 0 || (_pasteEvent$clipboard2 = _pasteEvent$clipboard2.types) === null || _pasteEvent$clipboard2 === void 0 ? void 0 : _pasteEvent$clipboard2.some(function (mimeType) {
|
|
6
|
+
return mimeType === 'x-tinymce/html';
|
|
7
|
+
})) !== null && _pasteEvent$clipboard !== void 0 ? _pasteEvent$clipboard : false;
|
|
8
|
+
};
|
|
9
|
+
export var isPastedFromTinyMCEConfluence = function isPastedFromTinyMCEConfluence(pasteEvent, html) {
|
|
10
|
+
return isPastedFromTinyMCE(pasteEvent) && !!html && !!html.match(/class=\"\s?(confluenceTd|confluenceTh|confluenceTable).+"/gim);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Wraps html markup with a `<table>` and uses `DOMParser` to generate
|
|
15
|
+
* and return both the table-wrapped and non-table-wrapped DOM document
|
|
16
|
+
* instances.
|
|
17
|
+
*/
|
|
18
|
+
export var wrapWithTable = function wrapWithTable(html) {
|
|
19
|
+
var parser = new DOMParser();
|
|
20
|
+
var nonTableWrappedDoc = parser.parseFromString(html, 'text/html');
|
|
21
|
+
var tableWrappedDoc = parser.parseFromString("<table>".concat(html, "</table>"), 'text/html');
|
|
22
|
+
tableWrappedDoc.body.querySelectorAll('meta').forEach(function (meta) {
|
|
23
|
+
tableWrappedDoc.head.prepend(meta);
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
tableWrappedDoc: tableWrappedDoc,
|
|
27
|
+
nonTableWrappedDoc: nonTableWrappedDoc
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
var exactlyDivisible = function exactlyDivisible(larger, smaller) {
|
|
31
|
+
return larger % smaller === 0;
|
|
32
|
+
};
|
|
33
|
+
var getTableElementsInfo = function getTableElementsInfo(doc) {
|
|
34
|
+
var cellCount = doc.querySelectorAll('td').length;
|
|
35
|
+
var thCount = doc.querySelectorAll('th').length;
|
|
36
|
+
var mergedCellCount = doc.querySelectorAll('td[colspan]:not([colspan="1"])').length;
|
|
37
|
+
var hasThAfterTd = false;
|
|
38
|
+
var thsAndCells = doc.querySelectorAll('th,td');
|
|
39
|
+
for (var i = 0, cellFound = false; i < thsAndCells.length; i++) {
|
|
40
|
+
if (cellFound && thsAndCells[i].nodeName === 'TH') {
|
|
41
|
+
hasThAfterTd = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
if (thsAndCells[i].nodeName === 'TD') {
|
|
45
|
+
cellFound = true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
var onlyTh = thCount > 0 && cellCount === 0;
|
|
49
|
+
var onlyCells = cellCount > 0 && thCount === 0;
|
|
50
|
+
var hasCompleteRow =
|
|
51
|
+
// we take header-only and cell-only tables to be
|
|
52
|
+
// row-complete
|
|
53
|
+
onlyTh || onlyCells ||
|
|
54
|
+
// if headers and cells can "fit" against each other,
|
|
55
|
+
// then we assume a complete row exists
|
|
56
|
+
(exactlyDivisible(thCount, cellCount) || exactlyDivisible(cellCount, thCount)) &&
|
|
57
|
+
// all numbers are divisible by 1, so we carve out a specific
|
|
58
|
+
// check for when there is only 1 table cell, and more than 1
|
|
59
|
+
// table header.
|
|
60
|
+
!(thCount > 1 && cellCount === 1);
|
|
61
|
+
return {
|
|
62
|
+
cellCount: cellCount,
|
|
63
|
+
thCount: thCount,
|
|
64
|
+
mergedCellCount: mergedCellCount,
|
|
65
|
+
hasThAfterTd: hasThAfterTd,
|
|
66
|
+
hasIncompleteRow: !hasCompleteRow
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
var configureTableRows = function configureTableRows(doc, colsInRow) {
|
|
70
|
+
var _Array$from;
|
|
71
|
+
var tableHeadersAndCells = Array.from(doc.body.querySelectorAll('th,td'));
|
|
72
|
+
var evenlySplitChunks = chunk(tableHeadersAndCells, colsInRow);
|
|
73
|
+
var tableBody = doc.body.querySelector('tbody');
|
|
74
|
+
evenlySplitChunks.forEach(function (chunk) {
|
|
75
|
+
var tr = doc.createElement('tr');
|
|
76
|
+
tableBody === null || tableBody === void 0 || tableBody.append(tr);
|
|
77
|
+
tr.append.apply(tr, _toConsumableArray(chunk));
|
|
78
|
+
});
|
|
79
|
+
// We remove any leftover empty rows which may cause fabric editor
|
|
80
|
+
// to no-op when parsing the table
|
|
81
|
+
var emptyRows = (_Array$from = Array.from(tableBody.querySelectorAll('tr'))) === null || _Array$from === void 0 ? void 0 : _Array$from.filter(function (row) {
|
|
82
|
+
return row.innerHTML.trim().length === 0;
|
|
83
|
+
});
|
|
84
|
+
emptyRows.forEach(function (row) {
|
|
85
|
+
return row.remove();
|
|
86
|
+
});
|
|
87
|
+
return doc.body.innerHTML;
|
|
88
|
+
};
|
|
89
|
+
var fillIncompleteRowWithEmptyCells = function fillIncompleteRowWithEmptyCells(doc, thCount, cellCount) {
|
|
90
|
+
var _lastCell$parentEleme;
|
|
91
|
+
var extraCellsCount = 0;
|
|
92
|
+
while (!exactlyDivisible(cellCount + extraCellsCount, thCount)) {
|
|
93
|
+
extraCellsCount++;
|
|
94
|
+
}
|
|
95
|
+
var extraEmptyCells = Array.from(Array(extraCellsCount)).map(function () {
|
|
96
|
+
return doc.createElement('td');
|
|
97
|
+
});
|
|
98
|
+
var lastCell = doc.body.querySelector('td:last-of-type');
|
|
99
|
+
lastCell === null || lastCell === void 0 || (_lastCell$parentEleme = lastCell.parentElement) === null || _lastCell$parentEleme === void 0 || _lastCell$parentEleme.append.apply(_lastCell$parentEleme, _toConsumableArray(extraEmptyCells));
|
|
100
|
+
return {
|
|
101
|
+
updatedCellCount: cellCount + extraCellsCount
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Given a DOM document, it will try to rebuild table rows by using the
|
|
107
|
+
* table headers count as an initial starting point for the assumed
|
|
108
|
+
* number of columns that make up a row (`colsInRow`). It will slowly
|
|
109
|
+
* decrease that `colsInRow` count until it finds exact fit for table
|
|
110
|
+
* headers and cells with `colsInRow` else it returns the original
|
|
111
|
+
* document's markup.
|
|
112
|
+
*
|
|
113
|
+
* NOTE: It will NOT try to rebuild table rows if it encounters merged cells
|
|
114
|
+
* or compex table configurations (where table headers exist after normal
|
|
115
|
+
* table cells). It will build a single column table if NO table
|
|
116
|
+
* headers exist.
|
|
117
|
+
*/
|
|
118
|
+
export var tryReconstructTableRows = function tryReconstructTableRows(doc) {
|
|
119
|
+
var _getTableElementsInfo = getTableElementsInfo(doc),
|
|
120
|
+
cellCount = _getTableElementsInfo.cellCount,
|
|
121
|
+
thCount = _getTableElementsInfo.thCount,
|
|
122
|
+
mergedCellCount = _getTableElementsInfo.mergedCellCount,
|
|
123
|
+
hasThAfterTd = _getTableElementsInfo.hasThAfterTd,
|
|
124
|
+
hasIncompleteRow = _getTableElementsInfo.hasIncompleteRow;
|
|
125
|
+
if (mergedCellCount || hasThAfterTd) {
|
|
126
|
+
// bail out to avoid handling more complex table structures
|
|
127
|
+
return doc.body.innerHTML;
|
|
128
|
+
}
|
|
129
|
+
if (!thCount) {
|
|
130
|
+
// if no table headers exist for reference, fallback to a single column table structure
|
|
131
|
+
return configureTableRows(doc, 1);
|
|
132
|
+
}
|
|
133
|
+
if (hasIncompleteRow) {
|
|
134
|
+
// if shift-click selection copies a partial table row to the clipboard,
|
|
135
|
+
// and we do have table headers for reference, then we add empty table cells
|
|
136
|
+
// to fill out the partial row
|
|
137
|
+
var _fillIncompleteRowWit = fillIncompleteRowWithEmptyCells(doc, thCount, cellCount),
|
|
138
|
+
updatedCellCount = _fillIncompleteRowWit.updatedCellCount;
|
|
139
|
+
cellCount = updatedCellCount;
|
|
140
|
+
}
|
|
141
|
+
for (var possibleColsInRow = thCount; possibleColsInRow > 0; possibleColsInRow--) {
|
|
142
|
+
if (exactlyDivisible(thCount, possibleColsInRow) && exactlyDivisible(cellCount, possibleColsInRow)) {
|
|
143
|
+
return configureTableRows(doc, possibleColsInRow);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return doc.body.innerHTML;
|
|
147
|
+
};
|
|
148
|
+
export var htmlHasIncompleteTable = function htmlHasIncompleteTable(html) {
|
|
149
|
+
return !html.includes('<table ') && (html.includes('<td ') || html.includes('<th '));
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Strictly for ED-7331. Given incomplete table html from tinyMCE, it will try to rebuild
|
|
154
|
+
* a whole valid table. If it rebuilds the table, it may first rebuild it as a single
|
|
155
|
+
* row table, so this also then tries to reconstruct the table rows/columns if
|
|
156
|
+
* possible (best effort).
|
|
157
|
+
*/
|
|
158
|
+
export var tryRebuildCompleteTableHtml = function tryRebuildCompleteTableHtml(incompleteTableHtml) {
|
|
159
|
+
// first we try wrapping the table elements with <table> and let DOMParser try to rebuild
|
|
160
|
+
// a valid DOM tree. we also keep the non-wrapped table for comparison purposes.
|
|
161
|
+
var _wrapWithTable = wrapWithTable(incompleteTableHtml),
|
|
162
|
+
nonTableWrappedDoc = _wrapWithTable.nonTableWrappedDoc,
|
|
163
|
+
tableWrappedDoc = _wrapWithTable.tableWrappedDoc;
|
|
164
|
+
var didPreserveTableElements = Boolean(!nonTableWrappedDoc.body.querySelector('th, td') && tableWrappedDoc.body.querySelector('th, td'));
|
|
165
|
+
var isExpectedStructure = tableWrappedDoc.querySelectorAll('body > table:only-child') && !tableWrappedDoc.querySelector("body > table > tbody > tr > :not(th,td)");
|
|
166
|
+
|
|
167
|
+
// if DOMParser saves table elements that we would otherwise lose, and
|
|
168
|
+
// if the table html is what we'd expect (a single table, with no extraneous
|
|
169
|
+
// elements in table rows other than th, td), then we can now also try to
|
|
170
|
+
// rebuild table rows/columns.
|
|
171
|
+
if (didPreserveTableElements && isExpectedStructure) {
|
|
172
|
+
var completeTableHtml = tryReconstructTableRows(tableWrappedDoc);
|
|
173
|
+
return completeTableHtml;
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LastContentPasted } from './types';
|
|
2
|
+
export declare enum PastePluginActionTypes {
|
|
3
|
+
START_TRACKING_PASTED_MACRO_POSITIONS = "START_TRACKING_PASTED_MACRO_POSITIONS",
|
|
4
|
+
STOP_TRACKING_PASTED_MACRO_POSITIONS = "STOP_TRACKING_PASTED_MACRO_POSITIONS",
|
|
5
|
+
ON_PASTE = "ON_PASTE"
|
|
6
|
+
}
|
|
7
|
+
export interface StartTrackingPastedMacroPositions {
|
|
8
|
+
type: PastePluginActionTypes.START_TRACKING_PASTED_MACRO_POSITIONS;
|
|
9
|
+
pastedMacroPositions: {
|
|
10
|
+
[key: string]: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface OnPaste {
|
|
14
|
+
type: PastePluginActionTypes.ON_PASTE;
|
|
15
|
+
contentPasted: LastContentPasted;
|
|
16
|
+
}
|
|
17
|
+
export interface StopTrackingPastedMacroPositions {
|
|
18
|
+
type: PastePluginActionTypes.STOP_TRACKING_PASTED_MACRO_POSITIONS;
|
|
19
|
+
pastedMacroPositionKeys: string[];
|
|
20
|
+
}
|
|
21
|
+
export type PastePluginAction = StartTrackingPastedMacroPositions | StopTrackingPastedMacroPositions | OnPaste;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Mark, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Use this to register macro link positions during a paste operation, that you
|
|
5
|
+
* want to track in a document over time, through any document changes.
|
|
6
|
+
*
|
|
7
|
+
* @param positions a map of string keys (custom position references) and position values e.g. { ['my-key-1']: 11 }
|
|
8
|
+
*
|
|
9
|
+
* **Context**: This is neccessary if there is an async process or an unknown period of time
|
|
10
|
+
* between obtaining an original position, and wanting to know about what its final eventual
|
|
11
|
+
* value. In that scenario, positions will need to be actively tracked and mapped in plugin
|
|
12
|
+
* state so that they can be mapped through any other independent document change transactions being
|
|
13
|
+
* dispatched to the editor that could affect their value.
|
|
14
|
+
*/
|
|
15
|
+
export declare const startTrackingPastedMacroPositions: (pastedMacroPositions: {
|
|
16
|
+
[key: string]: number;
|
|
17
|
+
}) => import("@atlaskit/editor-common/types").Command;
|
|
18
|
+
export declare const stopTrackingPastedMacroPositions: (pastedMacroPositionKeys: string[]) => import("@atlaskit/editor-common/types").Command;
|
|
19
|
+
export declare const upgradeTextToLists: (slice: Slice, schema: Schema) => Slice;
|
|
20
|
+
export declare const splitParagraphs: (slice: Slice, schema: Schema) => Slice;
|
|
21
|
+
/**
|
|
22
|
+
* Walks the slice, creating paragraphs that were previously separated by hardbreaks.
|
|
23
|
+
* Returns the original paragraph node (as a fragment), or a fragment containing multiple nodes.
|
|
24
|
+
*/
|
|
25
|
+
export declare const splitIntoParagraphs: ({ fragment, blockMarks, schema, }: {
|
|
26
|
+
fragment: Fragment;
|
|
27
|
+
blockMarks?: readonly Mark[] | undefined;
|
|
28
|
+
schema: Schema;
|
|
29
|
+
}) => Fragment;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
export declare function insertSliceForLists({ tr, slice, schema, }: {
|
|
4
|
+
tr: Transaction;
|
|
5
|
+
slice: Slice;
|
|
6
|
+
schema: Schema;
|
|
7
|
+
}): void | Transaction;
|
|
8
|
+
export declare function insertSliceForListsInsideBlockquote({ tr, slice, }: {
|
|
9
|
+
tr: Transaction;
|
|
10
|
+
slice: Slice;
|
|
11
|
+
}): Transaction | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Node as PMNode, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
export declare function insertSliceIntoEmptyNode({ tr, slice, }: {
|
|
4
|
+
tr: Transaction;
|
|
5
|
+
slice: Slice;
|
|
6
|
+
}): void;
|
|
7
|
+
export declare function insertSliceAtNodeEdge({ tr, slice, }: {
|
|
8
|
+
tr: Transaction;
|
|
9
|
+
slice: Slice;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function insertSliceIntoRangeSelectionInsideList({ tr, slice, }: {
|
|
12
|
+
tr: Transaction;
|
|
13
|
+
slice: Slice;
|
|
14
|
+
}): Transaction | undefined;
|
|
15
|
+
export declare function insertSliceInsideOfPanelNodeSelected(panelNode: PMNode): ({ tr, slice }: {
|
|
16
|
+
tr: Transaction;
|
|
17
|
+
slice: Slice;
|
|
18
|
+
}) => void;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { EditorAnalyticsAPI, InputMethodInsertMedia } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { CardOptions, QueueCardsFromTransactionAction } from '@atlaskit/editor-common/card';
|
|
3
|
+
import type { ExtensionAutoConvertHandler } from '@atlaskit/editor-common/extensions';
|
|
4
|
+
import type { Command } from '@atlaskit/editor-common/types';
|
|
5
|
+
import type { RunMacroAutoConvert } from '@atlaskit/editor-plugin-extension';
|
|
6
|
+
import type { FindRootParentListNode } from '@atlaskit/editor-plugin-list';
|
|
7
|
+
import type { InsertMediaAsMediaSingle } from '@atlaskit/editor-plugin-media/types';
|
|
8
|
+
import { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
9
|
+
import type { Schema } from '@atlaskit/editor-prosemirror/model';
|
|
10
|
+
import type { EditorState, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
11
|
+
export declare function handleMention(slice: Slice, schema: Schema): Slice;
|
|
12
|
+
export declare function handlePasteIntoTaskOrDecisionOrPanel(slice: Slice, queueCardsFromChangedTr: QueueCardsFromTransactionAction | undefined): Command;
|
|
13
|
+
export declare function handlePasteNonNestableBlockNodesIntoList(slice: Slice): Command;
|
|
14
|
+
export declare const doesSelectionWhichStartsOrEndsInListContainEntireList: (selection: Selection, findRootParentListNode: FindRootParentListNode | undefined) => boolean;
|
|
15
|
+
export declare function handlePastePanelOrDecisionContentIntoList(slice: Slice, findRootParentListNode: FindRootParentListNode | undefined): Command;
|
|
16
|
+
export declare function handlePasteLinkOnSelectedText(slice: Slice): Command;
|
|
17
|
+
export declare function handlePasteAsPlainText(slice: Slice, _event: ClipboardEvent, editorAnalyticsAPI: EditorAnalyticsAPI | undefined): Command;
|
|
18
|
+
export declare function handlePastePreservingMarks(slice: Slice, queueCardsFromChangedTr: QueueCardsFromTransactionAction | undefined): Command;
|
|
19
|
+
export declare function handleMacroAutoConvert(text: string, slice: Slice, queueCardsFromChangedTr: QueueCardsFromTransactionAction | undefined, runMacroAutoConvert: RunMacroAutoConvert | undefined, cardsOptions?: CardOptions, extensionAutoConverter?: ExtensionAutoConvertHandler): Command;
|
|
20
|
+
export declare function handleCodeBlock(text: string): Command;
|
|
21
|
+
export declare function handleMediaSingle(inputMethod: InputMethodInsertMedia, insertMediaAsMediaSingle: InsertMediaAsMediaSingle | undefined): (slice: Slice) => Command;
|
|
22
|
+
export declare function handleExpandPasteInTable(slice: Slice): Command;
|
|
23
|
+
export declare function handleMarkdown(markdownSlice: Slice, queueCardsFromChangedTr: QueueCardsFromTransactionAction | undefined, from?: number, to?: number): Command;
|
|
24
|
+
export declare function handleParagraphBlockMarks(state: EditorState, slice: Slice): Slice;
|
|
25
|
+
/**
|
|
26
|
+
* ED-6300: When a nested list is pasted in a table cell and the slice has openStart > openEnd,
|
|
27
|
+
* it splits the table. As a workaround, we flatten the list to even openStart and openEnd.
|
|
28
|
+
*
|
|
29
|
+
* Note: this only happens if the first child is a list
|
|
30
|
+
*
|
|
31
|
+
* Example: copying "one" and "two"
|
|
32
|
+
* - zero
|
|
33
|
+
* - one
|
|
34
|
+
* - two
|
|
35
|
+
*
|
|
36
|
+
* Before:
|
|
37
|
+
* ul
|
|
38
|
+
* ┗━ li
|
|
39
|
+
* ┗━ ul
|
|
40
|
+
* ┗━ li
|
|
41
|
+
* ┗━ p -> "one"
|
|
42
|
+
* ┗━ li
|
|
43
|
+
* ┗━ p -> "two"
|
|
44
|
+
*
|
|
45
|
+
* After:
|
|
46
|
+
* ul
|
|
47
|
+
* ┗━ li
|
|
48
|
+
* ┗━ p -> "one"
|
|
49
|
+
* ┗━ li
|
|
50
|
+
* ┗━p -> "two"
|
|
51
|
+
*/
|
|
52
|
+
export declare function flattenNestedListInSlice(slice: Slice): Slice;
|
|
53
|
+
export declare function handleRichText(slice: Slice, queueCardsFromChangedTr: QueueCardsFromTransactionAction | undefined): Command;
|
|
54
|
+
export declare function handlePasteIntoCaption(slice: Slice): Command;
|
|
55
|
+
export declare const handleSelectedTable: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (slice: Slice) => Command;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Schema, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
/**
|
|
4
|
+
* Ensure correct layout in nested mode
|
|
5
|
+
*
|
|
6
|
+
* TODO: this func is only used in handlePaste, so layout update won't work for drop event
|
|
7
|
+
*/
|
|
8
|
+
export declare function transformSliceForMedia(slice: Slice, schema: Schema): (selection: Selection) => Slice;
|
|
9
|
+
export declare const isImage: (fileType?: string) => boolean;
|
|
10
|
+
export declare const transformSliceToCorrectMediaWrapper: (slice: Slice, schema: Schema) => Slice;
|
|
11
|
+
/**
|
|
12
|
+
* This func will be called when copy & paste, drag & drop external html with media, media files, and slices from editor
|
|
13
|
+
* Because width may not be available when transform, DEFAULT_IMAGE_WIDTH is used as a fallback
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
export declare const transformSliceToMediaSingleWithNewExperience: (slice: Slice, schema: Schema) => Slice;
|
|
17
|
+
/**
|
|
18
|
+
* Given a html string, we attempt to hoist any nested `<img>` tags,
|
|
19
|
+
* not directly wrapped by a `<div>` as ProseMirror no-op's
|
|
20
|
+
* on those scenarios.
|
|
21
|
+
* @param html
|
|
22
|
+
*/
|
|
23
|
+
export declare const unwrapNestedMediaElements: (html: string) => string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { AnalyticsEventPayload, EditorAnalyticsAPI, PasteContent, PasteType } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { Command, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { FindRootParentListNode } from '@atlaskit/editor-plugin-list';
|
|
4
|
+
import type { InsertMediaAsMediaSingle } from '@atlaskit/editor-plugin-media/types';
|
|
5
|
+
import type { Fragment, Schema, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
6
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
+
import type { PastePlugin } from '../index';
|
|
8
|
+
type PasteContext = {
|
|
9
|
+
type: PasteType;
|
|
10
|
+
asPlain?: boolean;
|
|
11
|
+
/** Has the hyperlink been pasted while text is selected, making the text into a link? */
|
|
12
|
+
hyperlinkPasteOnText?: boolean;
|
|
13
|
+
/** Did this paste action split a list in half? */
|
|
14
|
+
pasteSplitList?: boolean;
|
|
15
|
+
};
|
|
16
|
+
type GetContentProps = {
|
|
17
|
+
schema: Schema;
|
|
18
|
+
slice: Slice;
|
|
19
|
+
};
|
|
20
|
+
export declare function getContent({ schema, slice }: GetContentProps): PasteContent;
|
|
21
|
+
export declare function getMediaTraceId(slice: Slice): undefined;
|
|
22
|
+
export declare function createPasteAnalyticsPayload(view: EditorView, event: ClipboardEvent, slice: Slice, pasteContext: PasteContext): AnalyticsEventPayload;
|
|
23
|
+
export declare const sendPasteAnalyticsEvent: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, pasteContext: PasteContext) => void;
|
|
24
|
+
export declare const handlePasteAsPlainTextWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice) => Command;
|
|
25
|
+
export declare const handlePasteIntoTaskAndDecisionWithAnalytics: (view: EditorView, event: ClipboardEvent, slice: Slice, type: PasteType, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined) => Command;
|
|
26
|
+
export declare const handlePasteIntoCaptionWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, type: PasteType) => Command;
|
|
27
|
+
export declare const handleCodeBlockWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, text: string) => Command;
|
|
28
|
+
export declare const handleMediaSingleWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, type: PasteType, insertMediaAsMediaSingle: InsertMediaAsMediaSingle | undefined) => Command;
|
|
29
|
+
export declare const handlePastePreservingMarksWithAnalytics: (view: EditorView, event: ClipboardEvent, slice: Slice, type: PasteType, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined) => Command;
|
|
30
|
+
export declare const handleMarkdownWithAnalytics: (view: EditorView, event: ClipboardEvent, slice: Slice, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined) => Command;
|
|
31
|
+
export declare const handleRichTextWithAnalytics: (view: EditorView, event: ClipboardEvent, slice: Slice, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined) => Command;
|
|
32
|
+
export declare const handlePastePanelOrDecisionIntoListWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, findRootParentListNode: FindRootParentListNode | undefined) => Command;
|
|
33
|
+
export declare const handlePasteNonNestableBlockNodesIntoListWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice) => Command;
|
|
34
|
+
export declare const handleExpandWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice) => Command;
|
|
35
|
+
export declare const handleSelectedTableWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice) => Command;
|
|
36
|
+
export declare const handlePasteLinkOnSelectedTextWithAnalytics: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (view: EditorView, event: ClipboardEvent, slice: Slice, type: PasteType) => Command;
|
|
37
|
+
export declare const createPasteMeasurePayload: ({ view, duration, content, distortedDuration, }: {
|
|
38
|
+
view: EditorView;
|
|
39
|
+
duration: number;
|
|
40
|
+
content: Array<string>;
|
|
41
|
+
distortedDuration: boolean;
|
|
42
|
+
}) => AnalyticsEventPayload;
|
|
43
|
+
export declare const getContentNodeTypes: (content: Fragment) => string[];
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a plain text serialization of a given slice. This is used for populating the plain text
|
|
4
|
+
* section of the clipboard on copy.
|
|
5
|
+
* The current implementation is bare bones - only inlineCards, blockCards and mentions are tested (they
|
|
6
|
+
* previously were empty on plain text copy).
|
|
7
|
+
* Unknown nodes are passed to node.textBetween().
|
|
8
|
+
*
|
|
9
|
+
* By default (without this function passed to the editor), the editor uses
|
|
10
|
+
* `slice.content.textBetween(0, slice.content.size, "\n\n")`
|
|
11
|
+
* (see https://prosemirror.net/docs/ref/#view.EditorProps.clipboardTextSerializer)
|
|
12
|
+
*/
|
|
13
|
+
export declare function clipboardTextSerializer(slice: Slice): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { CardOptions } from '@atlaskit/editor-common/card';
|
|
3
|
+
import type { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
|
|
4
|
+
import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
5
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
|
+
import type { ExtractInjectionAPI, FeatureFlags } from '@atlaskit/editor-common/types';
|
|
7
|
+
import type { Schema } from '@atlaskit/editor-prosemirror/model';
|
|
8
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
9
|
+
import type { PastePlugin } from '../index';
|
|
10
|
+
export { pluginKey as stateKey } from './plugin-factory';
|
|
11
|
+
export declare const isInsideBlockQuote: (state: EditorState) => boolean;
|
|
12
|
+
export declare function createPlugin(schema: Schema, dispatchAnalyticsEvent: DispatchAnalyticsEvent, dispatch: Dispatch, featureFlags: FeatureFlags, pluginInjectionApi: ExtractInjectionAPI<PastePlugin> | undefined, cardOptions?: CardOptions, sanitizePrivateContent?: boolean, providerFactory?: ProviderFactory): SafePlugin<import("../types").PastePluginState>;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
export declare const pluginKey: PluginKey<any>;
|
|
3
|
+
export declare const createPluginState: (dispatch: import("@atlaskit/editor-common/event-dispatcher").Dispatch<any>, initialState: import("..").PastePluginState | ((state: import("prosemirror-state").EditorState) => import("..").PastePluginState)) => import("prosemirror-state").SafeStateField<import("..").PastePluginState>, createCommand: <A = import("../actions").PastePluginAction>(action: A | ((state: Readonly<import("prosemirror-state").EditorState>) => false | A), transform?: ((tr: import("prosemirror-state").Transaction, state: import("prosemirror-state").EditorState) => import("prosemirror-state").Transaction) | undefined) => import("@atlaskit/editor-common/types").Command, getPluginState: (state: import("prosemirror-state").EditorState) => import("..").PastePluginState;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { EditorAnalyticsAPI, PasteSource } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import type { CardOptions } from '@atlaskit/editor-common/card';
|
|
3
|
+
import type { NodeType, Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import { Mark, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
5
|
+
import type { EditorState, Selection, Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
6
|
+
export declare function isPastedFromWord(html?: string): boolean;
|
|
7
|
+
export declare function isPastedFromExcel(html?: string): boolean;
|
|
8
|
+
export declare const isSingleLine: (text: string) => boolean;
|
|
9
|
+
export declare function htmlContainsSingleFile(html: string): boolean;
|
|
10
|
+
export declare function getPasteSource(event: ClipboardEvent): PasteSource;
|
|
11
|
+
export declare function escapeLinks(text: string): string;
|
|
12
|
+
export declare function hasOnlyNodesOfType(...nodeTypes: NodeType[]): (slice: Slice) => boolean;
|
|
13
|
+
export declare function applyTextMarksToSlice(schema: Schema, marks?: readonly Mark[]): (slice: Slice) => Slice;
|
|
14
|
+
export declare function isEmptyNode(node: PMNode | null | undefined): boolean | null;
|
|
15
|
+
export declare function isCursorSelectionAtTextStartOrEnd(selection: Selection): boolean | null;
|
|
16
|
+
export declare function isPanelNode(node: PMNode | null | undefined): boolean;
|
|
17
|
+
export declare function isSelectionInsidePanel(selection: Selection): PMNode | null;
|
|
18
|
+
export declare const htmlHasInvalidLinkTags: (html?: string) => boolean;
|
|
19
|
+
export declare const removeDuplicateInvalidLinks: (html: string) => string;
|
|
20
|
+
export declare const addReplaceSelectedTableAnalytics: (state: EditorState, tr: Transaction, editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => Transaction;
|
|
21
|
+
export declare const transformUnsupportedBlockCardToInline: (slice: Slice, state: EditorState, cardOptions?: CardOptions) => Slice;
|