@atlaskit/editor-plugin-block-menu 6.0.3 → 6.0.5
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 +17 -0
- package/dist/cjs/editor-actions/isTransformToTargetDisabled.js +1 -1
- package/dist/cjs/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +46 -0
- package/dist/cjs/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.js +91 -0
- package/dist/cjs/editor-commands/transform-node-utils/transform.js +31 -12
- package/dist/cjs/editor-commands/transform-node-utils/utils.js +4 -1
- package/dist/cjs/editor-commands/transformNode.js +65 -66
- package/dist/es2019/editor-actions/isTransformToTargetDisabled.js +1 -1
- package/dist/es2019/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +28 -0
- package/dist/es2019/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.js +75 -0
- package/dist/es2019/editor-commands/transform-node-utils/transform.js +30 -11
- package/dist/es2019/editor-commands/transform-node-utils/utils.js +4 -1
- package/dist/es2019/editor-commands/transformNode.js +64 -68
- package/dist/esm/editor-actions/isTransformToTargetDisabled.js +1 -1
- package/dist/esm/editor-commands/transform-node-utils/steps/convertEachNodeStep.js +39 -0
- package/dist/esm/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.js +85 -0
- package/dist/esm/editor-commands/transform-node-utils/transform.js +30 -11
- package/dist/esm/editor-commands/transform-node-utils/utils.js +4 -1
- package/dist/esm/editor-commands/transformNode.js +64 -66
- package/dist/types/editor-commands/transform-node-utils/steps/convertEachNodeStep.d.ts +2 -0
- package/dist/types/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.d.ts +32 -0
- package/dist/types/editor-commands/transform-node-utils/transform.d.ts +17 -1
- package/dist/types/editor-commands/transform-node-utils/utils.d.ts +1 -1
- package/dist/types/editor-commands/transformNode.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/convertEachNodeStep.d.ts +2 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.d.ts +32 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/transform.d.ts +17 -1
- package/dist/types-ts4.5/editor-commands/transform-node-utils/utils.d.ts +1 -1
- package/dist/types-ts4.5/editor-commands/transformNode.d.ts +1 -1
- package/package.json +3 -3
- package/dist/cjs/editor-commands/transform-node-utils/tranformContent.js +0 -18
- package/dist/es2019/editor-commands/transform-node-utils/tranformContent.js +0 -12
- package/dist/esm/editor-commands/transform-node-utils/tranformContent.js +0 -12
- package/dist/types/editor-commands/transform-node-utils/tranformContent.d.ts +0 -3
- package/dist/types-ts4.5/editor-commands/transform-node-utils/tranformContent.d.ts +0 -3
|
@@ -3,74 +3,70 @@ import { startMeasure, stopMeasure } from '@atlaskit/editor-common/performance-m
|
|
|
3
3
|
import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
|
|
4
4
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { isNestedNode } from '../ui/utils/isNestedNode';
|
|
6
|
-
import {
|
|
6
|
+
import { convertNodesToTargetType } from './transform-node-utils/transform';
|
|
7
7
|
import { isListNode } from './transforms/utils';
|
|
8
|
-
export const transformNode = api =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var _api$blockControls, _api$blockControls$sh;
|
|
15
|
-
const preservedSelection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
|
|
16
|
-
if (!preservedSelection) {
|
|
17
|
-
return tr;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Start performance measurement
|
|
21
|
-
const measureId = `transformNode_${targetType.name}_${Date.now()}`;
|
|
22
|
-
startMeasure(measureId);
|
|
23
|
-
const schema = tr.doc.type.schema;
|
|
24
|
-
const {
|
|
25
|
-
nodes
|
|
26
|
-
} = schema;
|
|
27
|
-
const {
|
|
28
|
-
$from,
|
|
29
|
-
$to
|
|
30
|
-
} = expandSelectionToBlockRange(preservedSelection);
|
|
31
|
-
const selectedParent = $from.parent;
|
|
32
|
-
const isParentLayout = selectedParent.type === nodes.layoutColumn;
|
|
33
|
-
const isNestedExceptLayout = isNestedNode(preservedSelection, '') && !isParentLayout;
|
|
34
|
-
const isList = isListNode(selectedParent);
|
|
35
|
-
const slice = tr.doc.slice(isList ? $from.pos - 1 : $from.pos, isList ? $to.pos + 1 : $to.pos);
|
|
36
|
-
|
|
37
|
-
// Collect source node information for analytics before transformation
|
|
38
|
-
let nodeCount = 0;
|
|
39
|
-
const sourceNodeTypes = {};
|
|
40
|
-
slice.content.forEach(node => {
|
|
41
|
-
nodeCount++;
|
|
42
|
-
const nodeTypeName = node.type.name;
|
|
43
|
-
sourceNodeTypes[nodeTypeName] = (sourceNodeTypes[nodeTypeName] || 0) + 1;
|
|
44
|
-
});
|
|
45
|
-
const transformedNodes = tranformContent(slice.content, targetType, schema, isNestedExceptLayout, metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs);
|
|
46
|
-
const nodesToDeleteAndInsert = [nodes.mediaSingle];
|
|
47
|
-
if (preservedSelection instanceof NodeSelection && nodesToDeleteAndInsert.includes(preservedSelection.node.type)) {
|
|
48
|
-
// when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats
|
|
49
|
-
tr.deleteRange($from.pos, $to.pos);
|
|
50
|
-
tr.insert($from.pos, transformedNodes);
|
|
51
|
-
} else {
|
|
52
|
-
tr.replaceWith(isList ? $from.pos - 1 : $from.pos, $to.pos, transformedNodes);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Stop performance measurement and fire analytics
|
|
56
|
-
stopMeasure(measureId, (duration, startTime) => {
|
|
57
|
-
var _api$analytics, _api$analytics$action;
|
|
58
|
-
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent({
|
|
59
|
-
action: ACTION.TRANSFORMED,
|
|
60
|
-
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
61
|
-
actionSubjectId: ACTION_SUBJECT_ID.TRANSFORM,
|
|
62
|
-
attributes: {
|
|
63
|
-
duration,
|
|
64
|
-
isList,
|
|
65
|
-
isNested: isNestedExceptLayout,
|
|
66
|
-
nodeCount,
|
|
67
|
-
sourceNodeTypes,
|
|
68
|
-
startTime,
|
|
69
|
-
targetNodeType: targetType.name
|
|
70
|
-
},
|
|
71
|
-
eventType: EVENT_TYPE.OPERATIONAL
|
|
72
|
-
});
|
|
73
|
-
});
|
|
8
|
+
export const transformNode = api => (targetType, metadata) => ({
|
|
9
|
+
tr
|
|
10
|
+
}) => {
|
|
11
|
+
var _api$blockControls, _api$blockControls$sh;
|
|
12
|
+
const preservedSelection = api === null || api === void 0 ? void 0 : (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : (_api$blockControls$sh = _api$blockControls.sharedState.currentState()) === null || _api$blockControls$sh === void 0 ? void 0 : _api$blockControls$sh.preservedSelection;
|
|
13
|
+
if (!preservedSelection) {
|
|
74
14
|
return tr;
|
|
75
|
-
}
|
|
15
|
+
}
|
|
16
|
+
const measureId = `transformNode_${targetType.name}_${Date.now()}`;
|
|
17
|
+
startMeasure(measureId);
|
|
18
|
+
const {
|
|
19
|
+
nodes
|
|
20
|
+
} = tr.doc.type.schema;
|
|
21
|
+
const {
|
|
22
|
+
$from,
|
|
23
|
+
$to
|
|
24
|
+
} = expandSelectionToBlockRange(preservedSelection);
|
|
25
|
+
const selectedParent = $from.parent;
|
|
26
|
+
const isParentLayout = selectedParent.type === nodes.layoutColumn;
|
|
27
|
+
const isNested = isNestedNode(preservedSelection, '') && !isParentLayout;
|
|
28
|
+
const isList = isListNode(selectedParent);
|
|
29
|
+
const sliceStart = isList ? $from.pos - 1 : $from.pos;
|
|
30
|
+
const sliceEnd = isList ? $to.pos + 1 : $to.pos;
|
|
31
|
+
const slice = tr.doc.slice(sliceStart, sliceEnd);
|
|
32
|
+
const sourceNodes = [...slice.content.content];
|
|
33
|
+
const sourceNodeTypes = {};
|
|
34
|
+
sourceNodes.forEach(node => {
|
|
35
|
+
const typeName = node.type.name;
|
|
36
|
+
sourceNodeTypes[typeName] = (sourceNodeTypes[typeName] || 0) + 1;
|
|
37
|
+
});
|
|
38
|
+
const resultNodes = convertNodesToTargetType({
|
|
39
|
+
sourceNodes,
|
|
40
|
+
targetNodeType: targetType,
|
|
41
|
+
schema: tr.doc.type.schema,
|
|
42
|
+
isNested,
|
|
43
|
+
targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs,
|
|
44
|
+
parentNode: selectedParent
|
|
45
|
+
});
|
|
46
|
+
const content = resultNodes.length > 0 ? resultNodes : slice.content;
|
|
47
|
+
if (preservedSelection instanceof NodeSelection && preservedSelection.node.type === nodes.mediaSingle) {
|
|
48
|
+
tr.deleteRange($from.pos, $to.pos);
|
|
49
|
+
tr.insert($from.pos, content);
|
|
50
|
+
} else {
|
|
51
|
+
tr.replaceWith(sliceStart, $to.pos, content);
|
|
52
|
+
}
|
|
53
|
+
stopMeasure(measureId, (duration, startTime) => {
|
|
54
|
+
var _api$analytics, _api$analytics$action;
|
|
55
|
+
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent({
|
|
56
|
+
action: ACTION.TRANSFORMED,
|
|
57
|
+
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
58
|
+
actionSubjectId: ACTION_SUBJECT_ID.TRANSFORM,
|
|
59
|
+
attributes: {
|
|
60
|
+
duration,
|
|
61
|
+
isList,
|
|
62
|
+
isNested,
|
|
63
|
+
nodeCount: sourceNodes.length,
|
|
64
|
+
sourceNodeTypes,
|
|
65
|
+
startTime,
|
|
66
|
+
targetNodeType: targetType.name
|
|
67
|
+
},
|
|
68
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
return tr;
|
|
76
72
|
};
|
|
@@ -4,7 +4,7 @@ import { isTransformDisabledBasedOnStepsConfig } from '../editor-commands/transf
|
|
|
4
4
|
import { toNodeTypeValue } from '../editor-commands/transform-node-utils/types';
|
|
5
5
|
import { getBlockNodesInRange, getTargetNodeTypeNameInContext } from '../editor-commands/transform-node-utils/utils';
|
|
6
6
|
export var canParentContainNodeType = function canParentContainNodeType(schema, selectedNodeTypeName, parentNode, nodeTypeName, nodeTypeAttrs) {
|
|
7
|
-
var adjustedNodeTypeName =
|
|
7
|
+
var adjustedNodeTypeName = getTargetNodeTypeNameInContext(nodeTypeName, true, parentNode);
|
|
8
8
|
if (!adjustedNodeTypeName) {
|
|
9
9
|
return false;
|
|
10
10
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
import { convertNodesToTargetType } from '../transform';
|
|
6
|
+
export var convertEachNodeStep = function convertEachNodeStep(nodes, context) {
|
|
7
|
+
var schema = context.schema,
|
|
8
|
+
targetNodeTypeName = context.targetNodeTypeName,
|
|
9
|
+
targetAttrs = context.targetAttrs;
|
|
10
|
+
var targetNodeType = schema.nodes[targetNodeTypeName];
|
|
11
|
+
if (!targetNodeType) {
|
|
12
|
+
return nodes;
|
|
13
|
+
}
|
|
14
|
+
var resultNodes = [];
|
|
15
|
+
var _iterator = _createForOfIteratorHelper(nodes),
|
|
16
|
+
_step;
|
|
17
|
+
try {
|
|
18
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
19
|
+
var node = _step.value;
|
|
20
|
+
var transformedNodes = convertNodesToTargetType({
|
|
21
|
+
sourceNodes: [node],
|
|
22
|
+
targetNodeType: targetNodeType,
|
|
23
|
+
schema: schema,
|
|
24
|
+
isNested: false,
|
|
25
|
+
targetAttrs: targetAttrs
|
|
26
|
+
});
|
|
27
|
+
if (transformedNodes.length > 0) {
|
|
28
|
+
resultNodes.push.apply(resultNodes, _toConsumableArray(transformedNodes));
|
|
29
|
+
} else {
|
|
30
|
+
resultNodes.push(node);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} catch (err) {
|
|
34
|
+
_iterator.e(err);
|
|
35
|
+
} finally {
|
|
36
|
+
_iterator.f();
|
|
37
|
+
}
|
|
38
|
+
return resultNodes;
|
|
39
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
2
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
3
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
4
|
+
import { isListWithIndentation } from '../nodeChecks';
|
|
5
|
+
/**
|
|
6
|
+
* Merges consecutive lists of the same type into a single list.
|
|
7
|
+
* This step is useful after multiToListStep which may create multiple separate lists
|
|
8
|
+
* that should be combined.
|
|
9
|
+
*
|
|
10
|
+
* Handles both nestable lists (bulletList, orderedList, taskList) and
|
|
11
|
+
* non-nestable lists (decisionList).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* Input:
|
|
15
|
+
* - bulletList
|
|
16
|
+
* - listItem "1"
|
|
17
|
+
* - bulletList
|
|
18
|
+
* - listItem "2"
|
|
19
|
+
* - panel (non-list node)
|
|
20
|
+
* - bulletList
|
|
21
|
+
* - listItem "3"
|
|
22
|
+
*
|
|
23
|
+
* Output:
|
|
24
|
+
* - bulletList
|
|
25
|
+
* - listItem "1"
|
|
26
|
+
* - listItem "2"
|
|
27
|
+
* - panel (non-list node)
|
|
28
|
+
* - bulletList
|
|
29
|
+
* - listItem "3"
|
|
30
|
+
*
|
|
31
|
+
* @param nodes - The nodes to process
|
|
32
|
+
* @param context - The transformation context
|
|
33
|
+
* @returns The merged nodes
|
|
34
|
+
*/
|
|
35
|
+
export var mergeNeighbourListsStep = function mergeNeighbourListsStep(nodes, context) {
|
|
36
|
+
if (nodes.length === 0) {
|
|
37
|
+
return nodes;
|
|
38
|
+
}
|
|
39
|
+
var schema = context.schema;
|
|
40
|
+
var resultNodes = [];
|
|
41
|
+
var currentList = null;
|
|
42
|
+
|
|
43
|
+
// Check if a node is any type of list (including decisionList)
|
|
44
|
+
var isList = function isList(node) {
|
|
45
|
+
return isListWithIndentation(node.type.name, schema) || node.type.name === 'decisionList';
|
|
46
|
+
};
|
|
47
|
+
var _iterator = _createForOfIteratorHelper(nodes),
|
|
48
|
+
_step;
|
|
49
|
+
try {
|
|
50
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
51
|
+
var node = _step.value;
|
|
52
|
+
// Check if this node is any type of list
|
|
53
|
+
if (isList(node)) {
|
|
54
|
+
if (currentList && currentList.type === node.type) {
|
|
55
|
+
// Merge with the current list by combining their children
|
|
56
|
+
var mergedContent = currentList.content.append(node.content);
|
|
57
|
+
currentList = currentList.type.create(currentList.attrs, mergedContent);
|
|
58
|
+
} else {
|
|
59
|
+
// Start a new list or switch to a different list type
|
|
60
|
+
if (currentList) {
|
|
61
|
+
resultNodes.push(currentList);
|
|
62
|
+
}
|
|
63
|
+
currentList = node;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
// Non-list node - push any accumulated list and then this node
|
|
67
|
+
if (currentList) {
|
|
68
|
+
resultNodes.push(currentList);
|
|
69
|
+
currentList = null;
|
|
70
|
+
}
|
|
71
|
+
resultNodes.push(node);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Don't forget the last list if we ended with one
|
|
76
|
+
} catch (err) {
|
|
77
|
+
_iterator.e(err);
|
|
78
|
+
} finally {
|
|
79
|
+
_iterator.f();
|
|
80
|
+
}
|
|
81
|
+
if (currentList) {
|
|
82
|
+
resultNodes.push(currentList);
|
|
83
|
+
}
|
|
84
|
+
return resultNodes;
|
|
85
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { getTargetNodeTypeNameInContext } from '../transform-node-utils/utils';
|
|
2
2
|
import { flattenStep } from './flattenStep';
|
|
3
3
|
import { applyTargetTextTypeStep } from './steps/applyTargetTextTypeStep';
|
|
4
|
+
import { convertEachNodeStep } from './steps/convertEachNodeStep';
|
|
4
5
|
import { decisionListToListStep } from './steps/decisionListToListStep';
|
|
5
6
|
import { flattenListStep } from './steps/flattenListStep';
|
|
6
7
|
import { listToDecisionListStep } from './steps/listToDecisionListStep';
|
|
7
8
|
import { listToListStep } from './steps/listToListStep';
|
|
9
|
+
import { mergeNeighbourListsStep } from './steps/mergeNeighbourListsStep';
|
|
8
10
|
import { unwrapLayoutStep } from './steps/unwrapLayoutStep';
|
|
9
11
|
import { unwrapListStep } from './steps/unwrapListStep';
|
|
10
12
|
import { wrapBlockquoteToDecisionListStep } from './steps/wrapBlockquoteToDecisionListStep';
|
|
@@ -50,10 +52,8 @@ var TRANSFORM_STEPS = {
|
|
|
50
52
|
multi: {
|
|
51
53
|
atomic: undefined,
|
|
52
54
|
container: [wrapMixedContentStep],
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// TODO: EDITOR-4140 - Implement multi text transform
|
|
56
|
-
text: undefined,
|
|
55
|
+
list: [convertEachNodeStep, mergeNeighbourListsStep],
|
|
56
|
+
text: [convertEachNodeStep],
|
|
57
57
|
multi: undefined
|
|
58
58
|
}
|
|
59
59
|
};
|
|
@@ -217,6 +217,10 @@ var TRANSFORM_STEPS_OVERRIDE = {
|
|
|
217
217
|
decisionList: null
|
|
218
218
|
},
|
|
219
219
|
multi: {
|
|
220
|
+
// TODO: EDITOR-4140 - Implement multiple paragraphs/headings/codeblocks to heading transform
|
|
221
|
+
heading: null,
|
|
222
|
+
// TODO: EDITOR-4141 - Implement multiple codeblocks/headings to paragraph transform
|
|
223
|
+
paragraph: null,
|
|
220
224
|
// TODO: EDITOR-4138 - Implement multi content to layout transform
|
|
221
225
|
layoutSection: undefined
|
|
222
226
|
}
|
|
@@ -232,22 +236,37 @@ var getTransformStepsForNodeTypes = function getTransformStepsForNodeTypes(selec
|
|
|
232
236
|
var steps = overrideSteps !== null && overrideSteps !== void 0 ? overrideSteps : TRANSFORM_STEPS[fromCategory][toCategory];
|
|
233
237
|
return steps;
|
|
234
238
|
};
|
|
235
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Convert a list of nodes to a target node type.
|
|
241
|
+
* If no steps are found, the source nodes are returned unchanged.
|
|
242
|
+
* If steps are found, they are applied to the source nodes in order.
|
|
243
|
+
* If a step returns an empty array, the source nodes are returned.
|
|
244
|
+
* If a step returns a non-empty array, that array is returned.
|
|
245
|
+
* @param args - The conversion arguments
|
|
246
|
+
* @param args.sourceNodes - The list of nodes to convert
|
|
247
|
+
* @param args.targetNodeType - The type of node to convert into
|
|
248
|
+
* @param args.schema - The schema to use for the conversion
|
|
249
|
+
* @param args.isNested - Whether the conversion is nested
|
|
250
|
+
* @param args.targetAttrs - The attributes to use for the conversion
|
|
251
|
+
* @param args.parentNode - The parent node of the selected node
|
|
252
|
+
* @returns The converted list of nodes
|
|
253
|
+
*/
|
|
254
|
+
export var convertNodesToTargetType = function convertNodesToTargetType(_ref) {
|
|
236
255
|
var sourceNodes = _ref.sourceNodes,
|
|
237
256
|
targetNodeType = _ref.targetNodeType,
|
|
238
257
|
schema = _ref.schema,
|
|
239
258
|
isNested = _ref.isNested,
|
|
240
|
-
targetAttrs = _ref.targetAttrs
|
|
259
|
+
targetAttrs = _ref.targetAttrs,
|
|
260
|
+
parentNode = _ref.parentNode;
|
|
241
261
|
var sourceNode = sourceNodes.at(0);
|
|
242
262
|
if (!sourceNode) {
|
|
243
|
-
return;
|
|
263
|
+
return sourceNodes;
|
|
244
264
|
}
|
|
245
265
|
var selectedNodeTypeName = toNodeTypeValue(getNodeName(sourceNodes));
|
|
246
266
|
var initialTargetNodeTypeName = toNodeTypeValue(targetNodeType.name);
|
|
247
|
-
var targetNodeTypeName = getTargetNodeTypeNameInContext(initialTargetNodeTypeName, isNested);
|
|
267
|
+
var targetNodeTypeName = getTargetNodeTypeNameInContext(initialTargetNodeTypeName, isNested, parentNode);
|
|
248
268
|
if (!selectedNodeTypeName || !targetNodeTypeName) {
|
|
249
|
-
|
|
250
|
-
return;
|
|
269
|
+
return sourceNodes;
|
|
251
270
|
}
|
|
252
271
|
var steps = getTransformStepsForNodeTypes(selectedNodeTypeName, targetNodeTypeName);
|
|
253
272
|
var context = {
|
|
@@ -258,7 +277,7 @@ export var getOutputNodes = function getOutputNodes(_ref) {
|
|
|
258
277
|
targetAttrs: targetAttrs
|
|
259
278
|
};
|
|
260
279
|
if (!steps || steps.length === 0) {
|
|
261
|
-
return;
|
|
280
|
+
return sourceNodes;
|
|
262
281
|
}
|
|
263
282
|
return steps.reduce(function (nodes, step) {
|
|
264
283
|
return step(nodes, context);
|
|
@@ -43,7 +43,10 @@ export var getSelectedNode = function getSelectedNode(selection) {
|
|
|
43
43
|
}
|
|
44
44
|
return undefined;
|
|
45
45
|
};
|
|
46
|
-
export var getTargetNodeTypeNameInContext = function getTargetNodeTypeNameInContext(nodeTypeName, isNested) {
|
|
46
|
+
export var getTargetNodeTypeNameInContext = function getTargetNodeTypeNameInContext(nodeTypeName, isNested, parentNode) {
|
|
47
|
+
if (parentNode && isNested && (parentNode.type.name === 'layoutColumn' || parentNode.type.name === 'bodiedSyncBlock')) {
|
|
48
|
+
return nodeTypeName;
|
|
49
|
+
}
|
|
47
50
|
if (nodeTypeName === 'expand' && isNested) {
|
|
48
51
|
return 'nestedExpand';
|
|
49
52
|
}
|
|
@@ -1,75 +1,73 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
2
3
|
import { startMeasure, stopMeasure } from '@atlaskit/editor-common/performance-measures';
|
|
3
4
|
import { expandSelectionToBlockRange } from '@atlaskit/editor-common/selection';
|
|
4
5
|
import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
|
|
5
6
|
import { isNestedNode } from '../ui/utils/isNestedNode';
|
|
6
|
-
import {
|
|
7
|
+
import { convertNodesToTargetType } from './transform-node-utils/transform';
|
|
7
8
|
import { isListNode } from './transforms/utils';
|
|
8
9
|
export var transformNode = function transformNode(api) {
|
|
9
|
-
return (
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
|
|
16
|
-
if (!preservedSelection) {
|
|
17
|
-
return tr;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Start performance measurement
|
|
21
|
-
var measureId = "transformNode_".concat(targetType.name, "_").concat(Date.now());
|
|
22
|
-
startMeasure(measureId);
|
|
23
|
-
var schema = tr.doc.type.schema;
|
|
24
|
-
var nodes = schema.nodes;
|
|
25
|
-
var _expandSelectionToBlo = expandSelectionToBlockRange(preservedSelection),
|
|
26
|
-
$from = _expandSelectionToBlo.$from,
|
|
27
|
-
$to = _expandSelectionToBlo.$to;
|
|
28
|
-
var selectedParent = $from.parent;
|
|
29
|
-
var isParentLayout = selectedParent.type === nodes.layoutColumn;
|
|
30
|
-
var isNestedExceptLayout = isNestedNode(preservedSelection, '') && !isParentLayout;
|
|
31
|
-
var isList = isListNode(selectedParent);
|
|
32
|
-
var slice = tr.doc.slice(isList ? $from.pos - 1 : $from.pos, isList ? $to.pos + 1 : $to.pos);
|
|
33
|
-
|
|
34
|
-
// Collect source node information for analytics before transformation
|
|
35
|
-
var nodeCount = 0;
|
|
36
|
-
var sourceNodeTypes = {};
|
|
37
|
-
slice.content.forEach(function (node) {
|
|
38
|
-
nodeCount++;
|
|
39
|
-
var nodeTypeName = node.type.name;
|
|
40
|
-
sourceNodeTypes[nodeTypeName] = (sourceNodeTypes[nodeTypeName] || 0) + 1;
|
|
41
|
-
});
|
|
42
|
-
var transformedNodes = tranformContent(slice.content, targetType, schema, isNestedExceptLayout, metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs);
|
|
43
|
-
var nodesToDeleteAndInsert = [nodes.mediaSingle];
|
|
44
|
-
if (preservedSelection instanceof NodeSelection && nodesToDeleteAndInsert.includes(preservedSelection.node.type)) {
|
|
45
|
-
// when node is media single, use tr.replaceWith freeze editor, if modify position, tr.replaceWith creates duplicats
|
|
46
|
-
tr.deleteRange($from.pos, $to.pos);
|
|
47
|
-
tr.insert($from.pos, transformedNodes);
|
|
48
|
-
} else {
|
|
49
|
-
tr.replaceWith(isList ? $from.pos - 1 : $from.pos, $to.pos, transformedNodes);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Stop performance measurement and fire analytics
|
|
53
|
-
stopMeasure(measureId, function (duration, startTime) {
|
|
54
|
-
var _api$analytics;
|
|
55
|
-
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.fireAnalyticsEvent({
|
|
56
|
-
action: ACTION.TRANSFORMED,
|
|
57
|
-
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
58
|
-
actionSubjectId: ACTION_SUBJECT_ID.TRANSFORM,
|
|
59
|
-
attributes: {
|
|
60
|
-
duration: duration,
|
|
61
|
-
isList: isList,
|
|
62
|
-
isNested: isNestedExceptLayout,
|
|
63
|
-
nodeCount: nodeCount,
|
|
64
|
-
sourceNodeTypes: sourceNodeTypes,
|
|
65
|
-
startTime: startTime,
|
|
66
|
-
targetNodeType: targetType.name
|
|
67
|
-
},
|
|
68
|
-
eventType: EVENT_TYPE.OPERATIONAL
|
|
69
|
-
});
|
|
70
|
-
});
|
|
10
|
+
return function (targetType, metadata) {
|
|
11
|
+
return function (_ref) {
|
|
12
|
+
var _api$blockControls;
|
|
13
|
+
var tr = _ref.tr;
|
|
14
|
+
var preservedSelection = api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 || (_api$blockControls = _api$blockControls.sharedState.currentState()) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.preservedSelection;
|
|
15
|
+
if (!preservedSelection) {
|
|
71
16
|
return tr;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
17
|
+
}
|
|
18
|
+
var measureId = "transformNode_".concat(targetType.name, "_").concat(Date.now());
|
|
19
|
+
startMeasure(measureId);
|
|
20
|
+
var nodes = tr.doc.type.schema.nodes;
|
|
21
|
+
var _expandSelectionToBlo = expandSelectionToBlockRange(preservedSelection),
|
|
22
|
+
$from = _expandSelectionToBlo.$from,
|
|
23
|
+
$to = _expandSelectionToBlo.$to;
|
|
24
|
+
var selectedParent = $from.parent;
|
|
25
|
+
var isParentLayout = selectedParent.type === nodes.layoutColumn;
|
|
26
|
+
var isNested = isNestedNode(preservedSelection, '') && !isParentLayout;
|
|
27
|
+
var isList = isListNode(selectedParent);
|
|
28
|
+
var sliceStart = isList ? $from.pos - 1 : $from.pos;
|
|
29
|
+
var sliceEnd = isList ? $to.pos + 1 : $to.pos;
|
|
30
|
+
var slice = tr.doc.slice(sliceStart, sliceEnd);
|
|
31
|
+
var sourceNodes = _toConsumableArray(slice.content.content);
|
|
32
|
+
var sourceNodeTypes = {};
|
|
33
|
+
sourceNodes.forEach(function (node) {
|
|
34
|
+
var typeName = node.type.name;
|
|
35
|
+
sourceNodeTypes[typeName] = (sourceNodeTypes[typeName] || 0) + 1;
|
|
36
|
+
});
|
|
37
|
+
var resultNodes = convertNodesToTargetType({
|
|
38
|
+
sourceNodes: sourceNodes,
|
|
39
|
+
targetNodeType: targetType,
|
|
40
|
+
schema: tr.doc.type.schema,
|
|
41
|
+
isNested: isNested,
|
|
42
|
+
targetAttrs: metadata === null || metadata === void 0 ? void 0 : metadata.targetAttrs,
|
|
43
|
+
parentNode: selectedParent
|
|
44
|
+
});
|
|
45
|
+
var content = resultNodes.length > 0 ? resultNodes : slice.content;
|
|
46
|
+
if (preservedSelection instanceof NodeSelection && preservedSelection.node.type === nodes.mediaSingle) {
|
|
47
|
+
tr.deleteRange($from.pos, $to.pos);
|
|
48
|
+
tr.insert($from.pos, content);
|
|
49
|
+
} else {
|
|
50
|
+
tr.replaceWith(sliceStart, $to.pos, content);
|
|
51
|
+
}
|
|
52
|
+
stopMeasure(measureId, function (duration, startTime) {
|
|
53
|
+
var _api$analytics;
|
|
54
|
+
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 || _api$analytics.fireAnalyticsEvent({
|
|
55
|
+
action: ACTION.TRANSFORMED,
|
|
56
|
+
actionSubject: ACTION_SUBJECT.ELEMENT,
|
|
57
|
+
actionSubjectId: ACTION_SUBJECT_ID.TRANSFORM,
|
|
58
|
+
attributes: {
|
|
59
|
+
duration: duration,
|
|
60
|
+
isList: isList,
|
|
61
|
+
isNested: isNested,
|
|
62
|
+
nodeCount: sourceNodes.length,
|
|
63
|
+
sourceNodeTypes: sourceNodeTypes,
|
|
64
|
+
startTime: startTime,
|
|
65
|
+
targetNodeType: targetType.name
|
|
66
|
+
},
|
|
67
|
+
eventType: EVENT_TYPE.OPERATIONAL
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return tr;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
75
73
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TransformStep } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Merges consecutive lists of the same type into a single list.
|
|
4
|
+
* This step is useful after multiToListStep which may create multiple separate lists
|
|
5
|
+
* that should be combined.
|
|
6
|
+
*
|
|
7
|
+
* Handles both nestable lists (bulletList, orderedList, taskList) and
|
|
8
|
+
* non-nestable lists (decisionList).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* Input:
|
|
12
|
+
* - bulletList
|
|
13
|
+
* - listItem "1"
|
|
14
|
+
* - bulletList
|
|
15
|
+
* - listItem "2"
|
|
16
|
+
* - panel (non-list node)
|
|
17
|
+
* - bulletList
|
|
18
|
+
* - listItem "3"
|
|
19
|
+
*
|
|
20
|
+
* Output:
|
|
21
|
+
* - bulletList
|
|
22
|
+
* - listItem "1"
|
|
23
|
+
* - listItem "2"
|
|
24
|
+
* - panel (non-list node)
|
|
25
|
+
* - bulletList
|
|
26
|
+
* - listItem "3"
|
|
27
|
+
*
|
|
28
|
+
* @param nodes - The nodes to process
|
|
29
|
+
* @param context - The transformation context
|
|
30
|
+
* @returns The merged nodes
|
|
31
|
+
*/
|
|
32
|
+
export declare const mergeNeighbourListsStep: TransformStep;
|
|
@@ -2,11 +2,27 @@ import { type Node as PMNode, type NodeType, type Schema } from '@atlaskit/edito
|
|
|
2
2
|
import type { NodeTypeName } from './types';
|
|
3
3
|
interface GetOutputNodesArgs {
|
|
4
4
|
isNested: boolean;
|
|
5
|
+
parentNode?: PMNode;
|
|
5
6
|
schema: Schema;
|
|
6
7
|
sourceNodes: PMNode[];
|
|
7
8
|
targetAttrs?: Record<string, unknown>;
|
|
8
9
|
targetNodeType: NodeType;
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Convert a list of nodes to a target node type.
|
|
13
|
+
* If no steps are found, the source nodes are returned unchanged.
|
|
14
|
+
* If steps are found, they are applied to the source nodes in order.
|
|
15
|
+
* If a step returns an empty array, the source nodes are returned.
|
|
16
|
+
* If a step returns a non-empty array, that array is returned.
|
|
17
|
+
* @param args - The conversion arguments
|
|
18
|
+
* @param args.sourceNodes - The list of nodes to convert
|
|
19
|
+
* @param args.targetNodeType - The type of node to convert into
|
|
20
|
+
* @param args.schema - The schema to use for the conversion
|
|
21
|
+
* @param args.isNested - Whether the conversion is nested
|
|
22
|
+
* @param args.targetAttrs - The attributes to use for the conversion
|
|
23
|
+
* @param args.parentNode - The parent node of the selected node
|
|
24
|
+
* @returns The converted list of nodes
|
|
25
|
+
*/
|
|
26
|
+
export declare const convertNodesToTargetType: ({ sourceNodes, targetNodeType, schema, isNested, targetAttrs, parentNode, }: GetOutputNodesArgs) => PMNode[];
|
|
11
27
|
export declare const isTransformDisabledBasedOnStepsConfig: (selectedNodeType: NodeTypeName, targetNodeType: NodeTypeName) => boolean;
|
|
12
28
|
export {};
|
|
@@ -3,7 +3,7 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
3
3
|
import { type ContentNodeWithPos } from '@atlaskit/editor-prosemirror/utils';
|
|
4
4
|
import type { NodeTypeName } from './types';
|
|
5
5
|
export declare const getSelectedNode: (selection: Selection) => ContentNodeWithPos | undefined;
|
|
6
|
-
export declare const getTargetNodeTypeNameInContext: (nodeTypeName: NodeTypeName | null, isNested?: boolean) => NodeTypeName | null;
|
|
6
|
+
export declare const getTargetNodeTypeNameInContext: (nodeTypeName: NodeTypeName | null, isNested?: boolean, parentNode?: PMNode) => NodeTypeName | null;
|
|
7
7
|
/**
|
|
8
8
|
* Converts a nestedExpand to a regular expand node.
|
|
9
9
|
* NestedExpands can only exist inside expands, so when breaking out or placing
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EditorCommand, ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
2
|
-
import {
|
|
2
|
+
import type { NodeType } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import type { BlockMenuPlugin } from '../blockMenuPluginType';
|
|
4
4
|
import type { TransformNodeMetadata } from './transforms/types';
|
|
5
5
|
export declare const transformNode: (api?: ExtractInjectionAPI<BlockMenuPlugin>) => (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand;
|
package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/mergeNeighbourListsStep.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TransformStep } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Merges consecutive lists of the same type into a single list.
|
|
4
|
+
* This step is useful after multiToListStep which may create multiple separate lists
|
|
5
|
+
* that should be combined.
|
|
6
|
+
*
|
|
7
|
+
* Handles both nestable lists (bulletList, orderedList, taskList) and
|
|
8
|
+
* non-nestable lists (decisionList).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* Input:
|
|
12
|
+
* - bulletList
|
|
13
|
+
* - listItem "1"
|
|
14
|
+
* - bulletList
|
|
15
|
+
* - listItem "2"
|
|
16
|
+
* - panel (non-list node)
|
|
17
|
+
* - bulletList
|
|
18
|
+
* - listItem "3"
|
|
19
|
+
*
|
|
20
|
+
* Output:
|
|
21
|
+
* - bulletList
|
|
22
|
+
* - listItem "1"
|
|
23
|
+
* - listItem "2"
|
|
24
|
+
* - panel (non-list node)
|
|
25
|
+
* - bulletList
|
|
26
|
+
* - listItem "3"
|
|
27
|
+
*
|
|
28
|
+
* @param nodes - The nodes to process
|
|
29
|
+
* @param context - The transformation context
|
|
30
|
+
* @returns The merged nodes
|
|
31
|
+
*/
|
|
32
|
+
export declare const mergeNeighbourListsStep: TransformStep;
|