@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.
Files changed (78) hide show
  1. package/.eslintrc.js +18 -0
  2. package/CHANGELOG.md +6 -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 +17 -5
package/dist/cjs/index.js CHANGED
@@ -2,4 +2,11 @@
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
- });
5
+ });
6
+ Object.defineProperty(exports, "pastePlugin", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _plugin.pastePlugin;
10
+ }
11
+ });
12
+ var _plugin = require("./plugin");
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.pastePlugin = void 0;
7
+ var _main = require("./pm-plugins/main");
8
+ var _pluginFactory = require("./pm-plugins/plugin-factory");
9
+ var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
10
+ var _api$featureFlags;
11
+ var config = _ref.config,
12
+ api = _ref.api;
13
+ var _ref2 = config !== null && config !== void 0 ? config : {},
14
+ cardOptions = _ref2.cardOptions,
15
+ sanitizePrivateContent = _ref2.sanitizePrivateContent;
16
+ var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
17
+ return {
18
+ name: 'paste',
19
+ pmPlugins: function pmPlugins() {
20
+ return [{
21
+ name: 'paste',
22
+ plugin: function plugin(_ref3) {
23
+ var schema = _ref3.schema,
24
+ providerFactory = _ref3.providerFactory,
25
+ dispatchAnalyticsEvent = _ref3.dispatchAnalyticsEvent,
26
+ dispatch = _ref3.dispatch;
27
+ return (0, _main.createPlugin)(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, cardOptions, sanitizePrivateContent, providerFactory);
28
+ }
29
+ }];
30
+ },
31
+ getSharedState: function getSharedState(editorState) {
32
+ if (!editorState) {
33
+ return {
34
+ lastContentPasted: null
35
+ };
36
+ }
37
+ var pluginState = _pluginFactory.pluginKey.getState(editorState);
38
+ return {
39
+ lastContentPasted: pluginState.lastContentPasted
40
+ };
41
+ }
42
+ };
43
+ };
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.isImage = void 0;
8
+ exports.transformSliceForMedia = transformSliceForMedia;
9
+ exports.unwrapNestedMediaElements = exports.transformSliceToMediaSingleWithNewExperience = exports.transformSliceToCorrectMediaWrapper = void 0;
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
+ var _mediaSingle = require("@atlaskit/editor-common/media-single");
12
+ var _utils = require("@atlaskit/editor-common/utils");
13
+ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
14
+ var _mediaCommon = require("@atlaskit/media-common");
15
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
16
+ 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; }
17
+ 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; }
18
+ /**
19
+ * Ensure correct layout in nested mode
20
+ *
21
+ * TODO: this func is only used in handlePaste, so layout update won't work for drop event
22
+ */
23
+ function transformSliceForMedia(slice, schema) {
24
+ var _schema$nodes = schema.nodes,
25
+ mediaSingle = _schema$nodes.mediaSingle,
26
+ layoutSection = _schema$nodes.layoutSection,
27
+ table = _schema$nodes.table,
28
+ bulletList = _schema$nodes.bulletList,
29
+ orderedList = _schema$nodes.orderedList,
30
+ expand = _schema$nodes.expand,
31
+ nestedExpand = _schema$nodes.nestedExpand;
32
+ return function (selection) {
33
+ var newSlice = slice;
34
+ if ((0, _utils2.hasParentNodeOfType)([layoutSection, table, bulletList, orderedList, expand, nestedExpand])(selection)) {
35
+ newSlice = (0, _utils.mapSlice)(newSlice, function (node) {
36
+ var extendedOrLegacyAttrs = (0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.extended-resize-experience') ? {
37
+ layout: node.attrs.layout,
38
+ widthType: node.attrs.widthType,
39
+ width: node.attrs.width
40
+ } : {
41
+ layout: node.attrs.layout
42
+ };
43
+ var attrs = {};
44
+ if ((0, _utils2.hasParentNodeOfType)([layoutSection, table])(selection)) {
45
+ // Supports layouts
46
+ attrs = _objectSpread({}, extendedOrLegacyAttrs);
47
+ } else if ((0, _utils2.hasParentNodeOfType)([bulletList, orderedList, expand, nestedExpand])(selection)) {
48
+ // does not support other layouts
49
+ attrs = _objectSpread(_objectSpread({}, extendedOrLegacyAttrs), {}, {
50
+ layout: 'center'
51
+ });
52
+ }
53
+ return node.type.name === 'mediaSingle' ? mediaSingle.createChecked(attrs, node.content, node.marks) : node;
54
+ });
55
+ }
56
+ return newSlice;
57
+ };
58
+ }
59
+
60
+ // TODO move this to editor-common
61
+ var isImage = exports.isImage = function isImage(fileType) {
62
+ return !!fileType && (fileType.indexOf('image/') > -1 || fileType.indexOf('video/') > -1);
63
+ };
64
+ var transformSliceToCorrectMediaWrapper = exports.transformSliceToCorrectMediaWrapper = function transformSliceToCorrectMediaWrapper(slice, schema) {
65
+ var _schema$nodes2 = schema.nodes,
66
+ mediaGroup = _schema$nodes2.mediaGroup,
67
+ mediaSingle = _schema$nodes2.mediaSingle,
68
+ media = _schema$nodes2.media;
69
+ return (0, _utils.mapSlice)(slice, function (node, parent) {
70
+ if (!parent && node.type === media) {
71
+ if (mediaSingle && (isImage(node.attrs.__fileMimeType) || node.attrs.type === 'external')) {
72
+ return mediaSingle.createChecked({}, node);
73
+ } else {
74
+ return mediaGroup.createChecked({}, [node]);
75
+ }
76
+ }
77
+ return node;
78
+ });
79
+ };
80
+
81
+ /**
82
+ * This func will be called when copy & paste, drag & drop external html with media, media files, and slices from editor
83
+ * Because width may not be available when transform, DEFAULT_IMAGE_WIDTH is used as a fallback
84
+ *
85
+ */
86
+ var transformSliceToMediaSingleWithNewExperience = exports.transformSliceToMediaSingleWithNewExperience = function transformSliceToMediaSingleWithNewExperience(slice, schema) {
87
+ var _schema$nodes3 = schema.nodes,
88
+ mediaInline = _schema$nodes3.mediaInline,
89
+ mediaSingle = _schema$nodes3.mediaSingle,
90
+ media = _schema$nodes3.media;
91
+ var newSlice = (0, _utils.mapSlice)(slice, function (node) {
92
+ // This logic is duplicated in editor-plugin-ai where external images can be inserted
93
+ // from external sources through the use of AI. The editor-plugin-ai package is avoiding
94
+ // sharing dependencies with editor-core to support products using it with various versions
95
+ // of editor packages.
96
+ // The duplication is in the following file:
97
+ // packages/editor/editor-plugin-ai/src/prebuilt/content-transformers/markdown-to-pm/markdown-transformer.ts
98
+ if (node.type === mediaSingle) {
99
+ return (0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.extended-resize-experience') ? mediaSingle.createChecked({
100
+ width: node.attrs.width || _mediaSingle.DEFAULT_IMAGE_WIDTH,
101
+ widthType: node.attrs.widthType || 'pixel',
102
+ layout: node.attrs.layout
103
+ }, node.content, node.marks) : node;
104
+ }
105
+ return node;
106
+ });
107
+ return (0, _utils.mapSlice)(newSlice, function (node) {
108
+ var __mediaTraceId = (0, _mediaCommon.getRandomHex)(8);
109
+ if (node.type === media) {
110
+ return media.createChecked(_objectSpread(_objectSpread({}, node.attrs), {}, {
111
+ __external: node.attrs.type === 'external',
112
+ __mediaTraceId: node.attrs.type === 'external' ? null : __mediaTraceId
113
+ }), node.content, node.marks);
114
+ }
115
+ if (node.type.name === 'mediaInline') {
116
+ return mediaInline.createChecked(_objectSpread(_objectSpread({}, node.attrs), {}, {
117
+ __mediaTraceId: __mediaTraceId
118
+ }), node.content, node.marks);
119
+ }
120
+ return node;
121
+ });
122
+ };
123
+
124
+ /**
125
+ * Check base styles to see if an element will be invisible when rendered in a document.
126
+ * @param element
127
+ */
128
+ var isElementInvisible = function isElementInvisible(element) {
129
+ return element.style.opacity === '0' || element.style.display === 'none' || element.style.visibility === 'hidden';
130
+ };
131
+ var VALID_TAGS_CONTAINER = ['DIV', 'TD'];
132
+ function canContainImage(element) {
133
+ if (!element) {
134
+ return false;
135
+ }
136
+ return VALID_TAGS_CONTAINER.indexOf(element.tagName) !== -1;
137
+ }
138
+
139
+ /**
140
+ * Given a html string, we attempt to hoist any nested `<img>` tags,
141
+ * not directly wrapped by a `<div>` as ProseMirror no-op's
142
+ * on those scenarios.
143
+ * @param html
144
+ */
145
+ var unwrapNestedMediaElements = exports.unwrapNestedMediaElements = function unwrapNestedMediaElements(html) {
146
+ var parser = new DOMParser();
147
+ var doc = parser.parseFromString(html, 'text/html');
148
+ var wrapper = doc.body;
149
+
150
+ // Remove Google Doc's wrapper <b> el
151
+ var docsWrapper = wrapper.querySelector('b[id^="docs-internal-guid-"]');
152
+ if (docsWrapper) {
153
+ (0, _utils.unwrap)(wrapper, docsWrapper);
154
+ }
155
+ var imageTags = wrapper.querySelectorAll('img');
156
+ if (!imageTags.length) {
157
+ return html;
158
+ }
159
+ imageTags.forEach(function (imageTag) {
160
+ // Capture the immediate parent, we may remove the media from here later.
161
+ var mediaParent = imageTag.parentElement;
162
+ if (!mediaParent) {
163
+ return;
164
+ }
165
+
166
+ // If either the parent or the image itself contains styles that would make
167
+ // them invisible on copy, dont paste them.
168
+ if (isElementInvisible(mediaParent) || isElementInvisible(imageTag)) {
169
+ mediaParent.removeChild(imageTag);
170
+ return;
171
+ }
172
+
173
+ // If its wrapped by a valid container we assume its safe to bypass.
174
+ // ProseMirror should handle these cases properly.
175
+ if (canContainImage(mediaParent) || mediaParent instanceof HTMLSpanElement && mediaParent.closest('[class*="emoji-common"]')) {
176
+ return;
177
+ }
178
+
179
+ // Find the top most element that the parent has a valid container for the image.
180
+ // Stop just before found the wrapper
181
+ var insertBeforeElement = (0, _utils.walkUpTreeUntil)(mediaParent, function (element) {
182
+ // If is at the top just use this element as reference
183
+ if (element.parentElement === wrapper) {
184
+ return true;
185
+ }
186
+ return canContainImage(element.parentElement);
187
+ });
188
+
189
+ // Here we try to insert the media right after its top most valid parent element
190
+ // Unless its the last element in our structure then we will insert above it.
191
+ if (insertBeforeElement && insertBeforeElement.parentElement) {
192
+ // Insert as close as possible to the most closest valid element index in the tree.
193
+ insertBeforeElement.parentElement.insertBefore(imageTag, insertBeforeElement.nextElementSibling || insertBeforeElement);
194
+
195
+ // Attempt to clean up lines left behind by the image
196
+ mediaParent.innerText = mediaParent.innerText.trim();
197
+ // Walk up and delete empty elements left over after removing the image tag
198
+ (0, _utils.removeNestedEmptyEls)(mediaParent);
199
+ }
200
+ });
201
+
202
+ // If last child is a hardbreak we don't want it
203
+ if (wrapper.lastElementChild && wrapper.lastElementChild.tagName === 'BR') {
204
+ wrapper.removeChild(wrapper.lastElementChild);
205
+ }
206
+ return wrapper.innerHTML;
207
+ };
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createPasteAnalyticsPayload = createPasteAnalyticsPayload;
8
+ exports.createPasteMeasurePayload = void 0;
9
+ exports.getContent = getContent;
10
+ exports.getContentNodeTypes = void 0;
11
+ exports.getMediaTraceId = getMediaTraceId;
12
+ exports.sendPasteAnalyticsEvent = exports.handleSelectedTableWithAnalytics = exports.handleRichTextWithAnalytics = exports.handlePastePreservingMarksWithAnalytics = exports.handlePastePanelOrDecisionIntoListWithAnalytics = exports.handlePasteNonNestableBlockNodesIntoListWithAnalytics = exports.handlePasteLinkOnSelectedTextWithAnalytics = exports.handlePasteIntoTaskAndDecisionWithAnalytics = exports.handlePasteIntoCaptionWithAnalytics = exports.handlePasteAsPlainTextWithAnalytics = exports.handleMediaSingleWithAnalytics = exports.handleMarkdownWithAnalytics = exports.handleExpandWithAnalytics = exports.handleCodeBlockWithAnalytics = void 0;
13
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
14
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
15
+ var _analytics = require("@atlaskit/editor-common/analytics");
16
+ var _utils = require("@atlaskit/editor-common/utils");
17
+ var _utils2 = require("@atlaskit/editor-prosemirror/utils");
18
+ var _handlers = require("../handlers");
19
+ var _util = require("../util");
20
+ 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; }
21
+ 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; }
22
+ var contentToPasteContent = {
23
+ url: _analytics.PasteContents.url,
24
+ paragraph: _analytics.PasteContents.text,
25
+ bulletList: _analytics.PasteContents.bulletList,
26
+ orderedList: _analytics.PasteContents.orderedList,
27
+ heading: _analytics.PasteContents.heading,
28
+ blockquote: _analytics.PasteContents.blockquote,
29
+ codeBlock: _analytics.PasteContents.codeBlock,
30
+ panel: _analytics.PasteContents.panel,
31
+ rule: _analytics.PasteContents.rule,
32
+ mediaSingle: _analytics.PasteContents.mediaSingle,
33
+ mediaCard: _analytics.PasteContents.mediaCard,
34
+ mediaGroup: _analytics.PasteContents.mediaGroup,
35
+ table: _analytics.PasteContents.table,
36
+ tableCells: _analytics.PasteContents.tableCells,
37
+ tableHeader: _analytics.PasteContents.tableHeader,
38
+ tableRow: _analytics.PasteContents.tableRow,
39
+ decisionList: _analytics.PasteContents.decisionList,
40
+ decisionItem: _analytics.PasteContents.decisionItem,
41
+ taskList: _analytics.PasteContents.taskItem,
42
+ extension: _analytics.PasteContents.extension,
43
+ bodiedExtension: _analytics.PasteContents.bodiedExtension,
44
+ blockCard: _analytics.PasteContents.blockCard,
45
+ layoutSection: _analytics.PasteContents.layoutSection
46
+ };
47
+ var nodeToActionSubjectId = {
48
+ blockquote: _analytics.ACTION_SUBJECT_ID.PASTE_BLOCKQUOTE,
49
+ blockCard: _analytics.ACTION_SUBJECT_ID.PASTE_BLOCK_CARD,
50
+ bodiedExtension: _analytics.ACTION_SUBJECT_ID.PASTE_BODIED_EXTENSION,
51
+ bulletList: _analytics.ACTION_SUBJECT_ID.PASTE_BULLET_LIST,
52
+ codeBlock: _analytics.ACTION_SUBJECT_ID.PASTE_CODE_BLOCK,
53
+ decisionList: _analytics.ACTION_SUBJECT_ID.PASTE_DECISION_LIST,
54
+ extension: _analytics.ACTION_SUBJECT_ID.PASTE_EXTENSION,
55
+ heading: _analytics.ACTION_SUBJECT_ID.PASTE_HEADING,
56
+ mediaGroup: _analytics.ACTION_SUBJECT_ID.PASTE_MEDIA_GROUP,
57
+ mediaSingle: _analytics.ACTION_SUBJECT_ID.PASTE_MEDIA_SINGLE,
58
+ orderedList: _analytics.ACTION_SUBJECT_ID.PASTE_ORDERED_LIST,
59
+ panel: _analytics.ACTION_SUBJECT_ID.PASTE_PANEL,
60
+ rule: _analytics.ACTION_SUBJECT_ID.PASTE_RULE,
61
+ table: _analytics.ACTION_SUBJECT_ID.PASTE_TABLE,
62
+ tableCell: _analytics.ACTION_SUBJECT_ID.PASTE_TABLE_CELL,
63
+ tableHeader: _analytics.ACTION_SUBJECT_ID.PASTE_TABLE_HEADER,
64
+ tableRow: _analytics.ACTION_SUBJECT_ID.PASTE_TABLE_ROW,
65
+ taskList: _analytics.ACTION_SUBJECT_ID.PASTE_TASK_LIST
66
+ };
67
+ function getContent(_ref) {
68
+ var schema = _ref.schema,
69
+ slice = _ref.slice;
70
+ var paragraph = schema.nodes.paragraph,
71
+ link = schema.marks.link;
72
+ var nodeOrMarkName = new Set();
73
+ slice.content.forEach(function (node) {
74
+ if (node.type === paragraph && node.content.size === 0) {
75
+ // Skip empty paragraph
76
+ return;
77
+ }
78
+ if (node.type.name === 'text' && link.isInSet(node.marks)) {
79
+ nodeOrMarkName.add('url');
80
+ return;
81
+ }
82
+
83
+ // Check node contain link
84
+ if (node.type === paragraph && node.rangeHasMark(0, node.nodeSize - 2, link)) {
85
+ nodeOrMarkName.add('url');
86
+ return;
87
+ }
88
+ nodeOrMarkName.add(node.type.name);
89
+ });
90
+ if (nodeOrMarkName.size > 1) {
91
+ return _analytics.PasteContents.mixed;
92
+ }
93
+ if (nodeOrMarkName.size === 0) {
94
+ return _analytics.PasteContents.uncategorized;
95
+ }
96
+ var type = nodeOrMarkName.values().next().value;
97
+ var pasteContent = contentToPasteContent[type];
98
+ return pasteContent ? pasteContent : _analytics.PasteContents.uncategorized;
99
+ }
100
+ function getMediaTraceId(slice) {
101
+ var traceId;
102
+ (0, _utils.mapSlice)(slice, function (node) {
103
+ if (node.type.name === 'media' || node.type.name === 'mediaInline') {
104
+ traceId = node.attrs.__mediaTraceId;
105
+ }
106
+ return node;
107
+ });
108
+ return traceId;
109
+ }
110
+ function getActionSubjectId(_ref2) {
111
+ var selection = _ref2.selection,
112
+ schema = _ref2.schema;
113
+ var _schema$nodes = schema.nodes,
114
+ paragraph = _schema$nodes.paragraph,
115
+ listItem = _schema$nodes.listItem,
116
+ taskItem = _schema$nodes.taskItem,
117
+ decisionItem = _schema$nodes.decisionItem;
118
+ var parent = (0, _utils2.findParentNode)(function (node) {
119
+ if (node.type !== paragraph && node.type !== listItem && node.type !== taskItem && node.type !== decisionItem) {
120
+ return true;
121
+ }
122
+ return false;
123
+ })(selection);
124
+ if (!parent) {
125
+ return _analytics.ACTION_SUBJECT_ID.PASTE_PARAGRAPH;
126
+ }
127
+ var parentType = parent.node.type;
128
+ var actionSubjectId = nodeToActionSubjectId[parentType.name];
129
+ return actionSubjectId ? actionSubjectId : _analytics.ACTION_SUBJECT_ID.PASTE_PARAGRAPH;
130
+ }
131
+ function createPasteAsPlainPayload(actionSubjectId, text, linksInPasteCount) {
132
+ return {
133
+ action: _analytics.ACTION.PASTED_AS_PLAIN,
134
+ actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
135
+ actionSubjectId: actionSubjectId,
136
+ eventType: _analytics.EVENT_TYPE.TRACK,
137
+ attributes: {
138
+ inputMethod: _analytics.INPUT_METHOD.KEYBOARD,
139
+ pasteSize: text.length,
140
+ linksInPasteCount: linksInPasteCount
141
+ }
142
+ };
143
+ }
144
+ function createPastePayload(actionSubjectId, attributes, linkDomain) {
145
+ return _objectSpread({
146
+ action: _analytics.ACTION.PASTED,
147
+ actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
148
+ actionSubjectId: actionSubjectId,
149
+ eventType: _analytics.EVENT_TYPE.TRACK,
150
+ attributes: _objectSpread({
151
+ inputMethod: _analytics.INPUT_METHOD.KEYBOARD
152
+ }, attributes)
153
+ }, linkDomain && linkDomain.length > 0 ? {
154
+ nonPrivacySafeAttributes: {
155
+ linkDomain: linkDomain
156
+ }
157
+ } : {});
158
+ }
159
+ function createPasteAnalyticsPayloadBySelection(event, slice, pasteContext) {
160
+ return function (selection) {
161
+ var text = event.clipboardData ? event.clipboardData.getData('text/plain') || event.clipboardData.getData('text/uri-list') : '';
162
+ var actionSubjectId = getActionSubjectId({
163
+ selection: selection,
164
+ schema: selection.$from.doc.type.schema
165
+ });
166
+ var pasteSize = slice.size;
167
+ var content = getContent({
168
+ schema: selection.$from.doc.type.schema,
169
+ slice: slice
170
+ });
171
+ var linkUrls = [];
172
+ var mediaTraceId = getMediaTraceId(slice);
173
+
174
+ // If we have a link among the pasted content, grab the
175
+ // domain and send it up with the analytics event
176
+ if (content === _analytics.PasteContents.url || content === _analytics.PasteContents.mixed) {
177
+ (0, _utils.mapSlice)(slice, function (node) {
178
+ var linkMark = node.marks.find(function (mark) {
179
+ return mark.type.name === 'link';
180
+ });
181
+ if (linkMark) {
182
+ linkUrls.push(linkMark.attrs.href);
183
+ }
184
+ return node;
185
+ });
186
+ }
187
+ if (pasteContext.asPlain) {
188
+ return createPasteAsPlainPayload(actionSubjectId, text, linkUrls.length);
189
+ }
190
+ var source = (0, _util.getPasteSource)(event);
191
+ if (pasteContext.type === _analytics.PasteTypes.plain) {
192
+ return createPastePayload(actionSubjectId, {
193
+ pasteSize: text.length,
194
+ type: pasteContext.type,
195
+ content: _analytics.PasteContents.text,
196
+ source: source,
197
+ hyperlinkPasteOnText: false,
198
+ linksInPasteCount: linkUrls.length,
199
+ pasteSplitList: pasteContext.pasteSplitList
200
+ });
201
+ }
202
+ var linkDomains = linkUrls.map(_utils.getLinkDomain);
203
+ return createPastePayload(actionSubjectId, {
204
+ type: pasteContext.type,
205
+ pasteSize: pasteSize,
206
+ content: content,
207
+ source: source,
208
+ hyperlinkPasteOnText: !!pasteContext.hyperlinkPasteOnText,
209
+ linksInPasteCount: linkUrls.length,
210
+ mediaTraceId: mediaTraceId,
211
+ pasteSplitList: pasteContext.pasteSplitList
212
+ }, linkDomains);
213
+ };
214
+ }
215
+ function createPasteAnalyticsPayload(view, event, slice, pasteContext) {
216
+ return createPasteAnalyticsPayloadBySelection(event, slice, pasteContext)(view.state.selection);
217
+ }
218
+
219
+ // TODO: ED-6612 We should not dispatch only analytics, it's preferred to wrap each command with his own analytics.
220
+ // However, handlers like handleMacroAutoConvert dispatch multiple time,
221
+ // so pasteCommandWithAnalytics is useless in this case.
222
+ var sendPasteAnalyticsEvent = exports.sendPasteAnalyticsEvent = function sendPasteAnalyticsEvent(editorAnalyticsAPI) {
223
+ return function (view, event, slice, pasteContext) {
224
+ var tr = view.state.tr;
225
+ var payload = createPasteAnalyticsPayload(view, event, slice, pasteContext);
226
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
227
+ view.dispatch(tr);
228
+ };
229
+ };
230
+ var handlePasteAsPlainTextWithAnalytics = exports.handlePasteAsPlainTextWithAnalytics = function handlePasteAsPlainTextWithAnalytics(editorAnalyticsAPI) {
231
+ return function (view, event, slice) {
232
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
233
+ type: _analytics.PasteTypes.plain,
234
+ asPlain: true
235
+ }))((0, _handlers.handlePasteAsPlainText)(slice, event, editorAnalyticsAPI));
236
+ };
237
+ };
238
+ var handlePasteIntoTaskAndDecisionWithAnalytics = exports.handlePasteIntoTaskAndDecisionWithAnalytics = function handlePasteIntoTaskAndDecisionWithAnalytics(view, event, slice, type, pluginInjectionApi) {
239
+ var _pluginInjectionApi$a, _pluginInjectionApi$c;
240
+ return injectAnalyticsPayloadBeforeCommand(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions)(createPasteAnalyticsPayloadBySelection(event, slice, {
241
+ type: type
242
+ }))((0, _handlers.handlePasteIntoTaskOrDecisionOrPanel)(slice, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card) === null || _pluginInjectionApi$c === void 0 || (_pluginInjectionApi$c = _pluginInjectionApi$c.actions) === null || _pluginInjectionApi$c === void 0 ? void 0 : _pluginInjectionApi$c.queueCardsFromChangedTr));
243
+ };
244
+ var handlePasteIntoCaptionWithAnalytics = exports.handlePasteIntoCaptionWithAnalytics = function handlePasteIntoCaptionWithAnalytics(editorAnalyticsAPI) {
245
+ return function (view, event, slice, type) {
246
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
247
+ type: type
248
+ }))((0, _handlers.handlePasteIntoCaption)(slice));
249
+ };
250
+ };
251
+ var handleCodeBlockWithAnalytics = exports.handleCodeBlockWithAnalytics = function handleCodeBlockWithAnalytics(editorAnalyticsAPI) {
252
+ return function (view, event, slice, text) {
253
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
254
+ type: _analytics.PasteTypes.plain
255
+ }))((0, _handlers.handleCodeBlock)(text));
256
+ };
257
+ };
258
+ var handleMediaSingleWithAnalytics = exports.handleMediaSingleWithAnalytics = function handleMediaSingleWithAnalytics(editorAnalyticsAPI) {
259
+ return function (view, event, slice, type, insertMediaAsMediaSingle) {
260
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
261
+ type: type
262
+ }))((0, _handlers.handleMediaSingle)(_analytics.INPUT_METHOD.CLIPBOARD, insertMediaAsMediaSingle)(slice));
263
+ };
264
+ };
265
+ var handlePastePreservingMarksWithAnalytics = exports.handlePastePreservingMarksWithAnalytics = function handlePastePreservingMarksWithAnalytics(view, event, slice, type, pluginInjectionApi) {
266
+ var _pluginInjectionApi$a2, _pluginInjectionApi$c2;
267
+ return injectAnalyticsPayloadBeforeCommand(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 ? void 0 : _pluginInjectionApi$a2.actions)(createPasteAnalyticsPayloadBySelection(event, slice, {
268
+ type: type
269
+ }))((0, _handlers.handlePastePreservingMarks)(slice, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.card) === null || _pluginInjectionApi$c2 === void 0 || (_pluginInjectionApi$c2 = _pluginInjectionApi$c2.actions) === null || _pluginInjectionApi$c2 === void 0 ? void 0 : _pluginInjectionApi$c2.queueCardsFromChangedTr));
270
+ };
271
+ var handleMarkdownWithAnalytics = exports.handleMarkdownWithAnalytics = function handleMarkdownWithAnalytics(view, event, slice, pluginInjectionApi) {
272
+ var _pluginInjectionApi$a3, _pluginInjectionApi$c3;
273
+ return injectAnalyticsPayloadBeforeCommand(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a3 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a3 === void 0 ? void 0 : _pluginInjectionApi$a3.actions)(createPasteAnalyticsPayloadBySelection(event, slice, {
274
+ type: _analytics.PasteTypes.markdown
275
+ }))((0, _handlers.handleMarkdown)(slice, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.card) === null || _pluginInjectionApi$c3 === void 0 || (_pluginInjectionApi$c3 = _pluginInjectionApi$c3.actions) === null || _pluginInjectionApi$c3 === void 0 ? void 0 : _pluginInjectionApi$c3.queueCardsFromChangedTr));
276
+ };
277
+ var handleRichTextWithAnalytics = exports.handleRichTextWithAnalytics = function handleRichTextWithAnalytics(view, event, slice, pluginInjectionApi) {
278
+ var _pluginInjectionApi$a4, _pluginInjectionApi$c4;
279
+ return injectAnalyticsPayloadBeforeCommand(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a4 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a4 === void 0 ? void 0 : _pluginInjectionApi$a4.actions)(createPasteAnalyticsPayloadBySelection(event, slice, {
280
+ type: _analytics.PasteTypes.richText
281
+ }))((0, _handlers.handleRichText)(slice, pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c4 = pluginInjectionApi.card) === null || _pluginInjectionApi$c4 === void 0 || (_pluginInjectionApi$c4 = _pluginInjectionApi$c4.actions) === null || _pluginInjectionApi$c4 === void 0 ? void 0 : _pluginInjectionApi$c4.queueCardsFromChangedTr));
282
+ };
283
+ var injectAnalyticsPayloadBeforeCommand = function injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI) {
284
+ return function (createPayloadByTransaction) {
285
+ return function (mainCommand) {
286
+ return function (state, dispatch, view) {
287
+ var originalTransaction = state.tr;
288
+ var fakeDispatch = function fakeDispatch(tr) {
289
+ originalTransaction = tr;
290
+ };
291
+ var result = mainCommand(state, fakeDispatch, view);
292
+ if (!result) {
293
+ return false;
294
+ }
295
+ if (dispatch && originalTransaction.docChanged) {
296
+ // it needs to know the selection before the changes
297
+ var payload = createPayloadByTransaction(state.selection);
298
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(originalTransaction);
299
+ dispatch(originalTransaction);
300
+ }
301
+ return true;
302
+ };
303
+ };
304
+ };
305
+ };
306
+ var handlePastePanelOrDecisionIntoListWithAnalytics = exports.handlePastePanelOrDecisionIntoListWithAnalytics = function handlePastePanelOrDecisionIntoListWithAnalytics(editorAnalyticsAPI) {
307
+ return function (view, event, slice, findRootParentListNode) {
308
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
309
+ type: _analytics.PasteTypes.richText
310
+ }))((0, _handlers.handlePastePanelOrDecisionContentIntoList)(slice, findRootParentListNode));
311
+ };
312
+ };
313
+ var handlePasteNonNestableBlockNodesIntoListWithAnalytics = exports.handlePasteNonNestableBlockNodesIntoListWithAnalytics = function handlePasteNonNestableBlockNodesIntoListWithAnalytics(editorAnalyticsAPI) {
314
+ return function (view, event, slice) {
315
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
316
+ type: _analytics.PasteTypes.richText,
317
+ pasteSplitList: true
318
+ }))((0, _handlers.handlePasteNonNestableBlockNodesIntoList)(slice));
319
+ };
320
+ };
321
+ var handleExpandWithAnalytics = exports.handleExpandWithAnalytics = function handleExpandWithAnalytics(editorAnalyticsAPI) {
322
+ return function (view, event, slice) {
323
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
324
+ type: _analytics.PasteTypes.richText,
325
+ pasteSplitList: true
326
+ }))((0, _handlers.handleExpandPasteInTable)(slice));
327
+ };
328
+ };
329
+ var handleSelectedTableWithAnalytics = exports.handleSelectedTableWithAnalytics = function handleSelectedTableWithAnalytics(editorAnalyticsAPI) {
330
+ return function (view, event, slice) {
331
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
332
+ type: _analytics.PasteTypes.richText
333
+ }))((0, _handlers.handleSelectedTable)(editorAnalyticsAPI)(slice));
334
+ };
335
+ };
336
+ var handlePasteLinkOnSelectedTextWithAnalytics = exports.handlePasteLinkOnSelectedTextWithAnalytics = function handlePasteLinkOnSelectedTextWithAnalytics(editorAnalyticsAPI) {
337
+ return function (view, event, slice, type) {
338
+ return injectAnalyticsPayloadBeforeCommand(editorAnalyticsAPI)(createPasteAnalyticsPayloadBySelection(event, slice, {
339
+ type: type,
340
+ hyperlinkPasteOnText: true
341
+ }))((0, _handlers.handlePasteLinkOnSelectedText)(slice));
342
+ };
343
+ };
344
+ var createPasteMeasurePayload = exports.createPasteMeasurePayload = function createPasteMeasurePayload(_ref3) {
345
+ var view = _ref3.view,
346
+ duration = _ref3.duration,
347
+ content = _ref3.content,
348
+ distortedDuration = _ref3.distortedDuration;
349
+ var pasteIntoNode = getActionSubjectId({
350
+ selection: view.state.selection,
351
+ schema: view.state.schema
352
+ });
353
+ return {
354
+ action: _analytics.ACTION.PASTED_TIMED,
355
+ actionSubject: _analytics.ACTION_SUBJECT.EDITOR,
356
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL,
357
+ attributes: {
358
+ pasteIntoNode: pasteIntoNode,
359
+ content: content,
360
+ time: duration,
361
+ distortedDuration: distortedDuration
362
+ }
363
+ };
364
+ };
365
+ var getContentNodeTypes = exports.getContentNodeTypes = function getContentNodeTypes(content) {
366
+ var nodeTypes = new Set();
367
+ if (content.size) {
368
+ content.forEach(function (node) {
369
+ if (node.content && node.content.size) {
370
+ nodeTypes = new Set([].concat((0, _toConsumableArray2.default)(nodeTypes), (0, _toConsumableArray2.default)(getContentNodeTypes(node.content))));
371
+ }
372
+ nodeTypes.add(node.type.name);
373
+ });
374
+ }
375
+ return Array.from(nodeTypes);
376
+ };