@atlaskit/editor-common 112.9.0 → 112.10.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.
- package/CHANGELOG.md +26 -0
- package/dist/cjs/lists/index.js +7 -0
- package/dist/cjs/lists/narrow-replacement-range.js +82 -0
- package/dist/cjs/media-inline/inline-image-wrapper.js +15 -2
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/preset/builder.js +23 -6
- package/dist/cjs/transforms/list-transforms.js +122 -16
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/es2019/lists/index.js +1 -0
- package/dist/es2019/lists/narrow-replacement-range.js +74 -0
- package/dist/es2019/media-inline/inline-image-wrapper.js +15 -2
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/preset/builder.js +23 -6
- package/dist/es2019/transforms/list-transforms.js +107 -12
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/esm/lists/index.js +1 -0
- package/dist/esm/lists/narrow-replacement-range.js +76 -0
- package/dist/esm/media-inline/inline-image-wrapper.js +15 -2
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/preset/builder.js +23 -6
- package/dist/esm/transforms/list-transforms.js +122 -16
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/types/lists/index.d.ts +2 -0
- package/dist/types/lists/narrow-replacement-range.d.ts +19 -0
- package/dist/types/media-inline/inline-image-wrapper.d.ts +1 -1
- package/dist/types-ts4.5/lists/index.d.ts +2 -0
- package/dist/types-ts4.5/lists/narrow-replacement-range.d.ts +19 -0
- package/dist/types-ts4.5/media-inline/inline-image-wrapper.d.ts +1 -1
- package/package.json +4 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import { findChildrenByType, findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
4
|
import { getSupportedListTypesSet, isBulletOrOrderedList, isTaskList, convertBlockToInlineContent } from './list-utils';
|
|
4
5
|
const getContentSupportChecker = targetNodeType => {
|
|
5
6
|
return node => {
|
|
@@ -10,6 +11,15 @@ const getContentSupportChecker = targetNodeType => {
|
|
|
10
11
|
}
|
|
11
12
|
};
|
|
12
13
|
};
|
|
14
|
+
const createBlockTaskItemWithMarks = (content, marks, schema) => {
|
|
15
|
+
const {
|
|
16
|
+
blockTaskItem,
|
|
17
|
+
paragraph
|
|
18
|
+
} = schema.nodes;
|
|
19
|
+
const allowedMarks = marks.filter(mark => blockTaskItem.allowsMarkType(mark.type));
|
|
20
|
+
const newParagraph = paragraph.create(null, content.length > 0 ? content : null, allowedMarks);
|
|
21
|
+
return blockTaskItem.create(null, newParagraph);
|
|
22
|
+
};
|
|
13
23
|
export const transformListRecursively = (props, onhandleUnsupportedContent) => {
|
|
14
24
|
const transformedItems = [];
|
|
15
25
|
const {
|
|
@@ -26,14 +36,33 @@ export const transformListRecursively = (props, onhandleUnsupportedContent) => {
|
|
|
26
36
|
taskList,
|
|
27
37
|
listItem,
|
|
28
38
|
taskItem,
|
|
29
|
-
paragraph
|
|
39
|
+
paragraph,
|
|
40
|
+
blockTaskItem
|
|
30
41
|
} = schema.nodes;
|
|
42
|
+
|
|
43
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
44
|
+
// but keep this solution general
|
|
45
|
+
const isBlockTaskEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Extracts paragraph children from a blockTaskItem, preserving their marks.
|
|
49
|
+
*/
|
|
50
|
+
const extractParagraphsFromBlockTaskItem = node => {
|
|
51
|
+
const paragraphs = [];
|
|
52
|
+
node.forEach(child => {
|
|
53
|
+
if (child.type === paragraph) {
|
|
54
|
+
paragraphs.push(child);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return paragraphs;
|
|
58
|
+
};
|
|
31
59
|
listNode.forEach(child => {
|
|
32
60
|
if (isSourceBulletOrOrdered && isTargetTask) {
|
|
33
61
|
// Convert bullet/ordered => task
|
|
34
62
|
if (child.type === listItem) {
|
|
35
63
|
const inlineContent = [];
|
|
36
64
|
const nestedTaskLists = [];
|
|
65
|
+
let blockMarks = [];
|
|
37
66
|
child.forEach(grandChild => {
|
|
38
67
|
if (supportedListTypes.has(grandChild.type) && grandChild.type !== taskList) {
|
|
39
68
|
nestedTaskLists.push(transformListRecursively({
|
|
@@ -43,18 +72,37 @@ export const transformListRecursively = (props, onhandleUnsupportedContent) => {
|
|
|
43
72
|
} else if (!getContentSupportChecker(taskItem)(grandChild) && !grandChild.isTextblock) {
|
|
44
73
|
onhandleUnsupportedContent === null || onhandleUnsupportedContent === void 0 ? void 0 : onhandleUnsupportedContent(grandChild);
|
|
45
74
|
} else {
|
|
75
|
+
if (isBlockTaskEnabled && grandChild.type === paragraph && grandChild.marks.length > 0) {
|
|
76
|
+
blockMarks = grandChild.marks;
|
|
77
|
+
}
|
|
46
78
|
inlineContent.push(...convertBlockToInlineContent(grandChild, schema));
|
|
47
79
|
}
|
|
48
80
|
});
|
|
49
|
-
|
|
81
|
+
if (isBlockTaskEnabled && blockMarks.length > 0) {
|
|
82
|
+
transformedItems.push(createBlockTaskItemWithMarks(inlineContent, blockMarks, schema));
|
|
83
|
+
} else {
|
|
84
|
+
transformedItems.push(taskItem.create(null, inlineContent.length > 0 ? inlineContent : null));
|
|
85
|
+
}
|
|
50
86
|
transformedItems.push(...nestedTaskLists);
|
|
51
87
|
}
|
|
52
88
|
} else if (isSourceTask && isTargetBulletOrOrdered) {
|
|
53
89
|
// Convert task => bullet/ordered
|
|
54
90
|
if (child.type === taskItem) {
|
|
55
91
|
const inlineContent = [...child.content.content];
|
|
56
|
-
|
|
92
|
+
|
|
93
|
+
// Transfer taskItem's block marks to the paragraph.
|
|
94
|
+
// Use listItem.allowsMarkType since the paragraph will be inside a listItem
|
|
95
|
+
// (which uses ParagraphWithFontSizeStage0 that allows fontSize).
|
|
96
|
+
const paragraphMarks = isBlockTaskEnabled && child.marks.length > 0 ? child.marks.filter(mark => listItem.allowsMarkType(mark.type)) : undefined;
|
|
97
|
+
const paragraphNode = paragraph.create(null, inlineContent.length > 0 ? inlineContent : null, paragraphMarks);
|
|
57
98
|
transformedItems.push(listItem.create(null, [paragraphNode]));
|
|
99
|
+
} else if (isBlockTaskEnabled && child.type === blockTaskItem) {
|
|
100
|
+
// blockTaskItem wraps content in paragraphs — extract them directly,
|
|
101
|
+
// preserving their fontSize marks
|
|
102
|
+
const paragraphs = extractParagraphsFromBlockTaskItem(child);
|
|
103
|
+
if (paragraphs.length > 0) {
|
|
104
|
+
transformedItems.push(listItem.create(null, paragraphs));
|
|
105
|
+
}
|
|
58
106
|
} else if (child.type === taskList) {
|
|
59
107
|
const transformedNestedList = transformListRecursively({
|
|
60
108
|
...props,
|
|
@@ -199,22 +247,28 @@ export const transformBetweenListTypes = context => {
|
|
|
199
247
|
export const transformToTaskList = (tr, range, targetNodeType, targetAttrs, nodes) => {
|
|
200
248
|
try {
|
|
201
249
|
const {
|
|
202
|
-
taskItem
|
|
250
|
+
taskItem,
|
|
251
|
+
paragraph,
|
|
252
|
+
blockTaskItem
|
|
203
253
|
} = nodes;
|
|
254
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
255
|
+
// but keep this solution general
|
|
256
|
+
const isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
204
257
|
const listItems = [];
|
|
205
258
|
|
|
206
259
|
// Process each block in the range
|
|
207
260
|
tr.doc.nodesBetween(range.start, range.end, node => {
|
|
208
261
|
if (node.isBlock) {
|
|
209
|
-
// For block nodes like paragraphs, directly use their inline content
|
|
210
262
|
const inlineContent = [...node.content.content];
|
|
211
263
|
if (inlineContent.length > 0) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
264
|
+
if (isBlockTaskItemEnabled && node.type === paragraph && node.marks.length > 0) {
|
|
265
|
+
listItems.push(createBlockTaskItemWithMarks(inlineContent, node.marks, tr.doc.type.schema));
|
|
266
|
+
} else {
|
|
267
|
+
listItems.push(taskItem.create(targetAttrs, inlineContent));
|
|
268
|
+
}
|
|
215
269
|
}
|
|
216
270
|
}
|
|
217
|
-
return false;
|
|
271
|
+
return false;
|
|
218
272
|
});
|
|
219
273
|
if (listItems.length === 0) {
|
|
220
274
|
return null;
|
|
@@ -242,6 +296,39 @@ export const transformTaskListToBlockNodes = context => {
|
|
|
242
296
|
selection
|
|
243
297
|
} = tr;
|
|
244
298
|
const schema = selection.$from.doc.type.schema;
|
|
299
|
+
const {
|
|
300
|
+
blockTaskItem
|
|
301
|
+
} = schema.nodes;
|
|
302
|
+
|
|
303
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
304
|
+
// but keep this solution general
|
|
305
|
+
const isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
306
|
+
if (isBlockTaskItemEnabled) {
|
|
307
|
+
const blockTaskItemsResult = findChildrenByType(sourceNode, blockTaskItem);
|
|
308
|
+
if (blockTaskItemsResult.length > 0 && targetNodeType === schema.nodes.paragraph) {
|
|
309
|
+
// blockTaskItem content is (paragraph | extension)+
|
|
310
|
+
// Extract paragraph children directly — they may carry block marks (e.g. fontSize)
|
|
311
|
+
const targetNodes = [];
|
|
312
|
+
for (const {
|
|
313
|
+
node: blockItem
|
|
314
|
+
} of blockTaskItemsResult) {
|
|
315
|
+
blockItem.forEach(child => {
|
|
316
|
+
if (child.type === schema.nodes.paragraph) {
|
|
317
|
+
targetNodes.push(child);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
if (targetNodes.length === 0) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const slice = new Slice(Fragment.fromArray(targetNodes), 0, 0);
|
|
325
|
+
const rangeStart = sourcePos !== null ? sourcePos : selection.from;
|
|
326
|
+
tr.replaceRange(rangeStart, rangeStart + sourceNode.nodeSize, slice);
|
|
327
|
+
return tr;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Original logic for regular taskItem children
|
|
245
332
|
const taskItemsResult = findChildrenByType(sourceNode, schema.nodes.taskItem);
|
|
246
333
|
const taskItems = taskItemsResult.map(item => item.node);
|
|
247
334
|
const taskItemFragments = taskItems.map(taskItem => taskItem.content);
|
|
@@ -283,6 +370,10 @@ export const getFormattedNode = tr => {
|
|
|
283
370
|
nodes
|
|
284
371
|
} = tr.doc.type.schema;
|
|
285
372
|
|
|
373
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
374
|
+
// but keep this solution general
|
|
375
|
+
const isBlockTaskItemEnabled = !!nodes.blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
376
|
+
|
|
286
377
|
// Find the node to format from the current selection
|
|
287
378
|
let nodeToFormat;
|
|
288
379
|
let nodePos = selection.from;
|
|
@@ -294,13 +385,17 @@ export const getFormattedNode = tr => {
|
|
|
294
385
|
nodePos = selectedNode.pos;
|
|
295
386
|
} else {
|
|
296
387
|
// Try to find parent node (including list parents)
|
|
297
|
-
const
|
|
388
|
+
const parentNodeTypes = [nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.taskItem, nodes.layoutSection];
|
|
389
|
+
if (isBlockTaskItemEnabled) {
|
|
390
|
+
parentNodeTypes.push(nodes.blockTaskItem);
|
|
391
|
+
}
|
|
392
|
+
const parentNode = findParentNodeOfType(parentNodeTypes)(selection);
|
|
298
393
|
if (parentNode) {
|
|
299
394
|
nodeToFormat = parentNode.node;
|
|
300
395
|
nodePos = parentNode.pos;
|
|
301
396
|
const paragraphOrHeadingNode = findParentNodeOfType([nodes.paragraph, nodes.heading])(selection);
|
|
302
|
-
// Special case: if we found a listItem, check if we need the parent list instead
|
|
303
|
-
if (parentNode.node.type === nodes.listItem || parentNode.node.type === nodes.taskItem) {
|
|
397
|
+
// Special case: if we found a listItem/taskItem/blockTaskItem, check if we need the parent list instead
|
|
398
|
+
if (parentNode.node.type === nodes.listItem || parentNode.node.type === nodes.taskItem || isBlockTaskItemEnabled && parentNode.node.type === nodes.blockTaskItem) {
|
|
304
399
|
const listParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
|
|
305
400
|
if (listParent) {
|
|
306
401
|
// For list transformations, we want the list parent, not the listItem
|
|
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
14
14
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
15
|
import Layer from '../Layer';
|
|
16
16
|
const packageName = "@atlaskit/editor-common";
|
|
17
|
-
const packageVersion = "112.
|
|
17
|
+
const packageVersion = "112.9.1";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
package/dist/esm/lists/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { getCommonListAnalyticsAttributes, countListItemsInSelection } from './a
|
|
|
8
8
|
export { hasValidListIndentationLevel } from './indentation';
|
|
9
9
|
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
10
10
|
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
11
|
+
export { narrowReplacementRange } from './narrow-replacement-range';
|
|
11
12
|
export { flattenList } from './flatten-list';
|
|
12
13
|
export { isListNode, isListItemNode, isBulletList, isParagraphNode } from '../utils';
|
|
13
14
|
export { messages } from './messages';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
/**
|
|
3
|
+
* Narrows a full-list replacement to the minimal changed range.
|
|
4
|
+
*
|
|
5
|
+
* Compares the old root list node with the new replacement fragment
|
|
6
|
+
* from both ends to find the first and last positions where they differ,
|
|
7
|
+
* then returns only the changed subrange.
|
|
8
|
+
*
|
|
9
|
+
* This reduces the scope of `tr.replaceWith()` so that remote cursors
|
|
10
|
+
* on unchanged items are preserved during collaborative editing.
|
|
11
|
+
*/
|
|
12
|
+
export function narrowReplacementRange(doc, rootListStart, rootListEnd, fragment, contentStartOffsets) {
|
|
13
|
+
var oldNode = doc.nodeAt(rootListStart);
|
|
14
|
+
var newNode = fragment.childCount === 1 ? fragment.firstChild : null;
|
|
15
|
+
if (!oldNode || !newNode || newNode.type !== oldNode.type) {
|
|
16
|
+
return {
|
|
17
|
+
start: rootListStart,
|
|
18
|
+
end: rootListEnd,
|
|
19
|
+
fragment: fragment,
|
|
20
|
+
adjustedContentStartOffsets: contentStartOffsets
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var minChildCount = Math.min(oldNode.childCount, newNode.childCount);
|
|
24
|
+
var commonPrefixChildren = 0;
|
|
25
|
+
var prefixSize = 0;
|
|
26
|
+
for (var i = 0; i < minChildCount; i++) {
|
|
27
|
+
var oldChild = oldNode.child(i);
|
|
28
|
+
var newChild = newNode.child(i);
|
|
29
|
+
if (oldChild.eq(newChild)) {
|
|
30
|
+
commonPrefixChildren++;
|
|
31
|
+
prefixSize += oldChild.nodeSize;
|
|
32
|
+
} else {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
var commonSuffixChildren = 0;
|
|
37
|
+
var suffixSize = 0;
|
|
38
|
+
for (var _i = 0; _i < minChildCount - commonPrefixChildren; _i++) {
|
|
39
|
+
var _oldChild = oldNode.child(oldNode.childCount - 1 - _i);
|
|
40
|
+
var _newChild = newNode.child(newNode.childCount - 1 - _i);
|
|
41
|
+
if (_oldChild.eq(_newChild)) {
|
|
42
|
+
commonSuffixChildren++;
|
|
43
|
+
suffixSize += _oldChild.nodeSize;
|
|
44
|
+
} else {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
var totalCommon = commonPrefixChildren + commonSuffixChildren;
|
|
49
|
+
if (totalCommon >= oldNode.childCount && totalCommon >= newNode.childCount) {
|
|
50
|
+
return {
|
|
51
|
+
start: rootListStart,
|
|
52
|
+
end: rootListStart,
|
|
53
|
+
fragment: Fragment.empty,
|
|
54
|
+
adjustedContentStartOffsets: contentStartOffsets
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
var narrowedStart = rootListStart + 1 + prefixSize;
|
|
58
|
+
var narrowedEnd = rootListEnd - 1 - suffixSize;
|
|
59
|
+
var changedChildStart = commonPrefixChildren;
|
|
60
|
+
var changedChildEnd = newNode.childCount - commonSuffixChildren;
|
|
61
|
+
var changedNodes = [];
|
|
62
|
+
for (var _i2 = changedChildStart; _i2 < changedChildEnd; _i2++) {
|
|
63
|
+
changedNodes.push(newNode.child(_i2));
|
|
64
|
+
}
|
|
65
|
+
var narrowedFragment = Fragment.from(changedNodes);
|
|
66
|
+
var prefixOffset = 1 + prefixSize;
|
|
67
|
+
var adjustedContentStartOffsets = contentStartOffsets.map(function (offset) {
|
|
68
|
+
return offset - prefixOffset;
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
start: narrowedStart,
|
|
72
|
+
end: narrowedEnd,
|
|
73
|
+
fragment: narrowedFragment,
|
|
74
|
+
adjustedContentStartOffsets: adjustedContentStartOffsets
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -10,6 +10,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
10
10
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic
|
|
11
11
|
import { css, jsx } from '@emotion/react';
|
|
12
12
|
import { hexToEditorBorderPaletteColor } from '@atlaskit/editor-palette';
|
|
13
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
14
|
import { borderStyle, INLINE_IMAGE_ASPECT_RATIO_CSS_VAR_KEY, INLINE_IMAGE_BORDER_COLOR_CSS_VAR_KEY, INLINE_IMAGE_BORDER_SIZE_CSS_VAR_KEY, INLINE_IMAGE_WRAPPER_CLASS_NAME, selectedStyle, wrapperStyle } from './styles';
|
|
14
15
|
|
|
15
16
|
// The MediaImage component needs to obtain its parent's dimensions.
|
|
@@ -32,8 +33,17 @@ export var InlineImageWrapper = function InlineImageWrapper(_ref) {
|
|
|
32
33
|
onClick = _ref.onClick;
|
|
33
34
|
var borderStyleVars = borderSize && borderColor ? _defineProperty(_defineProperty({}, INLINE_IMAGE_BORDER_SIZE_CSS_VAR_KEY, borderSize), INLINE_IMAGE_BORDER_COLOR_CSS_VAR_KEY, hexToEditorBorderPaletteColor(borderColor) || borderColor) : {};
|
|
34
35
|
var aspectStyleVars = aspectRatio ? _defineProperty({}, INLINE_IMAGE_ASPECT_RATIO_CSS_VAR_KEY, aspectRatio) : {};
|
|
36
|
+
var onKeyDown = function onKeyDown(e) {
|
|
37
|
+
if (expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true)) {
|
|
38
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
onClick(e);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
35
45
|
return (
|
|
36
|
-
// eslint-disable-next-line @atlaskit/design-system/prefer-primitives
|
|
46
|
+
// eslint-disable-next-line @atlaskit/design-system/prefer-primitives
|
|
37
47
|
jsx("span", _extends({
|
|
38
48
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
39
49
|
style: _objectSpread(_objectSpread({}, borderStyleVars), aspectStyleVars)
|
|
@@ -48,7 +58,10 @@ export var InlineImageWrapper = function InlineImageWrapper(_ref) {
|
|
|
48
58
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
|
|
49
59
|
isSelected && selectedStyle],
|
|
50
60
|
"data-testid": "inline-image-wrapper",
|
|
51
|
-
|
|
61
|
+
role: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? 'button' : undefined,
|
|
62
|
+
tabIndex: expValEquals('editor_a11y__enghealth-46814_fy26', 'isEnabled', true) ? 0 : undefined,
|
|
63
|
+
onClick: onClick,
|
|
64
|
+
onKeyDown: onKeyDown
|
|
52
65
|
// Ignored via go/ees005
|
|
53
66
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
54
67
|
}, htmlAttrs), jsx("span", {
|
|
@@ -10,7 +10,7 @@ import { isFedRamp } from './environment';
|
|
|
10
10
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
11
11
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
12
12
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
13
|
-
var packageVersion = "112.
|
|
13
|
+
var packageVersion = "112.9.1";
|
|
14
14
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
15
15
|
// Remove URL as it has UGC
|
|
16
16
|
// Ignored via go/ees007
|
|
@@ -4,6 +4,7 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
|
4
4
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
5
5
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
6
6
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
7
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
8
|
import { EventDispatcher } from '../event-dispatcher';
|
|
8
9
|
|
|
9
10
|
/*********************
|
|
@@ -666,12 +667,28 @@ export var EditorPresetBuilder = /*#__PURE__*/function () {
|
|
|
666
667
|
if (typeof fn !== 'function') {
|
|
667
668
|
return null;
|
|
668
669
|
}
|
|
669
|
-
var plugin
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
670
|
+
var plugin;
|
|
671
|
+
if (expValEquals('platform_editor_improve_preset_builder_logging', 'isEnabled', true)) {
|
|
672
|
+
try {
|
|
673
|
+
plugin = pluginInjectionAPI ? fn({
|
|
674
|
+
config: config,
|
|
675
|
+
api: pluginInjectionAPI.api()
|
|
676
|
+
}) : fn({
|
|
677
|
+
config: config
|
|
678
|
+
});
|
|
679
|
+
} catch (error) {
|
|
680
|
+
var pluginName = fn.name || 'unknown';
|
|
681
|
+
var enhancedError = error instanceof Error ? new Error("Failed to initialize plugin '".concat(pluginName, "': ").concat(error.message)) : new Error("Failed to initialize plugin '".concat(pluginName, "'"));
|
|
682
|
+
throw enhancedError;
|
|
683
|
+
}
|
|
684
|
+
} else {
|
|
685
|
+
plugin = pluginInjectionAPI ? fn({
|
|
686
|
+
config: config,
|
|
687
|
+
api: pluginInjectionAPI.api()
|
|
688
|
+
}) : fn({
|
|
689
|
+
config: config
|
|
690
|
+
});
|
|
691
|
+
}
|
|
675
692
|
if (plugin && excludePlugins !== null && excludePlugins !== void 0 && excludePlugins.has(plugin.name)) {
|
|
676
693
|
return null;
|
|
677
694
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
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; } } }; }
|
|
4
|
+
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; } }
|
|
5
|
+
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; }
|
|
3
6
|
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; }
|
|
4
7
|
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) { _defineProperty(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; }
|
|
5
8
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
6
9
|
import { findChildrenByType, findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
10
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
11
|
import { getSupportedListTypesSet, isBulletOrOrderedList, isTaskList, convertBlockToInlineContent } from './list-utils';
|
|
8
12
|
var getContentSupportChecker = function getContentSupportChecker(targetNodeType) {
|
|
9
13
|
return function (node) {
|
|
@@ -14,6 +18,16 @@ var getContentSupportChecker = function getContentSupportChecker(targetNodeType)
|
|
|
14
18
|
}
|
|
15
19
|
};
|
|
16
20
|
};
|
|
21
|
+
var createBlockTaskItemWithMarks = function createBlockTaskItemWithMarks(content, marks, schema) {
|
|
22
|
+
var _schema$nodes = schema.nodes,
|
|
23
|
+
blockTaskItem = _schema$nodes.blockTaskItem,
|
|
24
|
+
paragraph = _schema$nodes.paragraph;
|
|
25
|
+
var allowedMarks = marks.filter(function (mark) {
|
|
26
|
+
return blockTaskItem.allowsMarkType(mark.type);
|
|
27
|
+
});
|
|
28
|
+
var newParagraph = paragraph.create(null, content.length > 0 ? content : null, allowedMarks);
|
|
29
|
+
return blockTaskItem.create(null, newParagraph);
|
|
30
|
+
};
|
|
17
31
|
var _transformListRecursively = function transformListRecursively(props, onhandleUnsupportedContent) {
|
|
18
32
|
var transformedItems = [];
|
|
19
33
|
var listNode = props.listNode,
|
|
@@ -24,17 +38,36 @@ var _transformListRecursively = function transformListRecursively(props, onhandl
|
|
|
24
38
|
supportedListTypes = props.supportedListTypes,
|
|
25
39
|
schema = props.schema,
|
|
26
40
|
targetNodeType = props.targetNodeType;
|
|
27
|
-
var _schema$
|
|
28
|
-
taskList = _schema$
|
|
29
|
-
listItem = _schema$
|
|
30
|
-
taskItem = _schema$
|
|
31
|
-
paragraph = _schema$
|
|
41
|
+
var _schema$nodes2 = schema.nodes,
|
|
42
|
+
taskList = _schema$nodes2.taskList,
|
|
43
|
+
listItem = _schema$nodes2.listItem,
|
|
44
|
+
taskItem = _schema$nodes2.taskItem,
|
|
45
|
+
paragraph = _schema$nodes2.paragraph,
|
|
46
|
+
blockTaskItem = _schema$nodes2.blockTaskItem;
|
|
47
|
+
|
|
48
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
49
|
+
// but keep this solution general
|
|
50
|
+
var isBlockTaskEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extracts paragraph children from a blockTaskItem, preserving their marks.
|
|
54
|
+
*/
|
|
55
|
+
var extractParagraphsFromBlockTaskItem = function extractParagraphsFromBlockTaskItem(node) {
|
|
56
|
+
var paragraphs = [];
|
|
57
|
+
node.forEach(function (child) {
|
|
58
|
+
if (child.type === paragraph) {
|
|
59
|
+
paragraphs.push(child);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return paragraphs;
|
|
63
|
+
};
|
|
32
64
|
listNode.forEach(function (child) {
|
|
33
65
|
if (isSourceBulletOrOrdered && isTargetTask) {
|
|
34
66
|
// Convert bullet/ordered => task
|
|
35
67
|
if (child.type === listItem) {
|
|
36
68
|
var inlineContent = [];
|
|
37
69
|
var nestedTaskLists = [];
|
|
70
|
+
var blockMarks = [];
|
|
38
71
|
child.forEach(function (grandChild) {
|
|
39
72
|
if (supportedListTypes.has(grandChild.type) && grandChild.type !== taskList) {
|
|
40
73
|
nestedTaskLists.push(_transformListRecursively(_objectSpread(_objectSpread({}, props), {}, {
|
|
@@ -43,18 +76,39 @@ var _transformListRecursively = function transformListRecursively(props, onhandl
|
|
|
43
76
|
} else if (!getContentSupportChecker(taskItem)(grandChild) && !grandChild.isTextblock) {
|
|
44
77
|
onhandleUnsupportedContent === null || onhandleUnsupportedContent === void 0 || onhandleUnsupportedContent(grandChild);
|
|
45
78
|
} else {
|
|
79
|
+
if (isBlockTaskEnabled && grandChild.type === paragraph && grandChild.marks.length > 0) {
|
|
80
|
+
blockMarks = grandChild.marks;
|
|
81
|
+
}
|
|
46
82
|
inlineContent.push.apply(inlineContent, _toConsumableArray(convertBlockToInlineContent(grandChild, schema)));
|
|
47
83
|
}
|
|
48
84
|
});
|
|
49
|
-
|
|
85
|
+
if (isBlockTaskEnabled && blockMarks.length > 0) {
|
|
86
|
+
transformedItems.push(createBlockTaskItemWithMarks(inlineContent, blockMarks, schema));
|
|
87
|
+
} else {
|
|
88
|
+
transformedItems.push(taskItem.create(null, inlineContent.length > 0 ? inlineContent : null));
|
|
89
|
+
}
|
|
50
90
|
transformedItems.push.apply(transformedItems, nestedTaskLists);
|
|
51
91
|
}
|
|
52
92
|
} else if (isSourceTask && isTargetBulletOrOrdered) {
|
|
53
93
|
// Convert task => bullet/ordered
|
|
54
94
|
if (child.type === taskItem) {
|
|
55
95
|
var _inlineContent = _toConsumableArray(child.content.content);
|
|
56
|
-
|
|
96
|
+
|
|
97
|
+
// Transfer taskItem's block marks to the paragraph.
|
|
98
|
+
// Use listItem.allowsMarkType since the paragraph will be inside a listItem
|
|
99
|
+
// (which uses ParagraphWithFontSizeStage0 that allows fontSize).
|
|
100
|
+
var paragraphMarks = isBlockTaskEnabled && child.marks.length > 0 ? child.marks.filter(function (mark) {
|
|
101
|
+
return listItem.allowsMarkType(mark.type);
|
|
102
|
+
}) : undefined;
|
|
103
|
+
var paragraphNode = paragraph.create(null, _inlineContent.length > 0 ? _inlineContent : null, paragraphMarks);
|
|
57
104
|
transformedItems.push(listItem.create(null, [paragraphNode]));
|
|
105
|
+
} else if (isBlockTaskEnabled && child.type === blockTaskItem) {
|
|
106
|
+
// blockTaskItem wraps content in paragraphs — extract them directly,
|
|
107
|
+
// preserving their fontSize marks
|
|
108
|
+
var paragraphs = extractParagraphsFromBlockTaskItem(child);
|
|
109
|
+
if (paragraphs.length > 0) {
|
|
110
|
+
transformedItems.push(listItem.create(null, paragraphs));
|
|
111
|
+
}
|
|
58
112
|
} else if (child.type === taskList) {
|
|
59
113
|
var transformedNestedList = _transformListRecursively(_objectSpread(_objectSpread({}, props), {}, {
|
|
60
114
|
listNode: child
|
|
@@ -189,21 +243,27 @@ export var transformBetweenListTypes = function transformBetweenListTypes(contex
|
|
|
189
243
|
*/
|
|
190
244
|
export var transformToTaskList = function transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes) {
|
|
191
245
|
try {
|
|
192
|
-
var taskItem = nodes.taskItem
|
|
246
|
+
var taskItem = nodes.taskItem,
|
|
247
|
+
paragraph = nodes.paragraph,
|
|
248
|
+
blockTaskItem = nodes.blockTaskItem;
|
|
249
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
250
|
+
// but keep this solution general
|
|
251
|
+
var isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
193
252
|
var listItems = [];
|
|
194
253
|
|
|
195
254
|
// Process each block in the range
|
|
196
255
|
tr.doc.nodesBetween(range.start, range.end, function (node) {
|
|
197
256
|
if (node.isBlock) {
|
|
198
|
-
// For block nodes like paragraphs, directly use their inline content
|
|
199
257
|
var inlineContent = _toConsumableArray(node.content.content);
|
|
200
258
|
if (inlineContent.length > 0) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
259
|
+
if (isBlockTaskItemEnabled && node.type === paragraph && node.marks.length > 0) {
|
|
260
|
+
listItems.push(createBlockTaskItemWithMarks(inlineContent, node.marks, tr.doc.type.schema));
|
|
261
|
+
} else {
|
|
262
|
+
listItems.push(taskItem.create(targetAttrs, inlineContent));
|
|
263
|
+
}
|
|
204
264
|
}
|
|
205
265
|
}
|
|
206
|
-
return false;
|
|
266
|
+
return false;
|
|
207
267
|
});
|
|
208
268
|
if (listItems.length === 0) {
|
|
209
269
|
return null;
|
|
@@ -227,6 +287,44 @@ export var transformTaskListToBlockNodes = function transformTaskListToBlockNode
|
|
|
227
287
|
sourcePos = context.sourcePos;
|
|
228
288
|
var selection = tr.selection;
|
|
229
289
|
var schema = selection.$from.doc.type.schema;
|
|
290
|
+
var blockTaskItem = schema.nodes.blockTaskItem;
|
|
291
|
+
|
|
292
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
293
|
+
// but keep this solution general
|
|
294
|
+
var isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
295
|
+
if (isBlockTaskItemEnabled) {
|
|
296
|
+
var blockTaskItemsResult = findChildrenByType(sourceNode, blockTaskItem);
|
|
297
|
+
if (blockTaskItemsResult.length > 0 && targetNodeType === schema.nodes.paragraph) {
|
|
298
|
+
// blockTaskItem content is (paragraph | extension)+
|
|
299
|
+
// Extract paragraph children directly — they may carry block marks (e.g. fontSize)
|
|
300
|
+
var _targetNodes = [];
|
|
301
|
+
var _iterator = _createForOfIteratorHelper(blockTaskItemsResult),
|
|
302
|
+
_step;
|
|
303
|
+
try {
|
|
304
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
305
|
+
var blockItem = _step.value.node;
|
|
306
|
+
blockItem.forEach(function (child) {
|
|
307
|
+
if (child.type === schema.nodes.paragraph) {
|
|
308
|
+
_targetNodes.push(child);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
} catch (err) {
|
|
313
|
+
_iterator.e(err);
|
|
314
|
+
} finally {
|
|
315
|
+
_iterator.f();
|
|
316
|
+
}
|
|
317
|
+
if (_targetNodes.length === 0) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
var _slice = new Slice(Fragment.fromArray(_targetNodes), 0, 0);
|
|
321
|
+
var _rangeStart = sourcePos !== null ? sourcePos : selection.from;
|
|
322
|
+
tr.replaceRange(_rangeStart, _rangeStart + sourceNode.nodeSize, _slice);
|
|
323
|
+
return tr;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Original logic for regular taskItem children
|
|
230
328
|
var taskItemsResult = findChildrenByType(sourceNode, schema.nodes.taskItem);
|
|
231
329
|
var taskItems = taskItemsResult.map(function (item) {
|
|
232
330
|
return item.node;
|
|
@@ -274,6 +372,10 @@ export var getFormattedNode = function getFormattedNode(tr) {
|
|
|
274
372
|
var selection = tr.selection;
|
|
275
373
|
var nodes = tr.doc.type.schema.nodes;
|
|
276
374
|
|
|
375
|
+
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
376
|
+
// but keep this solution general
|
|
377
|
+
var isBlockTaskItemEnabled = !!nodes.blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
378
|
+
|
|
277
379
|
// Find the node to format from the current selection
|
|
278
380
|
var nodeToFormat;
|
|
279
381
|
var nodePos = selection.from;
|
|
@@ -285,13 +387,17 @@ export var getFormattedNode = function getFormattedNode(tr) {
|
|
|
285
387
|
nodePos = selectedNode.pos;
|
|
286
388
|
} else {
|
|
287
389
|
// Try to find parent node (including list parents)
|
|
288
|
-
var
|
|
390
|
+
var parentNodeTypes = [nodes.blockquote, nodes.panel, nodes.expand, nodes.codeBlock, nodes.listItem, nodes.taskItem, nodes.layoutSection];
|
|
391
|
+
if (isBlockTaskItemEnabled) {
|
|
392
|
+
parentNodeTypes.push(nodes.blockTaskItem);
|
|
393
|
+
}
|
|
394
|
+
var parentNode = findParentNodeOfType(parentNodeTypes)(selection);
|
|
289
395
|
if (parentNode) {
|
|
290
396
|
nodeToFormat = parentNode.node;
|
|
291
397
|
nodePos = parentNode.pos;
|
|
292
398
|
var paragraphOrHeadingNode = findParentNodeOfType([nodes.paragraph, nodes.heading])(selection);
|
|
293
|
-
// Special case: if we found a listItem, check if we need the parent list instead
|
|
294
|
-
if (parentNode.node.type === nodes.listItem || parentNode.node.type === nodes.taskItem) {
|
|
399
|
+
// Special case: if we found a listItem/taskItem/blockTaskItem, check if we need the parent list instead
|
|
400
|
+
if (parentNode.node.type === nodes.listItem || parentNode.node.type === nodes.taskItem || isBlockTaskItemEnabled && parentNode.node.type === nodes.blockTaskItem) {
|
|
295
401
|
var listParent = findParentNodeOfType([nodes.bulletList, nodes.orderedList, nodes.taskList])(selection);
|
|
296
402
|
if (listParent) {
|
|
297
403
|
// For list transformations, we want the list parent, not the listItem
|
|
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
21
21
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
22
22
|
import Layer from '../Layer';
|
|
23
23
|
var packageName = "@atlaskit/editor-common";
|
|
24
|
-
var packageVersion = "112.
|
|
24
|
+
var packageVersion = "112.9.1";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -6,6 +6,8 @@ export { hasValidListIndentationLevel } from './indentation';
|
|
|
6
6
|
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
7
7
|
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
8
8
|
export type { BuildResult } from './build-replacement-fragment';
|
|
9
|
+
export { narrowReplacementRange } from './narrow-replacement-range';
|
|
10
|
+
export type { NarrowedReplacement } from './narrow-replacement-range';
|
|
9
11
|
export type { FlattenedItem } from './flatten-list';
|
|
10
12
|
export { flattenList } from './flatten-list';
|
|
11
13
|
export type { FlattenListOptions, FlattenListResult } from './flatten-list';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
export type NarrowedReplacement = {
|
|
4
|
+
adjustedContentStartOffsets: number[];
|
|
5
|
+
end: number;
|
|
6
|
+
fragment: Fragment;
|
|
7
|
+
start: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Narrows a full-list replacement to the minimal changed range.
|
|
11
|
+
*
|
|
12
|
+
* Compares the old root list node with the new replacement fragment
|
|
13
|
+
* from both ends to find the first and last positions where they differ,
|
|
14
|
+
* then returns only the changed subrange.
|
|
15
|
+
*
|
|
16
|
+
* This reduces the scope of `tr.replaceWith()` so that remote cursors
|
|
17
|
+
* on unchanged items are preserved during collaborative editing.
|
|
18
|
+
*/
|
|
19
|
+
export declare function narrowReplacementRange(doc: PMNode, rootListStart: number, rootListEnd: number, fragment: Fragment, contentStartOffsets: number[]): NarrowedReplacement;
|