@atlaskit/editor-plugin-paste 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/cjs/plugin.js +11 -2
- package/dist/cjs/pm-plugins/move-analytics/actions.js +11 -0
- package/dist/cjs/pm-plugins/move-analytics/commands.js +45 -0
- package/dist/cjs/pm-plugins/move-analytics/plugin-factory.js +13 -0
- package/dist/cjs/pm-plugins/move-analytics/plugin-key.js +8 -0
- package/dist/cjs/pm-plugins/move-analytics/plugin.js +138 -0
- package/dist/cjs/pm-plugins/move-analytics/reducer.js +26 -0
- package/dist/cjs/pm-plugins/move-analytics/types.js +19 -0
- package/dist/cjs/pm-plugins/move-analytics/utils.js +120 -0
- package/dist/es2019/plugin.js +12 -2
- package/dist/es2019/pm-plugins/move-analytics/actions.js +5 -0
- package/dist/es2019/pm-plugins/move-analytics/commands.js +28 -0
- package/dist/es2019/pm-plugins/move-analytics/plugin-factory.js +8 -0
- package/dist/es2019/pm-plugins/move-analytics/plugin-key.js +2 -0
- package/dist/es2019/pm-plugins/move-analytics/plugin.js +144 -0
- package/dist/es2019/pm-plugins/move-analytics/reducer.js +21 -0
- package/dist/es2019/pm-plugins/move-analytics/types.js +13 -0
- package/dist/es2019/pm-plugins/move-analytics/utils.js +124 -0
- package/dist/esm/plugin.js +11 -2
- package/dist/esm/pm-plugins/move-analytics/actions.js +5 -0
- package/dist/esm/pm-plugins/move-analytics/commands.js +38 -0
- package/dist/esm/pm-plugins/move-analytics/plugin-factory.js +8 -0
- package/dist/esm/pm-plugins/move-analytics/plugin-key.js +2 -0
- package/dist/esm/pm-plugins/move-analytics/plugin.js +133 -0
- package/dist/esm/pm-plugins/move-analytics/reducer.js +19 -0
- package/dist/esm/pm-plugins/move-analytics/types.js +13 -0
- package/dist/esm/pm-plugins/move-analytics/utils.js +114 -0
- package/dist/types/pm-plugins/move-analytics/actions.d.ts +14 -0
- package/dist/types/pm-plugins/move-analytics/commands.d.ts +5 -0
- package/dist/types/pm-plugins/move-analytics/plugin-factory.d.ts +1 -0
- package/dist/types/pm-plugins/move-analytics/plugin-key.d.ts +3 -0
- package/dist/types/pm-plugins/move-analytics/plugin.d.ts +4 -0
- package/dist/types/pm-plugins/move-analytics/reducer.d.ts +3 -0
- package/dist/types/pm-plugins/move-analytics/types.d.ts +11 -0
- package/dist/types/pm-plugins/move-analytics/utils.d.ts +12 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/actions.d.ts +14 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/commands.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/plugin-factory.d.ts +1 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/plugin-key.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/plugin.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/reducer.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/types.d.ts +11 -0
- package/dist/types-ts4.5/pm-plugins/move-analytics/utils.d.ts +12 -0
- package/dist/types-ts4.5/types.d.ts +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-paste
|
|
2
2
|
|
|
3
|
+
## 1.3.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#115170](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/115170)
|
|
8
|
+
[`84489f16bb385`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/84489f16bb385) -
|
|
9
|
+
Adds a pm-plugin to register contentMoved event as an alternative to DnD feature.
|
|
10
|
+
|
|
3
11
|
## 1.3.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/dist/cjs/plugin.js
CHANGED
|
@@ -5,15 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.pastePlugin = void 0;
|
|
7
7
|
var _main = require("./pm-plugins/main");
|
|
8
|
+
var _plugin = require("./pm-plugins/move-analytics/plugin");
|
|
8
9
|
var _pluginFactory = require("./pm-plugins/plugin-factory");
|
|
9
10
|
var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
|
|
10
|
-
var _api$featureFlags;
|
|
11
|
+
var _api$featureFlags, _api$analytics;
|
|
11
12
|
var config = _ref.config,
|
|
12
13
|
api = _ref.api;
|
|
13
14
|
var _ref2 = config !== null && config !== void 0 ? config : {},
|
|
14
15
|
cardOptions = _ref2.cardOptions,
|
|
15
|
-
sanitizePrivateContent = _ref2.sanitizePrivateContent
|
|
16
|
+
sanitizePrivateContent = _ref2.sanitizePrivateContent,
|
|
17
|
+
isFullPage = _ref2.isFullPage;
|
|
16
18
|
var featureFlags = (api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
19
|
+
var editorAnalyticsAPI = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
17
20
|
return {
|
|
18
21
|
name: 'paste',
|
|
19
22
|
pmPlugins: function pmPlugins() {
|
|
@@ -26,6 +29,12 @@ var pastePlugin = exports.pastePlugin = function pastePlugin(_ref) {
|
|
|
26
29
|
dispatch = _ref3.dispatch;
|
|
27
30
|
return (0, _main.createPlugin)(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, cardOptions, sanitizePrivateContent, providerFactory);
|
|
28
31
|
}
|
|
32
|
+
}, {
|
|
33
|
+
name: 'moveAnalyticsPlugin',
|
|
34
|
+
plugin: function plugin(_ref4) {
|
|
35
|
+
var dispatch = _ref4.dispatch;
|
|
36
|
+
return isFullPage ? (0, _plugin.createPlugin)(dispatch, editorAnalyticsAPI) : undefined;
|
|
37
|
+
}
|
|
29
38
|
}];
|
|
30
39
|
},
|
|
31
40
|
getSharedState: function getSharedState(editorState) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MoveAnalyticPluginTypes = void 0;
|
|
7
|
+
var MoveAnalyticPluginTypes = exports.MoveAnalyticPluginTypes = /*#__PURE__*/function (MoveAnalyticPluginTypes) {
|
|
8
|
+
MoveAnalyticPluginTypes[MoveAnalyticPluginTypes["UpdateMovedAction"] = 0] = "UpdateMovedAction";
|
|
9
|
+
MoveAnalyticPluginTypes[MoveAnalyticPluginTypes["RemoveMovedAction"] = 1] = "RemoveMovedAction";
|
|
10
|
+
return MoveAnalyticPluginTypes;
|
|
11
|
+
}({});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.updateContentMoved = exports.resetContentMovedTransform = exports.resetContentMoved = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _actions = require("./actions");
|
|
10
|
+
var _pluginFactory = require("./plugin-factory");
|
|
11
|
+
var _pluginKey = require("./plugin-key");
|
|
12
|
+
var updateContentMoved = exports.updateContentMoved = function updateContentMoved(nextState, nextAction) {
|
|
13
|
+
return (0, _pluginFactory.createCommand)(function (state) {
|
|
14
|
+
var _getPluginState = (0, _pluginFactory.getPluginState)(state),
|
|
15
|
+
contentMoved = _getPluginState.contentMoved;
|
|
16
|
+
var data = {
|
|
17
|
+
currentActions: [].concat((0, _toConsumableArray2.default)(contentMoved.currentActions), [nextAction]),
|
|
18
|
+
size: (nextState === null || nextState === void 0 ? void 0 : nextState.size) || contentMoved.size,
|
|
19
|
+
nodeName: nextState === null || nextState === void 0 ? void 0 : nextState.nodeName
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
type: _actions.MoveAnalyticPluginTypes.UpdateMovedAction,
|
|
23
|
+
data: data
|
|
24
|
+
};
|
|
25
|
+
}, function (tr) {
|
|
26
|
+
return tr.setMeta('addToHistory', false);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
var resetContentMoved = exports.resetContentMoved = function resetContentMoved() {
|
|
30
|
+
return (0, _pluginFactory.createCommand)(function () {
|
|
31
|
+
return {
|
|
32
|
+
type: _actions.MoveAnalyticPluginTypes.RemoveMovedAction
|
|
33
|
+
};
|
|
34
|
+
}, function (tr) {
|
|
35
|
+
return tr.setMeta('addToHistory', false);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
var resetContentMovedTransform = exports.resetContentMovedTransform = function resetContentMovedTransform() {
|
|
39
|
+
return function (tr) {
|
|
40
|
+
var payload = {
|
|
41
|
+
type: _actions.MoveAnalyticPluginTypes.RemoveMovedAction
|
|
42
|
+
};
|
|
43
|
+
return tr.setMeta(_pluginKey.pluginKey, payload);
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getPluginState = exports.createPluginState = exports.createCommand = void 0;
|
|
7
|
+
var _utils = require("@atlaskit/editor-common/utils");
|
|
8
|
+
var _pluginKey = require("./plugin-key");
|
|
9
|
+
var _reducer = require("./reducer");
|
|
10
|
+
var _pluginFactory = (0, _utils.pluginFactory)(_pluginKey.pluginKey, _reducer.reducer),
|
|
11
|
+
createPluginState = exports.createPluginState = _pluginFactory.createPluginState,
|
|
12
|
+
createCommand = exports.createCommand = _pluginFactory.createCommand,
|
|
13
|
+
getPluginState = exports.getPluginState = _pluginFactory.getPluginState;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createPlugin = void 0;
|
|
7
|
+
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
8
|
+
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
9
|
+
var _commands = require("./commands");
|
|
10
|
+
var _pluginFactory = require("./plugin-factory");
|
|
11
|
+
var _pluginKey = require("./plugin-key");
|
|
12
|
+
var _types = require("./types");
|
|
13
|
+
var _utils = require("./utils");
|
|
14
|
+
// This plugin exists only in FullPage/FullWidth Editor and is used to register an event that tells us
|
|
15
|
+
// that a user cut and than pasted a node. This order of actions could be considered an alternative
|
|
16
|
+
// to new Drag and Drop functionality. The event (document moved) is not accurate, but should be enough to be
|
|
17
|
+
// used during DnD roll out. After DnD release this plugin must be removed.
|
|
18
|
+
var createPlugin = exports.createPlugin = function createPlugin(dispatch, editorAnalyticsAPI) {
|
|
19
|
+
// This variable is used to distinguish between copy and cut events in transformCopied.
|
|
20
|
+
var isCutEvent = false;
|
|
21
|
+
return new _safePlugin.SafePlugin({
|
|
22
|
+
key: _pluginKey.pluginKey,
|
|
23
|
+
state: (0, _pluginFactory.createPluginState)(dispatch, _types.defaultState),
|
|
24
|
+
props: {
|
|
25
|
+
handleDOMEvents: {
|
|
26
|
+
cut: function cut() {
|
|
27
|
+
isCutEvent = true;
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
handlePaste: function handlePaste(_ref, event, slice) {
|
|
31
|
+
var _content$firstChild;
|
|
32
|
+
var state = _ref.state,
|
|
33
|
+
dispatch = _ref.dispatch;
|
|
34
|
+
// The state was cleaned after previous paste. We don't need to update plugin state
|
|
35
|
+
// with 'contentPasted' if currentActions array doesn't have 'copiedOrCut'.
|
|
36
|
+
var _getPluginState = (0, _pluginFactory.getPluginState)(state),
|
|
37
|
+
contentMoved = _getPluginState.contentMoved;
|
|
38
|
+
var hasCutAction = contentMoved.currentActions.includes('contentCut');
|
|
39
|
+
if (!hasCutAction) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
var content = slice.content,
|
|
43
|
+
size = slice.size;
|
|
44
|
+
var nodeName = (_content$firstChild = content.firstChild) === null || _content$firstChild === void 0 ? void 0 : _content$firstChild.type.name;
|
|
45
|
+
// We should not account for pastes that go inside another node and create nested content as DnD can't do it.
|
|
46
|
+
if (!nodeName || !(contentMoved !== null && contentMoved !== void 0 && contentMoved.nodeName) || !(0, _utils.isValidNodeName)(contentMoved === null || contentMoved === void 0 ? void 0 : contentMoved.nodeName, nodeName) || size !== (contentMoved === null || contentMoved === void 0 ? void 0 : contentMoved.size) || !(0, _utils.isCursorSelectionAndInsideTopLevelNode)(state.selection)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
var tr = state.tr;
|
|
50
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
|
|
51
|
+
action: _analytics.ACTION.MOVED,
|
|
52
|
+
actionSubject: _analytics.ACTION_SUBJECT.DOCUMENT,
|
|
53
|
+
actionSubjectId: _analytics.ACTION_SUBJECT_ID.NODE,
|
|
54
|
+
eventType: _analytics.EVENT_TYPE.TRACK,
|
|
55
|
+
attributes: {
|
|
56
|
+
nodeType: contentMoved === null || contentMoved === void 0 ? void 0 : contentMoved.nodeName // keep nodeName from copied slice
|
|
57
|
+
}
|
|
58
|
+
})(tr);
|
|
59
|
+
|
|
60
|
+
// reset to default state
|
|
61
|
+
var updatedTr = (0, _commands.resetContentMovedTransform)()(tr);
|
|
62
|
+
dispatch(updatedTr);
|
|
63
|
+
},
|
|
64
|
+
transformCopied: function transformCopied(slice, _ref2) {
|
|
65
|
+
var _content$firstChild2;
|
|
66
|
+
var state = _ref2.state,
|
|
67
|
+
dispatch = _ref2.dispatch;
|
|
68
|
+
// We want to listen only to 'cut' events
|
|
69
|
+
if (!isCutEvent) {
|
|
70
|
+
return slice;
|
|
71
|
+
}
|
|
72
|
+
var resetState = false;
|
|
73
|
+
var content = slice.content,
|
|
74
|
+
size = slice.size;
|
|
75
|
+
// Content should be just one node, so we added a check for slice.content.childCount === 1;
|
|
76
|
+
// 1. It is possible to select a table by dragging the mouse over the table's rows.
|
|
77
|
+
// As a result, slice will contain rows without tableNode itself and the childCount will be the number of rows.
|
|
78
|
+
// From a user's perspective the whole table is selected and copied and on paste a table will indeed be created.
|
|
79
|
+
// 2. Some block nodes can get selected when a user drags the mouse from the paragraph above the node to
|
|
80
|
+
// the paragraph below the node. Visually only the node in between is selected, in reality, three nodes are
|
|
81
|
+
// in the slice.
|
|
82
|
+
// These cases are ignored and moveContent event won't be counted.
|
|
83
|
+
if (content.childCount !== 1) {
|
|
84
|
+
resetState = true;
|
|
85
|
+
}
|
|
86
|
+
var nodeName = ((_content$firstChild2 = content.firstChild) === null || _content$firstChild2 === void 0 ? void 0 : _content$firstChild2.type.name) || '';
|
|
87
|
+
// Some nodes are not relevant as they are parts of nodes, not whole nodes (like tableCell, tableHeader instead of table node)
|
|
88
|
+
// Some nodes like lists, taskList(item), decisionList(item) requires tricky checks that we want to avoid doing.
|
|
89
|
+
// These nodes were added to excludedNodes array.
|
|
90
|
+
if (!resetState && (0, _utils.isExcludedNode)(nodeName)) {
|
|
91
|
+
resetState = true;
|
|
92
|
+
}
|
|
93
|
+
var selection = state.selection;
|
|
94
|
+
// DnD can't drag part of text in a paragraph/heading. DnD will select the whole node with all the text inside.
|
|
95
|
+
// So we are only interested in cut slices that contain the entire node, not just a part of it.
|
|
96
|
+
if (!resetState && nodeName === 'paragraph' && !(0, _utils.isEntireTopLevelHeadingOrParagraphSelected)(selection, nodeName)) {
|
|
97
|
+
resetState = true;
|
|
98
|
+
}
|
|
99
|
+
if (!resetState && nodeName === 'heading' && !(0, _utils.isEntireTopLevelHeadingOrParagraphSelected)(selection, nodeName)) {
|
|
100
|
+
resetState = true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// DnD can't drag just one paragraph (when blockquote contains multiple paragraphs) or just a part of a paragraph in the blockquote.
|
|
104
|
+
// DnD will select and drag the whole blockquote. So we need to register cut events that have the entire blockquote too.
|
|
105
|
+
if (!resetState && nodeName === 'blockquote' && !(0, _utils.isEntireTopLevelBlockquoteSelected)(state)) {
|
|
106
|
+
resetState = true;
|
|
107
|
+
}
|
|
108
|
+
if (!resetState && (0, _utils.isInlineNode)(nodeName) && (0, _utils.isNestedInlineNode)(selection)) {
|
|
109
|
+
resetState = true;
|
|
110
|
+
}
|
|
111
|
+
if (!resetState && nodeName === 'table' && (0, _utils.isNestedTable)(selection)) {
|
|
112
|
+
resetState = true;
|
|
113
|
+
}
|
|
114
|
+
var isBlockNode = (0, _utils.isBlockNodeWithoutTable)(nodeName);
|
|
115
|
+
if (!resetState && (0, _utils.isNodeSelection)(selection) && isBlockNode && selection.$anchor.node().type.name !== 'doc' // checks that the block node is not a topLevel node
|
|
116
|
+
) {
|
|
117
|
+
resetState = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Some blockNodes can have text inside of them cut, in that case TextSelection occurs, we don't need to track
|
|
121
|
+
// these cut events.
|
|
122
|
+
if (!resetState && (0, _utils.isTextSelection)(selection) && isBlockNode) {
|
|
123
|
+
resetState = true;
|
|
124
|
+
}
|
|
125
|
+
if (resetState) {
|
|
126
|
+
(0, _commands.resetContentMoved)()(state, dispatch);
|
|
127
|
+
} else {
|
|
128
|
+
(0, _commands.updateContentMoved)({
|
|
129
|
+
size: size,
|
|
130
|
+
nodeName: nodeName
|
|
131
|
+
}, 'contentCut')(state, dispatch);
|
|
132
|
+
}
|
|
133
|
+
isCutEvent = false;
|
|
134
|
+
return slice;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.reducer = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _actions = require("./actions");
|
|
10
|
+
var _types = require("./types");
|
|
11
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
|
+
var reducer = exports.reducer = function reducer(state, action) {
|
|
14
|
+
switch (action.type) {
|
|
15
|
+
case _actions.MoveAnalyticPluginTypes.UpdateMovedAction:
|
|
16
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
17
|
+
contentMoved: _objectSpread(_objectSpread({}, state.contentMoved), action.data)
|
|
18
|
+
});
|
|
19
|
+
case _actions.MoveAnalyticPluginTypes.RemoveMovedAction:
|
|
20
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
21
|
+
contentMoved: _types.defaultState.contentMoved
|
|
22
|
+
});
|
|
23
|
+
default:
|
|
24
|
+
return state;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.defaultState = void 0;
|
|
7
|
+
// For an event to be considered a move content event we want to ensure that
|
|
8
|
+
// cut had happened and was followed by paste. So our currentActions array should
|
|
9
|
+
// look like this ['contentCut', 'contentPasted'];
|
|
10
|
+
// After removing appendTransaction we don't update currentActions with 'contentPasted'
|
|
11
|
+
// but leaving it as array in case we decide to change it back or add 'contentCopied'.
|
|
12
|
+
|
|
13
|
+
var defaultState = exports.defaultState = {
|
|
14
|
+
contentMoved: {
|
|
15
|
+
nodeName: undefined,
|
|
16
|
+
size: undefined,
|
|
17
|
+
currentActions: []
|
|
18
|
+
}
|
|
19
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isValidNodeName = exports.isTextSelection = exports.isNodeSelection = exports.isNestedTable = exports.isNestedInlineNode = exports.isInlineNode = exports.isExcludedNode = exports.isEntireTopLevelHeadingOrParagraphSelected = exports.isEntireTopLevelBlockquoteSelected = exports.isCursorSelectionAndInsideTopLevelNode = exports.isBlockNodeWithoutTable = void 0;
|
|
7
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
8
|
+
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
|
+
var excludedNodes = ['caption', 'layoutColumn', 'listItem', 'nestedExpand', 'tableHeader', 'tableCell', 'tableRow', 'text', 'placeholder', 'unsupportedBlock', 'unsupportedInline', 'hardBreak', 'media', 'confluenceUnsupportedBlock', 'confluenceUnsupportedInline', 'bulletList', 'orderedList', 'taskList', 'taskItem', 'decisionList', 'decisionItem'];
|
|
10
|
+
var isExcludedNode = exports.isExcludedNode = function isExcludedNode(nodeName) {
|
|
11
|
+
return excludedNodes.includes(nodeName);
|
|
12
|
+
};
|
|
13
|
+
var isCursorSelectionAndInsideTopLevelNode = exports.isCursorSelectionAndInsideTopLevelNode = function isCursorSelectionAndInsideTopLevelNode(selection) {
|
|
14
|
+
var $from = selection.$from,
|
|
15
|
+
from = selection.from,
|
|
16
|
+
to = selection.to;
|
|
17
|
+
if (from !== to || $from.depth > 1) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
};
|
|
22
|
+
var inlineNodes = ['emoji', 'date', 'status', 'mention', 'mediaInline', 'inlineCard', 'inlineExtension'];
|
|
23
|
+
var isInlineNode = exports.isInlineNode = function isInlineNode(nodeName) {
|
|
24
|
+
return inlineNodes.includes(nodeName);
|
|
25
|
+
};
|
|
26
|
+
var isNestedInlineNode = exports.isNestedInlineNode = function isNestedInlineNode(selection) {
|
|
27
|
+
if (selection.$from.depth !== 1) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// check if the node is a part of a larger paragraph or heading
|
|
32
|
+
var parentSize = selection.$from.parent.content.size;
|
|
33
|
+
var contentSize = selection.content().size;
|
|
34
|
+
var parentChildCount = selection.$from.parent.childCount;
|
|
35
|
+
// when the node was copied and pasted, it won't have extra space the parent has only one child
|
|
36
|
+
if (parentChildCount === 1) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// some inline nodes (like date and emoji) when inserted have extra space that is stores as a child
|
|
41
|
+
if (parentChildCount === 2 && parentSize - contentSize === 1) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
46
|
+
var blockNodes = ['bodiedExtension', 'blockCard', 'codeBlock', 'embedCard', 'expand', 'extension', 'layoutSection', 'mediaGroup', 'mediaSingle', 'panel', 'rule'];
|
|
47
|
+
var isBlockNodeWithoutTable = exports.isBlockNodeWithoutTable = function isBlockNodeWithoutTable(nodeName) {
|
|
48
|
+
return blockNodes.includes(nodeName);
|
|
49
|
+
};
|
|
50
|
+
var parentNodes = ['expand', 'extension', 'bodiedExtension', 'layoutSection'];
|
|
51
|
+
var isNestedTable = exports.isNestedTable = function isNestedTable(selection) {
|
|
52
|
+
var parentNode = selection.$anchor.node(1);
|
|
53
|
+
return parentNode && parentNodes.includes(parentNode.type.name);
|
|
54
|
+
};
|
|
55
|
+
var getPastedNameOfInlineNode = function getPastedNameOfInlineNode(nodeName) {
|
|
56
|
+
if (inlineNodes.includes(nodeName)) {
|
|
57
|
+
return 'paragraph';
|
|
58
|
+
}
|
|
59
|
+
return nodeName;
|
|
60
|
+
};
|
|
61
|
+
var isValidNodeName = exports.isValidNodeName = function isValidNodeName(copiedNodeName, pastedNodeName) {
|
|
62
|
+
if (copiedNodeName === pastedNodeName) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (getPastedNameOfInlineNode(copiedNodeName) === pastedNodeName) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
};
|
|
70
|
+
var isTextSelection = exports.isTextSelection = function isTextSelection(selection) {
|
|
71
|
+
return selection instanceof _state.TextSelection && selection.from !== selection.to;
|
|
72
|
+
};
|
|
73
|
+
var isNodeSelection = exports.isNodeSelection = function isNodeSelection(selection) {
|
|
74
|
+
return selection instanceof _state.NodeSelection;
|
|
75
|
+
};
|
|
76
|
+
var isEntireHeadingOrParagraphSelected = function isEntireHeadingOrParagraphSelected(selection, nodeName) {
|
|
77
|
+
if (!isTextSelection(selection)) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
var $from = selection.$from,
|
|
81
|
+
$to = selection.$to;
|
|
82
|
+
if (!($from.parent.type.name === nodeName)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if ($from.parent === $to.parent) {
|
|
86
|
+
var node = $from.parent;
|
|
87
|
+
return $from.parentOffset === 0 && $to.parentOffset === node.content.size;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var isEntireTopLevelHeadingOrParagraphSelected = exports.isEntireTopLevelHeadingOrParagraphSelected = function isEntireTopLevelHeadingOrParagraphSelected(selection, nodeName) {
|
|
91
|
+
if (selection.$from.depth !== 1) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return isEntireHeadingOrParagraphSelected(selection, nodeName);
|
|
95
|
+
};
|
|
96
|
+
var isEntireTopLevelBlockquoteSelected = exports.isEntireTopLevelBlockquoteSelected = function isEntireTopLevelBlockquoteSelected(state) {
|
|
97
|
+
var schema = state.schema,
|
|
98
|
+
selection = state.selection;
|
|
99
|
+
var blockquote = schema.nodes.blockquote;
|
|
100
|
+
var blockquoteNode = (0, _utils.findParentNodeOfTypeClosestToPos)(selection.$from, blockquote);
|
|
101
|
+
if (!blockquoteNode) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// checks if it is a top level blockquote
|
|
106
|
+
var depth = blockquoteNode.depth;
|
|
107
|
+
if (depth !== 1) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
var from = selection.from,
|
|
111
|
+
to = selection.to;
|
|
112
|
+
var selectedNodesCount = 0;
|
|
113
|
+
state.doc.nodesBetween(from, to, function (node, pos) {
|
|
114
|
+
if (pos >= from && pos + node.nodeSize <= to) {
|
|
115
|
+
selectedNodesCount++;
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return selectedNodesCount === blockquoteNode.node.childCount;
|
|
120
|
+
};
|
package/dist/es2019/plugin.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { createPlugin } from './pm-plugins/main';
|
|
2
|
+
import { createPlugin as createMoveAnalyticsPlugin } from './pm-plugins/move-analytics/plugin';
|
|
2
3
|
import { pluginKey } from './pm-plugins/plugin-factory';
|
|
3
4
|
export const pastePlugin = ({
|
|
4
5
|
config,
|
|
5
6
|
api
|
|
6
7
|
}) => {
|
|
7
|
-
var _api$featureFlags;
|
|
8
|
+
var _api$featureFlags, _api$analytics;
|
|
8
9
|
const {
|
|
9
10
|
cardOptions,
|
|
10
|
-
sanitizePrivateContent
|
|
11
|
+
sanitizePrivateContent,
|
|
12
|
+
isFullPage
|
|
11
13
|
} = config !== null && config !== void 0 ? config : {};
|
|
12
14
|
const featureFlags = (api === null || api === void 0 ? void 0 : (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
|
|
15
|
+
const editorAnalyticsAPI = api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions;
|
|
13
16
|
return {
|
|
14
17
|
name: 'paste',
|
|
15
18
|
pmPlugins() {
|
|
@@ -21,6 +24,13 @@ export const pastePlugin = ({
|
|
|
21
24
|
dispatchAnalyticsEvent,
|
|
22
25
|
dispatch
|
|
23
26
|
}) => createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, api, cardOptions, sanitizePrivateContent, providerFactory)
|
|
27
|
+
}, {
|
|
28
|
+
name: 'moveAnalyticsPlugin',
|
|
29
|
+
plugin: ({
|
|
30
|
+
dispatch
|
|
31
|
+
}) => {
|
|
32
|
+
return isFullPage ? createMoveAnalyticsPlugin(dispatch, editorAnalyticsAPI) : undefined;
|
|
33
|
+
}
|
|
24
34
|
}];
|
|
25
35
|
},
|
|
26
36
|
getSharedState: editorState => {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export let MoveAnalyticPluginTypes = /*#__PURE__*/function (MoveAnalyticPluginTypes) {
|
|
2
|
+
MoveAnalyticPluginTypes[MoveAnalyticPluginTypes["UpdateMovedAction"] = 0] = "UpdateMovedAction";
|
|
3
|
+
MoveAnalyticPluginTypes[MoveAnalyticPluginTypes["RemoveMovedAction"] = 1] = "RemoveMovedAction";
|
|
4
|
+
return MoveAnalyticPluginTypes;
|
|
5
|
+
}({});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MoveAnalyticPluginTypes } from './actions';
|
|
2
|
+
import { createCommand, getPluginState } from './plugin-factory';
|
|
3
|
+
import { pluginKey } from './plugin-key';
|
|
4
|
+
export const updateContentMoved = (nextState, nextAction) => createCommand(state => {
|
|
5
|
+
const {
|
|
6
|
+
contentMoved
|
|
7
|
+
} = getPluginState(state);
|
|
8
|
+
const data = {
|
|
9
|
+
currentActions: [...contentMoved.currentActions, nextAction],
|
|
10
|
+
size: (nextState === null || nextState === void 0 ? void 0 : nextState.size) || contentMoved.size,
|
|
11
|
+
nodeName: nextState === null || nextState === void 0 ? void 0 : nextState.nodeName
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
type: MoveAnalyticPluginTypes.UpdateMovedAction,
|
|
15
|
+
data
|
|
16
|
+
};
|
|
17
|
+
}, tr => tr.setMeta('addToHistory', false));
|
|
18
|
+
export const resetContentMoved = () => createCommand(() => {
|
|
19
|
+
return {
|
|
20
|
+
type: MoveAnalyticPluginTypes.RemoveMovedAction
|
|
21
|
+
};
|
|
22
|
+
}, tr => tr.setMeta('addToHistory', false));
|
|
23
|
+
export const resetContentMovedTransform = () => tr => {
|
|
24
|
+
const payload = {
|
|
25
|
+
type: MoveAnalyticPluginTypes.RemoveMovedAction
|
|
26
|
+
};
|
|
27
|
+
return tr.setMeta(pluginKey, payload);
|
|
28
|
+
};
|