@atlaskit/editor-plugin-paste 0.1.22 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +18 -0
- package/CHANGELOG.md +6 -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 +17 -5
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
rules: {
|
|
3
|
+
'@typescript-eslint/no-duplicate-imports': 'error',
|
|
4
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
5
|
+
'@typescript-eslint/ban-types': [
|
|
6
|
+
'error',
|
|
7
|
+
{
|
|
8
|
+
types: {
|
|
9
|
+
'React.FC':
|
|
10
|
+
'Please use types directly on props instead, and explicitly define children if required',
|
|
11
|
+
'React.FunctionalComponent':
|
|
12
|
+
'Please use types directly on props instead, and explicitly define children if required',
|
|
13
|
+
},
|
|
14
|
+
extendDefaults: false,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
};
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#63830](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/63830) [`a21d2c99bd13`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a21d2c99bd13) - Move code for editor paste plugin from editor-core to @atlaskit/editor-plugin-paste
|
|
8
|
+
|
|
3
9
|
## 0.1.22
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PastePluginActionTypes = void 0;
|
|
7
|
+
var PastePluginActionTypes = exports.PastePluginActionTypes = /*#__PURE__*/function (PastePluginActionTypes) {
|
|
8
|
+
PastePluginActionTypes["START_TRACKING_PASTED_MACRO_POSITIONS"] = "START_TRACKING_PASTED_MACRO_POSITIONS";
|
|
9
|
+
PastePluginActionTypes["STOP_TRACKING_PASTED_MACRO_POSITIONS"] = "STOP_TRACKING_PASTED_MACRO_POSITIONS";
|
|
10
|
+
PastePluginActionTypes["ON_PASTE"] = "ON_PASTE";
|
|
11
|
+
return PastePluginActionTypes;
|
|
12
|
+
}({});
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.upgradeTextToLists = exports.stopTrackingPastedMacroPositions = exports.startTrackingPastedMacroPositions = exports.splitParagraphs = exports.splitIntoParagraphs = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
10
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
11
|
+
var _commands = require("@atlaskit/editor-prosemirror/commands");
|
|
12
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
13
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
14
|
+
var _actions = require("./actions");
|
|
15
|
+
var _pluginFactory = require("./pm-plugins/plugin-factory");
|
|
16
|
+
/**
|
|
17
|
+
* Use this to register macro link positions during a paste operation, that you
|
|
18
|
+
* want to track in a document over time, through any document changes.
|
|
19
|
+
*
|
|
20
|
+
* @param positions a map of string keys (custom position references) and position values e.g. { ['my-key-1']: 11 }
|
|
21
|
+
*
|
|
22
|
+
* **Context**: This is neccessary if there is an async process or an unknown period of time
|
|
23
|
+
* between obtaining an original position, and wanting to know about what its final eventual
|
|
24
|
+
* value. In that scenario, positions will need to be actively tracked and mapped in plugin
|
|
25
|
+
* state so that they can be mapped through any other independent document change transactions being
|
|
26
|
+
* dispatched to the editor that could affect their value.
|
|
27
|
+
*/
|
|
28
|
+
var startTrackingPastedMacroPositions = exports.startTrackingPastedMacroPositions = function startTrackingPastedMacroPositions(pastedMacroPositions) {
|
|
29
|
+
return (0, _pluginFactory.createCommand)(function () {
|
|
30
|
+
return {
|
|
31
|
+
type: _actions.PastePluginActionTypes.START_TRACKING_PASTED_MACRO_POSITIONS,
|
|
32
|
+
pastedMacroPositions: pastedMacroPositions
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
var stopTrackingPastedMacroPositions = exports.stopTrackingPastedMacroPositions = function stopTrackingPastedMacroPositions(pastedMacroPositionKeys) {
|
|
37
|
+
return (0, _pluginFactory.createCommand)(function () {
|
|
38
|
+
return {
|
|
39
|
+
type: _actions.PastePluginActionTypes.STOP_TRACKING_PASTED_MACRO_POSITIONS,
|
|
40
|
+
pastedMacroPositionKeys: pastedMacroPositionKeys
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// matchers for text lists
|
|
46
|
+
var bullets = /^\s*[\*\-\u2022](\s+|\s+$)/;
|
|
47
|
+
var numbers = /^\s*\d[\.\)](\s+|$)/;
|
|
48
|
+
var getListType = function getListType(node, schema) {
|
|
49
|
+
if (!node.text) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
var _schema$nodes = schema.nodes,
|
|
53
|
+
bulletList = _schema$nodes.bulletList,
|
|
54
|
+
orderedList = _schema$nodes.orderedList;
|
|
55
|
+
return [{
|
|
56
|
+
node: bulletList,
|
|
57
|
+
matcher: bullets
|
|
58
|
+
}, {
|
|
59
|
+
node: orderedList,
|
|
60
|
+
matcher: numbers
|
|
61
|
+
}].reduce(function (lastMatch, listType) {
|
|
62
|
+
if (lastMatch) {
|
|
63
|
+
return lastMatch;
|
|
64
|
+
}
|
|
65
|
+
var match = node.text.match(listType.matcher);
|
|
66
|
+
return match ? [listType.node, match[0].length] : lastMatch;
|
|
67
|
+
}, null);
|
|
68
|
+
};
|
|
69
|
+
var extractListFromParagraph = function extractListFromParagraph(node, parent, schema) {
|
|
70
|
+
var _schema$nodes2 = schema.nodes,
|
|
71
|
+
hardBreak = _schema$nodes2.hardBreak,
|
|
72
|
+
bulletList = _schema$nodes2.bulletList,
|
|
73
|
+
orderedList = _schema$nodes2.orderedList;
|
|
74
|
+
var content = (0, _utils.mapChildren)(node.content, function (node) {
|
|
75
|
+
return node;
|
|
76
|
+
});
|
|
77
|
+
var listTypes = [bulletList, orderedList];
|
|
78
|
+
|
|
79
|
+
// wrap each line into a listItem and a containing list
|
|
80
|
+
var listified = content.map(function (child, index) {
|
|
81
|
+
var listMatch = getListType(child, schema);
|
|
82
|
+
var prevChild = index > 0 && content[index - 1];
|
|
83
|
+
|
|
84
|
+
// only extract list when preceded by a hardbreak
|
|
85
|
+
if (prevChild && prevChild.type !== hardBreak) {
|
|
86
|
+
return child;
|
|
87
|
+
}
|
|
88
|
+
if (!listMatch || !child.text) {
|
|
89
|
+
return child;
|
|
90
|
+
}
|
|
91
|
+
var _listMatch = (0, _slicedToArray2.default)(listMatch, 2),
|
|
92
|
+
nodeType = _listMatch[0],
|
|
93
|
+
length = _listMatch[1];
|
|
94
|
+
|
|
95
|
+
// convert to list item
|
|
96
|
+
var newText = child.text.substr(length);
|
|
97
|
+
var listItemNode = schema.nodes.listItem.createAndFill(undefined, schema.nodes.paragraph.createChecked(undefined, newText.length ? schema.text(newText) : undefined));
|
|
98
|
+
if (!listItemNode) {
|
|
99
|
+
return child;
|
|
100
|
+
}
|
|
101
|
+
var newList = nodeType.createChecked(undefined, [listItemNode]);
|
|
102
|
+
// Check whether our new list is valid content in our current structure,
|
|
103
|
+
// otherwise dont convert.
|
|
104
|
+
if (parent && !parent.type.validContent(_model.Fragment.from(newList))) {
|
|
105
|
+
return child;
|
|
106
|
+
}
|
|
107
|
+
return newList;
|
|
108
|
+
}).filter(function (child, idx, arr) {
|
|
109
|
+
// remove hardBreaks that have a list node on either side
|
|
110
|
+
|
|
111
|
+
// wasn't hardBreak, leave as-is
|
|
112
|
+
if (child.type !== hardBreak) {
|
|
113
|
+
return child;
|
|
114
|
+
}
|
|
115
|
+
if (idx > 0 && listTypes.indexOf(arr[idx - 1].type) > -1) {
|
|
116
|
+
// list node on the left
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (idx < arr.length - 1 && listTypes.indexOf(arr[idx + 1].type) > -1) {
|
|
120
|
+
// list node on the right
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return child;
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// try to join
|
|
127
|
+
var mockState = _state.EditorState.create({
|
|
128
|
+
schema: schema
|
|
129
|
+
});
|
|
130
|
+
var joinedListsTr;
|
|
131
|
+
var mockDispatch = function mockDispatch(tr) {
|
|
132
|
+
joinedListsTr = tr;
|
|
133
|
+
};
|
|
134
|
+
(0, _commands.autoJoin)(function (state, dispatch) {
|
|
135
|
+
if (!dispatch) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Return false to prevent replaceWith from wrapping the text node in a paragraph
|
|
140
|
+
// paragraph since that will be done later. If it's done here, it will fail
|
|
141
|
+
// the paragraph.validContent check.
|
|
142
|
+
// Dont return false if there are lists, as they arent validContent for paragraphs
|
|
143
|
+
// and will result in hanging textNodes
|
|
144
|
+
var containsList = listified.some(function (node) {
|
|
145
|
+
return node.type === bulletList || node.type === orderedList;
|
|
146
|
+
});
|
|
147
|
+
if (listified.some(function (node) {
|
|
148
|
+
return node.isText;
|
|
149
|
+
}) && !containsList) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
dispatch(state.tr.replaceWith(0, 2, listified));
|
|
153
|
+
return true;
|
|
154
|
+
}, function (before, after) {
|
|
155
|
+
return (0, _utils.isListNode)(before) && (0, _utils.isListNode)(after);
|
|
156
|
+
})(mockState, mockDispatch);
|
|
157
|
+
var fragment = joinedListsTr ? joinedListsTr.doc.content : _model.Fragment.from(listified);
|
|
158
|
+
|
|
159
|
+
// try to re-wrap fragment in paragraph (which is the original node we unwrapped)
|
|
160
|
+
var paragraph = schema.nodes.paragraph;
|
|
161
|
+
if (paragraph.validContent(fragment)) {
|
|
162
|
+
return _model.Fragment.from(paragraph.create(node.attrs, fragment, node.marks));
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// fragment now contains other nodes, get Prosemirror to wrap with ContentMatch later
|
|
166
|
+
return fragment;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// above will wrap everything in paragraphs for us
|
|
170
|
+
var upgradeTextToLists = exports.upgradeTextToLists = function upgradeTextToLists(slice, schema) {
|
|
171
|
+
return (0, _utils.mapSlice)(slice, function (node, parent) {
|
|
172
|
+
if (node.type === schema.nodes.paragraph) {
|
|
173
|
+
return extractListFromParagraph(node, parent, schema);
|
|
174
|
+
}
|
|
175
|
+
return node;
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
var splitParagraphs = exports.splitParagraphs = function splitParagraphs(slice, schema) {
|
|
179
|
+
// exclude Text nodes with a code mark, since we transform those later
|
|
180
|
+
// into a codeblock
|
|
181
|
+
var hasCodeMark = false;
|
|
182
|
+
slice.content.forEach(function (child) {
|
|
183
|
+
hasCodeMark = hasCodeMark || child.marks.some(function (mark) {
|
|
184
|
+
return mark.type === schema.marks.code;
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// slice might just be a raw text string
|
|
189
|
+
if (schema.nodes.paragraph.validContent(slice.content) && !hasCodeMark) {
|
|
190
|
+
var replSlice = splitIntoParagraphs({
|
|
191
|
+
fragment: slice.content,
|
|
192
|
+
schema: schema
|
|
193
|
+
});
|
|
194
|
+
return new _model.Slice(replSlice, slice.openStart + 1, slice.openEnd + 1);
|
|
195
|
+
}
|
|
196
|
+
return (0, _utils.mapSlice)(slice, function (node) {
|
|
197
|
+
if (node.type === schema.nodes.paragraph) {
|
|
198
|
+
return splitIntoParagraphs({
|
|
199
|
+
fragment: node.content,
|
|
200
|
+
blockMarks: node.marks,
|
|
201
|
+
schema: schema
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return node;
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Walks the slice, creating paragraphs that were previously separated by hardbreaks.
|
|
210
|
+
* Returns the original paragraph node (as a fragment), or a fragment containing multiple nodes.
|
|
211
|
+
*/
|
|
212
|
+
var splitIntoParagraphs = exports.splitIntoParagraphs = function splitIntoParagraphs(_ref) {
|
|
213
|
+
var fragment = _ref.fragment,
|
|
214
|
+
_ref$blockMarks = _ref.blockMarks,
|
|
215
|
+
blockMarks = _ref$blockMarks === void 0 ? [] : _ref$blockMarks,
|
|
216
|
+
schema = _ref.schema;
|
|
217
|
+
var paragraphs = [];
|
|
218
|
+
var curChildren = [];
|
|
219
|
+
var lastNode = null;
|
|
220
|
+
var _schema$nodes3 = schema.nodes,
|
|
221
|
+
hardBreak = _schema$nodes3.hardBreak,
|
|
222
|
+
paragraph = _schema$nodes3.paragraph;
|
|
223
|
+
fragment.forEach(function (node, i) {
|
|
224
|
+
var isNodeValidContentForParagraph = schema.nodes.paragraph.validContent(_model.Fragment.from(node));
|
|
225
|
+
if (!isNodeValidContentForParagraph) {
|
|
226
|
+
paragraphs.push(node);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
// ED-14725 Fixed the issue that it make duplicated line
|
|
230
|
+
// when pasting <br /> from google docs.
|
|
231
|
+
if (i === 0 && node.type === hardBreak) {
|
|
232
|
+
paragraphs.push(paragraph.createChecked(undefined, curChildren, (0, _toConsumableArray2.default)(blockMarks)));
|
|
233
|
+
lastNode = node;
|
|
234
|
+
return;
|
|
235
|
+
} else if (lastNode && lastNode.type === hardBreak && node.type === hardBreak) {
|
|
236
|
+
// double hardbreak
|
|
237
|
+
|
|
238
|
+
// backtrack a little; remove the trailing hardbreak we added last loop
|
|
239
|
+
curChildren.pop();
|
|
240
|
+
|
|
241
|
+
// create a new paragraph
|
|
242
|
+
paragraphs.push(paragraph.createChecked(undefined, curChildren, (0, _toConsumableArray2.default)(blockMarks)));
|
|
243
|
+
curChildren = [];
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// add to this paragraph
|
|
248
|
+
curChildren.push(node);
|
|
249
|
+
lastNode = node;
|
|
250
|
+
});
|
|
251
|
+
if (curChildren.length) {
|
|
252
|
+
paragraphs.push(paragraph.createChecked(undefined, curChildren, (0, _toConsumableArray2.default)(blockMarks)));
|
|
253
|
+
}
|
|
254
|
+
return _model.Fragment.from(paragraphs.length ? paragraphs : [paragraph.createAndFill(undefined, undefined, (0, _toConsumableArray2.default)(blockMarks))]);
|
|
255
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.insertSliceForLists = insertSliceForLists;
|
|
7
|
+
exports.insertSliceForListsInsideBlockquote = insertSliceForListsInsideBlockquote;
|
|
8
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
9
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
10
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
11
|
+
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
12
|
+
var _util = require("../util");
|
|
13
|
+
var _lists = require("./lists");
|
|
14
|
+
function insertSliceForLists(_ref) {
|
|
15
|
+
var _slice$content$firstC;
|
|
16
|
+
var tr = _ref.tr,
|
|
17
|
+
slice = _ref.slice,
|
|
18
|
+
schema = _ref.schema;
|
|
19
|
+
var selection = tr.selection,
|
|
20
|
+
_tr$selection = tr.selection,
|
|
21
|
+
$to = _tr$selection.$to,
|
|
22
|
+
$from = _tr$selection.$from;
|
|
23
|
+
var _ref2 = selection,
|
|
24
|
+
$cursor = _ref2.$cursor;
|
|
25
|
+
var panelNode = (0, _util.isSelectionInsidePanel)(selection);
|
|
26
|
+
var selectionIsInsideList = $from.blockRange($to, _utils.isListNode);
|
|
27
|
+
if (!$cursor && selectionIsInsideList) {
|
|
28
|
+
return (0, _lists.insertSliceIntoRangeSelectionInsideList)({
|
|
29
|
+
tr: tr,
|
|
30
|
+
slice: slice
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// if inside an empty panel, try and insert content inside it rather than replace it
|
|
35
|
+
if (panelNode && (0, _util.isEmptyNode)(panelNode) && $from.node() === $to.node()) {
|
|
36
|
+
return (0, _lists.insertSliceInsideOfPanelNodeSelected)(panelNode)({
|
|
37
|
+
tr: tr,
|
|
38
|
+
slice: slice
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (!$cursor || selectionIsInsideList) {
|
|
42
|
+
return tr.replaceSelection(slice);
|
|
43
|
+
}
|
|
44
|
+
if ((0, _util.isEmptyNode)(tr.doc.resolve($cursor.pos).node())) {
|
|
45
|
+
return (0, _lists.insertSliceIntoEmptyNode)({
|
|
46
|
+
tr: tr,
|
|
47
|
+
slice: slice
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// When pasting a single list item into an action or decision, we skip the special "insert at node edge"
|
|
52
|
+
// logic so that prosemirror pastes the list's content into the action/decision, rather than
|
|
53
|
+
// pasting a whole list node directly after the action/decision item. (But we still preserve the
|
|
54
|
+
// existing "insert at" node edge" behaviour if dealing with a list with more than one item, so that
|
|
55
|
+
// it still inserts whole list node after the action/decision item).
|
|
56
|
+
var pastingIntoActionOrDecision = Boolean((0, _utils2.findParentNodeOfType)([schema.nodes.taskList, schema.nodes.decisionList])(selection));
|
|
57
|
+
var oneListItem = slice.content.childCount === 1 && (0, _utils.isListNode)(slice.content.firstChild) && ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.childCount) === 1;
|
|
58
|
+
if (!(pastingIntoActionOrDecision && oneListItem) && (0, _util.isCursorSelectionAtTextStartOrEnd)(selection)) {
|
|
59
|
+
return (0, _lists.insertSliceAtNodeEdge)({
|
|
60
|
+
tr: tr,
|
|
61
|
+
slice: slice
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
tr.replaceSelection(slice);
|
|
65
|
+
}
|
|
66
|
+
function insertSliceForListsInsideBlockquote(_ref3) {
|
|
67
|
+
var tr = _ref3.tr,
|
|
68
|
+
slice = _ref3.slice;
|
|
69
|
+
(0, _utils2.safeInsert)(slice.content, tr.selection.$to.pos)(tr).scrollIntoView();
|
|
70
|
+
// ProseMirror doesn't give a proper way to tell us where something was inserted.
|
|
71
|
+
// However, we can know "how" it inserted something.
|
|
72
|
+
//
|
|
73
|
+
// So, instead of weird depth calculations, we can use the step produced by the transform.
|
|
74
|
+
// For instance:
|
|
75
|
+
// The `replaceStep.to and replaceStep.from`, tell us the real position
|
|
76
|
+
// where the content will be insert.
|
|
77
|
+
// Then, we can use the `tr.mapping.map` to the updated position after the replace operation
|
|
78
|
+
var replaceStep = tr.steps[0];
|
|
79
|
+
if (!(replaceStep instanceof _transform.ReplaceStep)) {
|
|
80
|
+
return tr;
|
|
81
|
+
}
|
|
82
|
+
var nextPosition = tr.mapping.map(replaceStep.to);
|
|
83
|
+
// The findFrom will make search for both: TextSelection and NodeSelections.
|
|
84
|
+
var nextSelection = _state.Selection.findFrom(tr.doc.resolve(Math.min(nextPosition, tr.doc.content.size)), -1);
|
|
85
|
+
if (nextSelection) {
|
|
86
|
+
tr.setSelection(nextSelection);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.insertSliceAtNodeEdge = insertSliceAtNodeEdge;
|
|
7
|
+
exports.insertSliceInsideOfPanelNodeSelected = insertSliceInsideOfPanelNodeSelected;
|
|
8
|
+
exports.insertSliceIntoEmptyNode = insertSliceIntoEmptyNode;
|
|
9
|
+
exports.insertSliceIntoRangeSelectionInsideList = insertSliceIntoRangeSelectionInsideList;
|
|
10
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
11
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
12
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
13
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
14
|
+
function insertSliceIntoEmptyNode(_ref) {
|
|
15
|
+
var tr = _ref.tr,
|
|
16
|
+
slice = _ref.slice;
|
|
17
|
+
tr.replaceSelection(slice);
|
|
18
|
+
}
|
|
19
|
+
function insertSliceAtNodeEdge(_ref2) {
|
|
20
|
+
var tr = _ref2.tr,
|
|
21
|
+
slice = _ref2.slice;
|
|
22
|
+
var selection = tr.selection;
|
|
23
|
+
var _ref3 = selection,
|
|
24
|
+
$cursor = _ref3.$cursor;
|
|
25
|
+
if (!$cursor) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
var position = !$cursor.nodeBefore ? $cursor.before() : $cursor.after();
|
|
29
|
+
tr.replaceRange(position, position, slice);
|
|
30
|
+
var startSlicePosition = tr.doc.resolve(Math.min(position + slice.content.size - slice.openEnd, tr.doc.content.size));
|
|
31
|
+
var direction = -1;
|
|
32
|
+
tr.setSelection(_state.TextSelection.near(startSlicePosition, direction));
|
|
33
|
+
}
|
|
34
|
+
function insertSliceIntoRangeSelectionInsideList(_ref4) {
|
|
35
|
+
var tr = _ref4.tr,
|
|
36
|
+
slice = _ref4.slice;
|
|
37
|
+
var _tr$selection = tr.selection,
|
|
38
|
+
$to = _tr$selection.$to,
|
|
39
|
+
$from = _tr$selection.$from,
|
|
40
|
+
to = _tr$selection.to,
|
|
41
|
+
from = _tr$selection.from;
|
|
42
|
+
|
|
43
|
+
// when the selection is inside of the same list item
|
|
44
|
+
// we can use a normal replace
|
|
45
|
+
if ($from.sameParent($to) || $from.depth === $to.depth) {
|
|
46
|
+
return tr.replaceSelection(slice);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// if pasting a list inside another list, ensure no empty list items get added
|
|
50
|
+
var newRange = $from.blockRange($to);
|
|
51
|
+
if (!newRange) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
var startPos = from;
|
|
55
|
+
var endPos = $to.nodeAfter ? to : to + 2;
|
|
56
|
+
var newSlice = tr.doc.slice(endPos, newRange.end);
|
|
57
|
+
tr.deleteRange(startPos, newRange.end);
|
|
58
|
+
var mapped = tr.mapping.map(startPos);
|
|
59
|
+
tr.replaceRange(mapped, mapped, slice);
|
|
60
|
+
if (newSlice.size <= 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
var newSelection = _state.TextSelection.near(tr.doc.resolve(tr.mapping.map(mapped)), -1);
|
|
64
|
+
// @ts-ignore - [unblock prosemirror bump] assigning to readonly prop
|
|
65
|
+
newSlice.openEnd = newSlice.openStart;
|
|
66
|
+
tr.replaceRange(newSelection.from, newSelection.from, newSlice);
|
|
67
|
+
tr.setSelection(_state.TextSelection.near(tr.doc.resolve(newSelection.from), -1));
|
|
68
|
+
}
|
|
69
|
+
function insertSliceInsideOfPanelNodeSelected(panelNode) {
|
|
70
|
+
return function (_ref5) {
|
|
71
|
+
var tr = _ref5.tr,
|
|
72
|
+
slice = _ref5.slice;
|
|
73
|
+
var selection = tr.selection,
|
|
74
|
+
_tr$selection2 = tr.selection,
|
|
75
|
+
$to = _tr$selection2.$to,
|
|
76
|
+
$from = _tr$selection2.$from;
|
|
77
|
+
var panelPosition = selection.from;
|
|
78
|
+
|
|
79
|
+
// if content of slice isn't valid for a panel node, insert the invalid node and following content after
|
|
80
|
+
if (panelNode && !panelNode.type.validContent(_model.Fragment.from(slice.content))) {
|
|
81
|
+
var _parentNode$firstChil;
|
|
82
|
+
var insertPosition = $to.pos + 1;
|
|
83
|
+
tr.replaceRange(insertPosition, insertPosition, slice);
|
|
84
|
+
// need to delete the empty paragraph at the top of the panel
|
|
85
|
+
var parentNode = tr.doc.resolve($from.before()).node();
|
|
86
|
+
if (parentNode && parentNode.childCount > 1 && ((_parentNode$firstChil = parentNode.firstChild) === null || _parentNode$firstChil === void 0 ? void 0 : _parentNode$firstChil.type.name) === 'paragraph' && (0, _utils.isEmptyParagraph)(parentNode.firstChild)) {
|
|
87
|
+
var startPosDelete = tr.doc.resolve($from.before()).posAtIndex(0);
|
|
88
|
+
var endPosDelete = tr.doc.resolve($from.before()).posAtIndex(1);
|
|
89
|
+
var SIZE_OF_EMPTY_PARAGRAPH = 2; // {startPos}<p>{startPos + 1}</p>{endPos}
|
|
90
|
+
if (endPosDelete - startPosDelete === SIZE_OF_EMPTY_PARAGRAPH) {
|
|
91
|
+
tr.delete(startPosDelete, endPosDelete);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
tr.setSelection(_state.TextSelection.near(tr.doc.resolve(insertPosition + slice.content.size - slice.openStart - slice.openEnd + 1)));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
var temporaryDoc = new _transform.Transform(tr.doc.type.createAndFill());
|
|
98
|
+
temporaryDoc.replaceRange(0, temporaryDoc.doc.content.size, slice);
|
|
99
|
+
var sliceWithoutInvalidListSurrounding = temporaryDoc.doc.slice(0);
|
|
100
|
+
var newPanel = panelNode.copy(sliceWithoutInvalidListSurrounding.content);
|
|
101
|
+
var panelNodeSelected = selection instanceof _state.NodeSelection ? selection.node : null;
|
|
102
|
+
var replaceFrom = panelNodeSelected ? panelPosition : tr.doc.resolve(panelPosition).start();
|
|
103
|
+
var replaceTo = panelNodeSelected ? panelPosition + panelNodeSelected.nodeSize : replaceFrom;
|
|
104
|
+
tr.replaceRangeWith(replaceFrom, replaceTo, newPanel);
|
|
105
|
+
tr.setSelection(_state.TextSelection.near(tr.doc.resolve($from.pos + newPanel.content.size), -1));
|
|
106
|
+
};
|
|
107
|
+
}
|