@atlaskit/editor-plugin-block-menu 5.2.13 → 5.2.15
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 +14 -0
- package/dist/cjs/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +43 -2
- package/dist/es2019/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +41 -2
- package/dist/esm/editor-commands/transform-node-utils/steps/wrapMixedContentStep.js +42 -2
- package/dist/types/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +1 -0
- package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts +1 -0
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-menu
|
|
2
2
|
|
|
3
|
+
## 5.2.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 5.2.14
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`6bf9c33a49f72`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6bf9c33a49f72) -
|
|
14
|
+
[ux] Add check for empty transformation and create blank node
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 5.2.13
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.wrapMixedContentStep = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
7
9
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
8
10
|
var _types = require("../types");
|
|
9
11
|
/**
|
|
@@ -48,6 +50,38 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
|
|
|
48
50
|
return targetNodeType.validContent(_model.Fragment.from(node));
|
|
49
51
|
};
|
|
50
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Handles the edge case where transforming from a container to another container results in
|
|
55
|
+
* all content breaking out (no valid children for the target). In this case, creates an empty
|
|
56
|
+
* container to ensure the target container type is created.
|
|
57
|
+
*
|
|
58
|
+
* We can determine if there were no valid children by checking if no container was created
|
|
59
|
+
* (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
|
|
60
|
+
* means all content broke out rather than being wrapped.
|
|
61
|
+
*
|
|
62
|
+
* @param result - The current result nodes after processing
|
|
63
|
+
* @param hasCreatedContainer - Whether a container was already created during processing
|
|
64
|
+
* @param fromNode - The original source node (before unwrapping)
|
|
65
|
+
* @param targetNodeType - The target container type
|
|
66
|
+
* @param targetNodeTypeName - The target container type name
|
|
67
|
+
* @param schema - The schema
|
|
68
|
+
* @returns The result nodes with an empty container prepended if needed, or the original result
|
|
69
|
+
*/
|
|
70
|
+
var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) {
|
|
71
|
+
var isFromContainer = _types.NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
|
|
72
|
+
var isTargetContainer = _types.NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
|
|
73
|
+
// If no container was created but we have nodes in result, all content broke out
|
|
74
|
+
// (meaning there were no valid children that could be wrapped)
|
|
75
|
+
var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
76
|
+
var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
77
|
+
if (shouldCreateEmptyTarget) {
|
|
78
|
+
var emptyParagraph = schema.nodes.paragraph.create();
|
|
79
|
+
var emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
80
|
+
return [emptyContainer].concat((0, _toConsumableArray2.default)(result));
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
};
|
|
84
|
+
|
|
51
85
|
/**
|
|
52
86
|
* A wrap step that handles mixed content according to the Compatibility Matrix:
|
|
53
87
|
* - Wraps consecutive compatible nodes into the target container
|
|
@@ -65,21 +99,25 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
|
|
|
65
99
|
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
66
100
|
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
67
101
|
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
102
|
+
* Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
|
|
68
103
|
*/
|
|
69
104
|
var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedContentStep(nodes, context) {
|
|
70
105
|
var schema = context.schema,
|
|
71
|
-
targetNodeTypeName = context.targetNodeTypeName
|
|
106
|
+
targetNodeTypeName = context.targetNodeTypeName,
|
|
107
|
+
fromNode = context.fromNode;
|
|
72
108
|
var targetNodeType = schema.nodes[targetNodeTypeName];
|
|
73
109
|
if (!targetNodeType) {
|
|
74
110
|
return nodes;
|
|
75
111
|
}
|
|
76
112
|
var result = [];
|
|
77
113
|
var currentContainerContent = [];
|
|
114
|
+
var hasCreatedContainer = false;
|
|
78
115
|
var flushCurrentContainer = function flushCurrentContainer() {
|
|
79
116
|
if (currentContainerContent.length > 0) {
|
|
80
117
|
var containerNode = targetNodeType.createAndFill({}, _model.Fragment.fromArray(currentContainerContent));
|
|
81
118
|
if (containerNode) {
|
|
82
119
|
result.push(containerNode);
|
|
120
|
+
hasCreatedContainer = true;
|
|
83
121
|
}
|
|
84
122
|
currentContainerContent = [];
|
|
85
123
|
}
|
|
@@ -110,5 +148,8 @@ var wrapMixedContentStep = exports.wrapMixedContentStep = function wrapMixedCont
|
|
|
110
148
|
|
|
111
149
|
// Flush any remaining content into a container
|
|
112
150
|
flushCurrentContainer();
|
|
113
|
-
|
|
151
|
+
|
|
152
|
+
// Handle edge case: create empty container if all content broke out
|
|
153
|
+
var finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
|
|
154
|
+
return finalResult.length > 0 ? finalResult : nodes;
|
|
114
155
|
};
|
|
@@ -43,6 +43,38 @@ const canWrapInTarget = (node, targetNodeType, targetNodeTypeName) => {
|
|
|
43
43
|
return targetNodeType.validContent(Fragment.from(node));
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Handles the edge case where transforming from a container to another container results in
|
|
48
|
+
* all content breaking out (no valid children for the target). In this case, creates an empty
|
|
49
|
+
* container to ensure the target container type is created.
|
|
50
|
+
*
|
|
51
|
+
* We can determine if there were no valid children by checking if no container was created
|
|
52
|
+
* (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
|
|
53
|
+
* means all content broke out rather than being wrapped.
|
|
54
|
+
*
|
|
55
|
+
* @param result - The current result nodes after processing
|
|
56
|
+
* @param hasCreatedContainer - Whether a container was already created during processing
|
|
57
|
+
* @param fromNode - The original source node (before unwrapping)
|
|
58
|
+
* @param targetNodeType - The target container type
|
|
59
|
+
* @param targetNodeTypeName - The target container type name
|
|
60
|
+
* @param schema - The schema
|
|
61
|
+
* @returns The result nodes with an empty container prepended if needed, or the original result
|
|
62
|
+
*/
|
|
63
|
+
const handleEmptyContainerEdgeCase = (result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) => {
|
|
64
|
+
const isFromContainer = NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
|
|
65
|
+
const isTargetContainer = NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
|
|
66
|
+
// If no container was created but we have nodes in result, all content broke out
|
|
67
|
+
// (meaning there were no valid children that could be wrapped)
|
|
68
|
+
const allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
69
|
+
const shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
70
|
+
if (shouldCreateEmptyTarget) {
|
|
71
|
+
const emptyParagraph = schema.nodes.paragraph.create();
|
|
72
|
+
const emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
73
|
+
return [emptyContainer, ...result];
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
};
|
|
77
|
+
|
|
46
78
|
/**
|
|
47
79
|
* A wrap step that handles mixed content according to the Compatibility Matrix:
|
|
48
80
|
* - Wraps consecutive compatible nodes into the target container
|
|
@@ -60,11 +92,13 @@ const canWrapInTarget = (node, targetNodeType, targetNodeTypeName) => {
|
|
|
60
92
|
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
61
93
|
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
62
94
|
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
95
|
+
* Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
|
|
63
96
|
*/
|
|
64
97
|
export const wrapMixedContentStep = (nodes, context) => {
|
|
65
98
|
const {
|
|
66
99
|
schema,
|
|
67
|
-
targetNodeTypeName
|
|
100
|
+
targetNodeTypeName,
|
|
101
|
+
fromNode
|
|
68
102
|
} = context;
|
|
69
103
|
const targetNodeType = schema.nodes[targetNodeTypeName];
|
|
70
104
|
if (!targetNodeType) {
|
|
@@ -72,11 +106,13 @@ export const wrapMixedContentStep = (nodes, context) => {
|
|
|
72
106
|
}
|
|
73
107
|
const result = [];
|
|
74
108
|
let currentContainerContent = [];
|
|
109
|
+
let hasCreatedContainer = false;
|
|
75
110
|
const flushCurrentContainer = () => {
|
|
76
111
|
if (currentContainerContent.length > 0) {
|
|
77
112
|
const containerNode = targetNodeType.createAndFill({}, Fragment.fromArray(currentContainerContent));
|
|
78
113
|
if (containerNode) {
|
|
79
114
|
result.push(containerNode);
|
|
115
|
+
hasCreatedContainer = true;
|
|
80
116
|
}
|
|
81
117
|
currentContainerContent = [];
|
|
82
118
|
}
|
|
@@ -107,5 +143,8 @@ export const wrapMixedContentStep = (nodes, context) => {
|
|
|
107
143
|
|
|
108
144
|
// Flush any remaining content into a container
|
|
109
145
|
flushCurrentContainer();
|
|
110
|
-
|
|
146
|
+
|
|
147
|
+
// Handle edge case: create empty container if all content broke out
|
|
148
|
+
const finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
|
|
149
|
+
return finalResult.length > 0 ? finalResult : nodes;
|
|
111
150
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
3
|
import { NODE_CATEGORY_BY_TYPE } from '../types';
|
|
3
4
|
|
|
@@ -43,6 +44,38 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
|
|
|
43
44
|
return targetNodeType.validContent(Fragment.from(node));
|
|
44
45
|
};
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Handles the edge case where transforming from a container to another container results in
|
|
49
|
+
* all content breaking out (no valid children for the target). In this case, creates an empty
|
|
50
|
+
* container to ensure the target container type is created.
|
|
51
|
+
*
|
|
52
|
+
* We can determine if there were no valid children by checking if no container was created
|
|
53
|
+
* (`!hasCreatedContainer`) and there are nodes in the result (`result.length > 0`), which
|
|
54
|
+
* means all content broke out rather than being wrapped.
|
|
55
|
+
*
|
|
56
|
+
* @param result - The current result nodes after processing
|
|
57
|
+
* @param hasCreatedContainer - Whether a container was already created during processing
|
|
58
|
+
* @param fromNode - The original source node (before unwrapping)
|
|
59
|
+
* @param targetNodeType - The target container type
|
|
60
|
+
* @param targetNodeTypeName - The target container type name
|
|
61
|
+
* @param schema - The schema
|
|
62
|
+
* @returns The result nodes with an empty container prepended if needed, or the original result
|
|
63
|
+
*/
|
|
64
|
+
var handleEmptyContainerEdgeCase = function handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema) {
|
|
65
|
+
var isFromContainer = NODE_CATEGORY_BY_TYPE[fromNode.type.name] === 'container';
|
|
66
|
+
var isTargetContainer = NODE_CATEGORY_BY_TYPE[targetNodeTypeName] === 'container';
|
|
67
|
+
// If no container was created but we have nodes in result, all content broke out
|
|
68
|
+
// (meaning there were no valid children that could be wrapped)
|
|
69
|
+
var allContentBrokeOut = !hasCreatedContainer && result.length > 0;
|
|
70
|
+
var shouldCreateEmptyTarget = isFromContainer && isTargetContainer && allContentBrokeOut;
|
|
71
|
+
if (shouldCreateEmptyTarget) {
|
|
72
|
+
var emptyParagraph = schema.nodes.paragraph.create();
|
|
73
|
+
var emptyContainer = targetNodeType.create({}, emptyParagraph);
|
|
74
|
+
return [emptyContainer].concat(_toConsumableArray(result));
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
78
|
+
|
|
46
79
|
/**
|
|
47
80
|
* A wrap step that handles mixed content according to the Compatibility Matrix:
|
|
48
81
|
* - Wraps consecutive compatible nodes into the target container
|
|
@@ -60,21 +93,25 @@ var canWrapInTarget = function canWrapInTarget(node, targetNodeType, targetNodeT
|
|
|
60
93
|
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
61
94
|
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
62
95
|
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
96
|
+
* Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
|
|
63
97
|
*/
|
|
64
98
|
export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context) {
|
|
65
99
|
var schema = context.schema,
|
|
66
|
-
targetNodeTypeName = context.targetNodeTypeName
|
|
100
|
+
targetNodeTypeName = context.targetNodeTypeName,
|
|
101
|
+
fromNode = context.fromNode;
|
|
67
102
|
var targetNodeType = schema.nodes[targetNodeTypeName];
|
|
68
103
|
if (!targetNodeType) {
|
|
69
104
|
return nodes;
|
|
70
105
|
}
|
|
71
106
|
var result = [];
|
|
72
107
|
var currentContainerContent = [];
|
|
108
|
+
var hasCreatedContainer = false;
|
|
73
109
|
var flushCurrentContainer = function flushCurrentContainer() {
|
|
74
110
|
if (currentContainerContent.length > 0) {
|
|
75
111
|
var containerNode = targetNodeType.createAndFill({}, Fragment.fromArray(currentContainerContent));
|
|
76
112
|
if (containerNode) {
|
|
77
113
|
result.push(containerNode);
|
|
114
|
+
hasCreatedContainer = true;
|
|
78
115
|
}
|
|
79
116
|
currentContainerContent = [];
|
|
80
117
|
}
|
|
@@ -105,5 +142,8 @@ export var wrapMixedContentStep = function wrapMixedContentStep(nodes, context)
|
|
|
105
142
|
|
|
106
143
|
// Flush any remaining content into a container
|
|
107
144
|
flushCurrentContainer();
|
|
108
|
-
|
|
145
|
+
|
|
146
|
+
// Handle edge case: create empty container if all content broke out
|
|
147
|
+
var finalResult = handleEmptyContainerEdgeCase(result, hasCreatedContainer, fromNode, targetNodeType, targetNodeTypeName, schema);
|
|
148
|
+
return finalResult.length > 0 ? finalResult : nodes;
|
|
109
149
|
};
|
|
@@ -16,5 +16,6 @@ import type { TransformStep } from '../types';
|
|
|
16
16
|
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
17
17
|
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
18
18
|
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
19
|
+
* Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
|
|
19
20
|
*/
|
|
20
21
|
export declare const wrapMixedContentStep: TransformStep;
|
package/dist/types-ts4.5/editor-commands/transform-node-utils/steps/wrapMixedContentStep.d.ts
CHANGED
|
@@ -16,5 +16,6 @@ import type { TransformStep } from '../types';
|
|
|
16
16
|
* Example: expand(p('a'), table(), p('b')) → panel: [panel(p('a')), table(), panel(p('b'))]
|
|
17
17
|
* Example: expand(p('a'), panel(p('x')), p('b')) → panel: [panel(p('a')), panel(p('x')), panel(p('b'))]
|
|
18
18
|
* Example: expand(p('a'), nestedExpand({title: 'inner'})(p('x')), p('b')) → panel: [panel(p('a')), expand({title: 'inner'})(p('x')), panel(p('b'))]
|
|
19
|
+
* Example: expand(nestedExpand()(p())) → panel: [panel(), expand()(p())] (empty panel when all content breaks out)
|
|
19
20
|
*/
|
|
20
21
|
export declare const wrapMixedContentStep: TransformStep;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-menu",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.15",
|
|
4
4
|
"description": "BlockMenu plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@atlaskit/css": "^0.
|
|
31
|
+
"@atlaskit/css": "^0.18.0",
|
|
32
32
|
"@atlaskit/dropdown-menu": "^16.3.0",
|
|
33
33
|
"@atlaskit/editor-plugin-analytics": "^6.2.0",
|
|
34
|
-
"@atlaskit/editor-plugin-block-controls": "^7.
|
|
34
|
+
"@atlaskit/editor-plugin-block-controls": "^7.15.0",
|
|
35
35
|
"@atlaskit/editor-plugin-decorations": "^6.1.0",
|
|
36
36
|
"@atlaskit/editor-plugin-selection": "^6.1.0",
|
|
37
37
|
"@atlaskit/editor-plugin-user-intent": "^4.0.0",
|
|
@@ -39,17 +39,17 @@
|
|
|
39
39
|
"@atlaskit/editor-shared-styles": "^3.10.0",
|
|
40
40
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
41
41
|
"@atlaskit/editor-toolbar": "^0.18.0",
|
|
42
|
-
"@atlaskit/flag": "^17.
|
|
43
|
-
"@atlaskit/icon": "^29.
|
|
42
|
+
"@atlaskit/flag": "^17.7.0",
|
|
43
|
+
"@atlaskit/icon": "^29.2.0",
|
|
44
44
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
45
45
|
"@atlaskit/platform-feature-flags-react": "^0.4.0",
|
|
46
46
|
"@atlaskit/primitives": "^16.4.0",
|
|
47
|
-
"@atlaskit/tmp-editor-statsig": "^15.
|
|
48
|
-
"@atlaskit/tokens": "^8.
|
|
47
|
+
"@atlaskit/tmp-editor-statsig": "^15.12.0",
|
|
48
|
+
"@atlaskit/tokens": "^8.6.0",
|
|
49
49
|
"@babel/runtime": "^7.0.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@atlaskit/editor-common": "^110.
|
|
52
|
+
"@atlaskit/editor-common": "^110.45.0",
|
|
53
53
|
"react": "^18.2.0",
|
|
54
54
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
55
55
|
},
|