@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.
Files changed (78) hide show
  1. package/.eslintrc.js +18 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/cjs/actions.js +12 -0
  4. package/dist/cjs/commands.js +255 -0
  5. package/dist/cjs/edge-cases/index.js +88 -0
  6. package/dist/cjs/edge-cases/lists.js +107 -0
  7. package/dist/cjs/handlers.js +939 -0
  8. package/dist/cjs/index.js +8 -1
  9. package/dist/cjs/plugin.js +43 -0
  10. package/dist/cjs/plugins/media.js +207 -0
  11. package/dist/cjs/pm-plugins/analytics.js +376 -0
  12. package/dist/cjs/pm-plugins/clipboard-text-serializer.js +43 -0
  13. package/dist/cjs/pm-plugins/main.js +484 -0
  14. package/dist/cjs/pm-plugins/plugin-factory.js +42 -0
  15. package/dist/cjs/reducer.js +41 -0
  16. package/dist/cjs/util/index.js +214 -0
  17. package/dist/cjs/util/tinyMCE.js +183 -0
  18. package/dist/es2019/actions.js +6 -0
  19. package/dist/es2019/commands.js +236 -0
  20. package/dist/es2019/edge-cases/index.js +87 -0
  21. package/dist/es2019/edge-cases/lists.js +113 -0
  22. package/dist/es2019/handlers.js +919 -0
  23. package/dist/es2019/index.js +1 -1
  24. package/dist/es2019/plugin.js +38 -0
  25. package/dist/es2019/plugins/media.js +204 -0
  26. package/dist/es2019/pm-plugins/analytics.js +332 -0
  27. package/dist/es2019/pm-plugins/clipboard-text-serializer.js +37 -0
  28. package/dist/es2019/pm-plugins/main.js +453 -0
  29. package/dist/es2019/pm-plugins/plugin-factory.js +30 -0
  30. package/dist/es2019/reducer.js +32 -0
  31. package/dist/es2019/util/index.js +209 -0
  32. package/dist/es2019/util/tinyMCE.js +168 -0
  33. package/dist/esm/actions.js +6 -0
  34. package/dist/esm/commands.js +249 -0
  35. package/dist/esm/edge-cases/index.js +81 -0
  36. package/dist/esm/edge-cases/lists.js +98 -0
  37. package/dist/esm/handlers.js +918 -0
  38. package/dist/esm/index.js +1 -1
  39. package/dist/esm/plugin.js +37 -0
  40. package/dist/esm/plugins/media.js +199 -0
  41. package/dist/esm/pm-plugins/analytics.js +364 -0
  42. package/dist/esm/pm-plugins/clipboard-text-serializer.js +37 -0
  43. package/dist/esm/pm-plugins/main.js +471 -0
  44. package/dist/esm/pm-plugins/plugin-factory.js +36 -0
  45. package/dist/esm/reducer.js +34 -0
  46. package/dist/esm/util/index.js +194 -0
  47. package/dist/esm/util/tinyMCE.js +176 -0
  48. package/dist/types/actions.d.ts +21 -0
  49. package/dist/types/commands.d.ts +29 -0
  50. package/dist/types/edge-cases/index.d.ts +11 -0
  51. package/dist/types/edge-cases/lists.d.ts +18 -0
  52. package/dist/types/handlers.d.ts +55 -0
  53. package/dist/types/index.d.ts +1 -0
  54. package/dist/types/plugin.d.ts +2 -0
  55. package/dist/types/plugins/media.d.ts +23 -0
  56. package/dist/types/pm-plugins/analytics.d.ts +44 -0
  57. package/dist/types/pm-plugins/clipboard-text-serializer.d.ts +13 -0
  58. package/dist/types/pm-plugins/main.d.ts +12 -0
  59. package/dist/types/pm-plugins/plugin-factory.d.ts +3 -0
  60. package/dist/types/reducer.d.ts +3 -0
  61. package/dist/types/util/index.d.ts +21 -0
  62. package/dist/types/util/tinyMCE.d.ts +32 -0
  63. package/dist/types-ts4.5/actions.d.ts +21 -0
  64. package/dist/types-ts4.5/commands.d.ts +29 -0
  65. package/dist/types-ts4.5/edge-cases/index.d.ts +11 -0
  66. package/dist/types-ts4.5/edge-cases/lists.d.ts +18 -0
  67. package/dist/types-ts4.5/handlers.d.ts +55 -0
  68. package/dist/types-ts4.5/index.d.ts +1 -0
  69. package/dist/types-ts4.5/plugin.d.ts +2 -0
  70. package/dist/types-ts4.5/plugins/media.d.ts +23 -0
  71. package/dist/types-ts4.5/pm-plugins/analytics.d.ts +44 -0
  72. package/dist/types-ts4.5/pm-plugins/clipboard-text-serializer.d.ts +13 -0
  73. package/dist/types-ts4.5/pm-plugins/main.d.ts +12 -0
  74. package/dist/types-ts4.5/pm-plugins/plugin-factory.d.ts +3 -0
  75. package/dist/types-ts4.5/reducer.d.ts +3 -0
  76. package/dist/types-ts4.5/util/index.d.ts +21 -0
  77. package/dist/types-ts4.5/util/tinyMCE.d.ts +32 -0
  78. package/package.json +18 -6
@@ -0,0 +1,87 @@
1
+ import { isListNode } from '@atlaskit/editor-common/utils';
2
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
3
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
4
+ import { findParentNodeOfType, safeInsert } from '@atlaskit/editor-prosemirror/utils';
5
+ import { isCursorSelectionAtTextStartOrEnd, isEmptyNode, isSelectionInsidePanel } from '../util';
6
+ import { insertSliceAtNodeEdge, insertSliceInsideOfPanelNodeSelected, insertSliceIntoEmptyNode, insertSliceIntoRangeSelectionInsideList } from './lists';
7
+ export function insertSliceForLists({
8
+ tr,
9
+ slice,
10
+ schema
11
+ }) {
12
+ var _slice$content$firstC;
13
+ const {
14
+ selection,
15
+ selection: {
16
+ $to,
17
+ $from
18
+ }
19
+ } = tr;
20
+ const {
21
+ $cursor
22
+ } = selection;
23
+ const panelNode = isSelectionInsidePanel(selection);
24
+ const selectionIsInsideList = $from.blockRange($to, isListNode);
25
+ if (!$cursor && selectionIsInsideList) {
26
+ return insertSliceIntoRangeSelectionInsideList({
27
+ tr,
28
+ slice
29
+ });
30
+ }
31
+
32
+ // if inside an empty panel, try and insert content inside it rather than replace it
33
+ if (panelNode && isEmptyNode(panelNode) && $from.node() === $to.node()) {
34
+ return insertSliceInsideOfPanelNodeSelected(panelNode)({
35
+ tr,
36
+ slice
37
+ });
38
+ }
39
+ if (!$cursor || selectionIsInsideList) {
40
+ return tr.replaceSelection(slice);
41
+ }
42
+ if (isEmptyNode(tr.doc.resolve($cursor.pos).node())) {
43
+ return insertSliceIntoEmptyNode({
44
+ tr,
45
+ slice
46
+ });
47
+ }
48
+
49
+ // When pasting a single list item into an action or decision, we skip the special "insert at node edge"
50
+ // logic so that prosemirror pastes the list's content into the action/decision, rather than
51
+ // pasting a whole list node directly after the action/decision item. (But we still preserve the
52
+ // existing "insert at" node edge" behaviour if dealing with a list with more than one item, so that
53
+ // it still inserts whole list node after the action/decision item).
54
+ const pastingIntoActionOrDecision = Boolean(findParentNodeOfType([schema.nodes.taskList, schema.nodes.decisionList])(selection));
55
+ const oneListItem = slice.content.childCount === 1 && isListNode(slice.content.firstChild) && ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.childCount) === 1;
56
+ if (!(pastingIntoActionOrDecision && oneListItem) && isCursorSelectionAtTextStartOrEnd(selection)) {
57
+ return insertSliceAtNodeEdge({
58
+ tr,
59
+ slice
60
+ });
61
+ }
62
+ tr.replaceSelection(slice);
63
+ }
64
+ export function insertSliceForListsInsideBlockquote({
65
+ tr,
66
+ slice
67
+ }) {
68
+ safeInsert(slice.content, tr.selection.$to.pos)(tr).scrollIntoView();
69
+ // ProseMirror doesn't give a proper way to tell us where something was inserted.
70
+ // However, we can know "how" it inserted something.
71
+ //
72
+ // So, instead of weird depth calculations, we can use the step produced by the transform.
73
+ // For instance:
74
+ // The `replaceStep.to and replaceStep.from`, tell us the real position
75
+ // where the content will be insert.
76
+ // Then, we can use the `tr.mapping.map` to the updated position after the replace operation
77
+ const replaceStep = tr.steps[0];
78
+ if (!(replaceStep instanceof ReplaceStep)) {
79
+ return tr;
80
+ }
81
+ const nextPosition = tr.mapping.map(replaceStep.to);
82
+ // The findFrom will make search for both: TextSelection and NodeSelections.
83
+ const nextSelection = Selection.findFrom(tr.doc.resolve(Math.min(nextPosition, tr.doc.content.size)), -1);
84
+ if (nextSelection) {
85
+ tr.setSelection(nextSelection);
86
+ }
87
+ }
@@ -0,0 +1,113 @@
1
+ import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
2
+ import { Fragment } from '@atlaskit/editor-prosemirror/model';
3
+ import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
4
+ import { Transform } from '@atlaskit/editor-prosemirror/transform';
5
+ export function insertSliceIntoEmptyNode({
6
+ tr,
7
+ slice
8
+ }) {
9
+ tr.replaceSelection(slice);
10
+ }
11
+ export function insertSliceAtNodeEdge({
12
+ tr,
13
+ slice
14
+ }) {
15
+ const {
16
+ selection
17
+ } = tr;
18
+ const {
19
+ $cursor
20
+ } = selection;
21
+ if (!$cursor) {
22
+ return;
23
+ }
24
+ const position = !$cursor.nodeBefore ? $cursor.before() : $cursor.after();
25
+ tr.replaceRange(position, position, slice);
26
+ const startSlicePosition = tr.doc.resolve(Math.min(position + slice.content.size - slice.openEnd, tr.doc.content.size));
27
+ const direction = -1;
28
+ tr.setSelection(TextSelection.near(startSlicePosition, direction));
29
+ }
30
+ export function insertSliceIntoRangeSelectionInsideList({
31
+ tr,
32
+ slice
33
+ }) {
34
+ const {
35
+ selection: {
36
+ $to,
37
+ $from,
38
+ to,
39
+ from
40
+ }
41
+ } = tr;
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
+ const newRange = $from.blockRange($to);
51
+ if (!newRange) {
52
+ return;
53
+ }
54
+ const startPos = from;
55
+ const endPos = $to.nodeAfter ? to : to + 2;
56
+ const newSlice = tr.doc.slice(endPos, newRange.end);
57
+ tr.deleteRange(startPos, newRange.end);
58
+ const mapped = tr.mapping.map(startPos);
59
+ tr.replaceRange(mapped, mapped, slice);
60
+ if (newSlice.size <= 0) {
61
+ return;
62
+ }
63
+ const newSelection = 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(TextSelection.near(tr.doc.resolve(newSelection.from), -1));
68
+ }
69
+ export function insertSliceInsideOfPanelNodeSelected(panelNode) {
70
+ return ({
71
+ tr,
72
+ slice
73
+ }) => {
74
+ const {
75
+ selection,
76
+ selection: {
77
+ $to,
78
+ $from
79
+ }
80
+ } = tr;
81
+ const {
82
+ from: panelPosition
83
+ } = selection;
84
+
85
+ // if content of slice isn't valid for a panel node, insert the invalid node and following content after
86
+ if (panelNode && !panelNode.type.validContent(Fragment.from(slice.content))) {
87
+ var _parentNode$firstChil;
88
+ const insertPosition = $to.pos + 1;
89
+ tr.replaceRange(insertPosition, insertPosition, slice);
90
+ // need to delete the empty paragraph at the top of the panel
91
+ const parentNode = tr.doc.resolve($from.before()).node();
92
+ if (parentNode && parentNode.childCount > 1 && ((_parentNode$firstChil = parentNode.firstChild) === null || _parentNode$firstChil === void 0 ? void 0 : _parentNode$firstChil.type.name) === 'paragraph' && isEmptyParagraph(parentNode.firstChild)) {
93
+ const startPosDelete = tr.doc.resolve($from.before()).posAtIndex(0);
94
+ const endPosDelete = tr.doc.resolve($from.before()).posAtIndex(1);
95
+ const SIZE_OF_EMPTY_PARAGRAPH = 2; // {startPos}<p>{startPos + 1}</p>{endPos}
96
+ if (endPosDelete - startPosDelete === SIZE_OF_EMPTY_PARAGRAPH) {
97
+ tr.delete(startPosDelete, endPosDelete);
98
+ }
99
+ }
100
+ tr.setSelection(TextSelection.near(tr.doc.resolve(insertPosition + slice.content.size - slice.openStart - slice.openEnd + 1)));
101
+ return;
102
+ }
103
+ const temporaryDoc = new Transform(tr.doc.type.createAndFill());
104
+ temporaryDoc.replaceRange(0, temporaryDoc.doc.content.size, slice);
105
+ const sliceWithoutInvalidListSurrounding = temporaryDoc.doc.slice(0);
106
+ const newPanel = panelNode.copy(sliceWithoutInvalidListSurrounding.content);
107
+ const panelNodeSelected = selection instanceof NodeSelection ? selection.node : null;
108
+ const replaceFrom = panelNodeSelected ? panelPosition : tr.doc.resolve(panelPosition).start();
109
+ const replaceTo = panelNodeSelected ? panelPosition + panelNodeSelected.nodeSize : replaceFrom;
110
+ tr.replaceRangeWith(replaceFrom, replaceTo, newPanel);
111
+ tr.setSelection(TextSelection.near(tr.doc.resolve($from.pos + newPanel.content.size), -1));
112
+ };
113
+ }