@atlaskit/editor-common 74.29.3 → 74.31.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 +12 -0
- package/dist/cjs/i18n/cs.js +19 -0
- package/dist/cjs/i18n/da.js +19 -0
- package/dist/cjs/i18n/de.js +19 -0
- package/dist/cjs/i18n/es.js +19 -0
- package/dist/cjs/i18n/fi.js +19 -0
- package/dist/cjs/i18n/fr.js +19 -0
- package/dist/cjs/i18n/hu.js +19 -0
- package/dist/cjs/i18n/it.js +19 -0
- package/dist/cjs/i18n/ja.js +19 -0
- package/dist/cjs/i18n/ko.js +19 -0
- package/dist/cjs/i18n/nb.js +19 -0
- package/dist/cjs/i18n/nl.js +19 -0
- package/dist/cjs/i18n/pl.js +19 -0
- package/dist/cjs/i18n/pt_BR.js +19 -0
- package/dist/cjs/i18n/ru.js +19 -0
- package/dist/cjs/i18n/sv.js +19 -0
- package/dist/cjs/i18n/th.js +19 -0
- package/dist/cjs/i18n/tr.js +19 -0
- package/dist/cjs/i18n/uk.js +19 -0
- package/dist/cjs/i18n/vi.js +19 -0
- package/dist/cjs/i18n/zh.js +19 -0
- package/dist/cjs/i18n/zh_TW.js +19 -0
- package/dist/cjs/lists/analytics.js +40 -0
- package/dist/cjs/lists/indentation.js +24 -0
- package/dist/cjs/lists/index.js +89 -0
- package/dist/cjs/lists/node.js +97 -0
- package/dist/cjs/lists/replace-content.js +24 -0
- package/dist/cjs/lists/selection.js +59 -0
- package/dist/cjs/mark/commands.js +201 -0
- package/dist/cjs/mark/index.js +30 -0
- package/dist/cjs/messages/full-page.js +25 -0
- package/dist/cjs/messages/index.js +7 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/node-width/index.js +10 -2
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/ui/Toolbar/index.js +8 -0
- package/dist/cjs/ui/index.js +7 -0
- package/dist/cjs/ui-menu/DropdownMenu/index.js +16 -2
- package/dist/cjs/ui-menu/ToolbarArrowKeyNavigationProvider/index.js +219 -0
- package/dist/cjs/ui-menu/index.js +23 -4
- package/dist/cjs/utils/commands.js +110 -2
- package/dist/cjs/utils/document.js +26 -1
- package/dist/cjs/utils/index.js +51 -2
- package/dist/cjs/utils/prosemirror/autojoin.js +68 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/i18n/cs.js +19 -0
- package/dist/es2019/i18n/da.js +19 -0
- package/dist/es2019/i18n/de.js +19 -0
- package/dist/es2019/i18n/es.js +19 -0
- package/dist/es2019/i18n/fi.js +19 -0
- package/dist/es2019/i18n/fr.js +19 -0
- package/dist/es2019/i18n/hu.js +19 -0
- package/dist/es2019/i18n/it.js +19 -0
- package/dist/es2019/i18n/ja.js +19 -0
- package/dist/es2019/i18n/ko.js +19 -0
- package/dist/es2019/i18n/nb.js +19 -0
- package/dist/es2019/i18n/nl.js +19 -0
- package/dist/es2019/i18n/pl.js +19 -0
- package/dist/es2019/i18n/pt_BR.js +19 -0
- package/dist/es2019/i18n/ru.js +19 -0
- package/dist/es2019/i18n/sv.js +19 -0
- package/dist/es2019/i18n/th.js +19 -0
- package/dist/es2019/i18n/tr.js +19 -0
- package/dist/es2019/i18n/uk.js +19 -0
- package/dist/es2019/i18n/vi.js +19 -0
- package/dist/es2019/i18n/zh.js +19 -0
- package/dist/es2019/i18n/zh_TW.js +19 -0
- package/dist/es2019/lists/analytics.js +36 -0
- package/dist/es2019/lists/indentation.js +18 -0
- package/dist/es2019/lists/index.js +6 -0
- package/dist/es2019/lists/node.js +97 -0
- package/dist/es2019/lists/replace-content.js +18 -0
- package/dist/es2019/lists/selection.js +53 -0
- package/dist/es2019/mark/commands.js +205 -0
- package/dist/es2019/mark/index.js +1 -0
- package/dist/es2019/messages/full-page.js +18 -0
- package/dist/es2019/messages/index.js +1 -0
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/node-width/index.js +7 -0
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/ui/Toolbar/index.js +1 -0
- package/dist/es2019/ui/index.js +2 -1
- package/dist/es2019/ui-menu/DropdownMenu/index.js +16 -2
- package/dist/es2019/ui-menu/ToolbarArrowKeyNavigationProvider/index.js +209 -0
- package/dist/es2019/ui-menu/index.js +5 -4
- package/dist/es2019/utils/commands.js +106 -2
- package/dist/es2019/utils/document.js +25 -1
- package/dist/es2019/utils/index.js +3 -2
- package/dist/es2019/utils/prosemirror/autojoin.js +57 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/i18n/cs.js +19 -0
- package/dist/esm/i18n/da.js +19 -0
- package/dist/esm/i18n/de.js +19 -0
- package/dist/esm/i18n/es.js +19 -0
- package/dist/esm/i18n/fi.js +19 -0
- package/dist/esm/i18n/fr.js +19 -0
- package/dist/esm/i18n/hu.js +19 -0
- package/dist/esm/i18n/it.js +19 -0
- package/dist/esm/i18n/ja.js +19 -0
- package/dist/esm/i18n/ko.js +19 -0
- package/dist/esm/i18n/nb.js +19 -0
- package/dist/esm/i18n/nl.js +19 -0
- package/dist/esm/i18n/pl.js +19 -0
- package/dist/esm/i18n/pt_BR.js +19 -0
- package/dist/esm/i18n/ru.js +19 -0
- package/dist/esm/i18n/sv.js +19 -0
- package/dist/esm/i18n/th.js +19 -0
- package/dist/esm/i18n/tr.js +19 -0
- package/dist/esm/i18n/uk.js +19 -0
- package/dist/esm/i18n/vi.js +19 -0
- package/dist/esm/i18n/zh.js +19 -0
- package/dist/esm/i18n/zh_TW.js +19 -0
- package/dist/esm/lists/analytics.js +32 -0
- package/dist/esm/lists/indentation.js +17 -0
- package/dist/esm/lists/index.js +6 -0
- package/dist/esm/lists/node.js +87 -0
- package/dist/esm/lists/replace-content.js +17 -0
- package/dist/esm/lists/selection.js +50 -0
- package/dist/esm/mark/commands.js +190 -0
- package/dist/esm/mark/index.js +1 -0
- package/dist/esm/messages/full-page.js +18 -0
- package/dist/esm/messages/index.js +1 -0
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/node-width/index.js +7 -0
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/ui/Toolbar/index.js +1 -0
- package/dist/esm/ui/index.js +2 -1
- package/dist/esm/ui-menu/DropdownMenu/index.js +15 -2
- package/dist/esm/ui-menu/ToolbarArrowKeyNavigationProvider/index.js +207 -0
- package/dist/esm/ui-menu/index.js +5 -4
- package/dist/esm/utils/commands.js +104 -2
- package/dist/esm/utils/document.js +25 -1
- package/dist/esm/utils/index.js +3 -2
- package/dist/esm/utils/prosemirror/autojoin.js +63 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/i18n/cs.d.ts +19 -0
- package/dist/types/i18n/da.d.ts +19 -0
- package/dist/types/i18n/de.d.ts +19 -0
- package/dist/types/i18n/es.d.ts +19 -0
- package/dist/types/i18n/fi.d.ts +19 -0
- package/dist/types/i18n/fr.d.ts +19 -0
- package/dist/types/i18n/hu.d.ts +19 -0
- package/dist/types/i18n/it.d.ts +19 -0
- package/dist/types/i18n/ja.d.ts +19 -0
- package/dist/types/i18n/ko.d.ts +19 -0
- package/dist/types/i18n/nb.d.ts +19 -0
- package/dist/types/i18n/nl.d.ts +19 -0
- package/dist/types/i18n/pl.d.ts +19 -0
- package/dist/types/i18n/pt_BR.d.ts +19 -0
- package/dist/types/i18n/ru.d.ts +19 -0
- package/dist/types/i18n/sv.d.ts +19 -0
- package/dist/types/i18n/th.d.ts +19 -0
- package/dist/types/i18n/tr.d.ts +19 -0
- package/dist/types/i18n/uk.d.ts +19 -0
- package/dist/types/i18n/vi.d.ts +19 -0
- package/dist/types/i18n/zh.d.ts +19 -0
- package/dist/types/i18n/zh_TW.d.ts +19 -0
- package/dist/types/lists/analytics.d.ts +4 -0
- package/dist/types/lists/indentation.d.ts +5 -0
- package/dist/types/lists/index.d.ts +6 -0
- package/dist/types/lists/node.d.ts +18 -0
- package/dist/types/lists/replace-content.d.ts +8 -0
- package/dist/types/lists/selection.d.ts +13 -0
- package/dist/types/mark/commands.d.ts +18 -0
- package/dist/types/mark/index.d.ts +1 -0
- package/dist/types/messages/full-page.d.ts +17 -0
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/node-width/index.d.ts +1 -0
- package/dist/types/ui/Toolbar/index.d.ts +5 -0
- package/dist/types/ui/index.d.ts +2 -0
- package/dist/types/ui-menu/DropdownMenu/index.d.ts +2 -1
- package/dist/types/ui-menu/ToolbarArrowKeyNavigationProvider/index.d.ts +30 -0
- package/dist/types/ui-menu/index.d.ts +7 -6
- package/dist/types/utils/commands.d.ts +36 -2
- package/dist/types/utils/document.d.ts +4 -0
- package/dist/types/utils/index.d.ts +4 -2
- package/dist/types/utils/prosemirror/autojoin.d.ts +13 -0
- package/dist/types-ts4.5/i18n/cs.d.ts +19 -0
- package/dist/types-ts4.5/i18n/da.d.ts +19 -0
- package/dist/types-ts4.5/i18n/de.d.ts +19 -0
- package/dist/types-ts4.5/i18n/es.d.ts +19 -0
- package/dist/types-ts4.5/i18n/fi.d.ts +19 -0
- package/dist/types-ts4.5/i18n/fr.d.ts +19 -0
- package/dist/types-ts4.5/i18n/hu.d.ts +19 -0
- package/dist/types-ts4.5/i18n/it.d.ts +19 -0
- package/dist/types-ts4.5/i18n/ja.d.ts +19 -0
- package/dist/types-ts4.5/i18n/ko.d.ts +19 -0
- package/dist/types-ts4.5/i18n/nb.d.ts +19 -0
- package/dist/types-ts4.5/i18n/nl.d.ts +19 -0
- package/dist/types-ts4.5/i18n/pl.d.ts +19 -0
- package/dist/types-ts4.5/i18n/pt_BR.d.ts +19 -0
- package/dist/types-ts4.5/i18n/ru.d.ts +19 -0
- package/dist/types-ts4.5/i18n/sv.d.ts +19 -0
- package/dist/types-ts4.5/i18n/th.d.ts +19 -0
- package/dist/types-ts4.5/i18n/tr.d.ts +19 -0
- package/dist/types-ts4.5/i18n/uk.d.ts +19 -0
- package/dist/types-ts4.5/i18n/vi.d.ts +19 -0
- package/dist/types-ts4.5/i18n/zh.d.ts +19 -0
- package/dist/types-ts4.5/i18n/zh_TW.d.ts +19 -0
- package/dist/types-ts4.5/lists/analytics.d.ts +4 -0
- package/dist/types-ts4.5/lists/indentation.d.ts +5 -0
- package/dist/types-ts4.5/lists/index.d.ts +6 -0
- package/dist/types-ts4.5/lists/node.d.ts +18 -0
- package/dist/types-ts4.5/lists/replace-content.d.ts +8 -0
- package/dist/types-ts4.5/lists/selection.d.ts +13 -0
- package/dist/types-ts4.5/mark/commands.d.ts +18 -0
- package/dist/types-ts4.5/mark/index.d.ts +1 -0
- package/dist/types-ts4.5/messages/full-page.d.ts +17 -0
- package/dist/types-ts4.5/messages/index.d.ts +1 -0
- package/dist/types-ts4.5/node-width/index.d.ts +1 -0
- package/dist/types-ts4.5/ui/Toolbar/index.d.ts +5 -0
- package/dist/types-ts4.5/ui/index.d.ts +2 -0
- package/dist/types-ts4.5/ui-menu/DropdownMenu/index.d.ts +2 -1
- package/dist/types-ts4.5/ui-menu/ToolbarArrowKeyNavigationProvider/index.d.ts +30 -0
- package/dist/types-ts4.5/ui-menu/index.d.ts +7 -6
- package/dist/types-ts4.5/utils/commands.d.ts +42 -2
- package/dist/types-ts4.5/utils/document.d.ts +4 -0
- package/dist/types-ts4.5/utils/index.d.ts +4 -2
- package/dist/types-ts4.5/utils/prosemirror/autojoin.d.ts +13 -0
- package/lists/package.json +15 -0
- package/mark/package.json +15 -0
- package/package.json +6 -3
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { isListItemNode, isListNode } from '../utils';
|
|
3
|
+
export function isListNodeValidContent(node) {
|
|
4
|
+
var bulletList = node.type.schema.nodes.bulletList;
|
|
5
|
+
if (!bulletList) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
var listFragment = Fragment.from(bulletList.createAndFill());
|
|
9
|
+
return !isListItemNode(node) && node.type.validContent(listFragment);
|
|
10
|
+
}
|
|
11
|
+
export var JoinDirection = /*#__PURE__*/function (JoinDirection) {
|
|
12
|
+
JoinDirection[JoinDirection["LEFT"] = 1] = "LEFT";
|
|
13
|
+
JoinDirection[JoinDirection["RIGHT"] = -1] = "RIGHT";
|
|
14
|
+
return JoinDirection;
|
|
15
|
+
}({});
|
|
16
|
+
export var joinSiblingLists = function joinSiblingLists(_ref) {
|
|
17
|
+
var tr = _ref.tr,
|
|
18
|
+
direction = _ref.direction,
|
|
19
|
+
forceListType = _ref.forceListType;
|
|
20
|
+
var result = {
|
|
21
|
+
orderedList: 0,
|
|
22
|
+
bulletList: 0
|
|
23
|
+
};
|
|
24
|
+
var doc = tr.doc,
|
|
25
|
+
_tr$selection = tr.selection,
|
|
26
|
+
$from = _tr$selection.$from,
|
|
27
|
+
$to = _tr$selection.$to,
|
|
28
|
+
selection = tr.selection;
|
|
29
|
+
var range = $from.blockRange($to, isListNodeValidContent);
|
|
30
|
+
if (!range) {
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
var rootListNode = doc.nodeAt(range.start);
|
|
34
|
+
var from = isListNode(rootListNode) ? range.start : 0;
|
|
35
|
+
var to = isListNode(rootListNode) ? range.end : tr.doc.content.size;
|
|
36
|
+
var joins = [];
|
|
37
|
+
doc.nodesBetween(from, to, function (node, pos, parent) {
|
|
38
|
+
var resolvedPos = doc.resolve(pos);
|
|
39
|
+
var nodeBefore = resolvedPos.nodeBefore,
|
|
40
|
+
nodeAfter = resolvedPos.nodeAfter;
|
|
41
|
+
if (!nodeBefore || !nodeAfter || !isListNode(nodeBefore) || !isListNode(nodeAfter)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var isNestedList = isListItemNode(parent);
|
|
45
|
+
if (!isNestedList && nodeBefore.type !== nodeAfter.type && !forceListType) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
var index = resolvedPos.index();
|
|
49
|
+
var positionPreviousNode = resolvedPos.posAtIndex(index - 1);
|
|
50
|
+
var positionCurrentNode = resolvedPos.posAtIndex(index);
|
|
51
|
+
|
|
52
|
+
// If the previous node is part of the selection, OR
|
|
53
|
+
// If the previous node is not part of the selection and the previous node has the same list type that we’re converting to
|
|
54
|
+
var joinBefore = positionPreviousNode >= from || nodeBefore.type === forceListType;
|
|
55
|
+
if (forceListType) {
|
|
56
|
+
if (joinBefore) {
|
|
57
|
+
tr.setNodeMarkup(positionPreviousNode, forceListType);
|
|
58
|
+
}
|
|
59
|
+
tr.setNodeMarkup(positionCurrentNode, forceListType);
|
|
60
|
+
}
|
|
61
|
+
if (isNestedList && nodeBefore.type !== nodeAfter.type) {
|
|
62
|
+
var nodeType = direction === JoinDirection.RIGHT ? nodeAfter.type : nodeBefore.type;
|
|
63
|
+
tr.setNodeMarkup(positionPreviousNode, nodeType);
|
|
64
|
+
}
|
|
65
|
+
if (joinBefore) {
|
|
66
|
+
joins.push(pos);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
if (selection.empty && rootListNode && isListNode(rootListNode)) {
|
|
70
|
+
var resolvedPos = doc.resolve(range.start + rootListNode.nodeSize);
|
|
71
|
+
var nodeBefore = resolvedPos.nodeBefore,
|
|
72
|
+
nodeAfter = resolvedPos.nodeAfter;
|
|
73
|
+
if (nodeBefore && nodeAfter && isListNode(nodeBefore) && isListNode(nodeAfter) && nodeAfter.type === nodeBefore.type) {
|
|
74
|
+
joins.push(resolvedPos.pos);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (var i = joins.length - 1; i >= 0; i--) {
|
|
78
|
+
var listNode = tr.doc.nodeAt(joins[i]);
|
|
79
|
+
var listName = listNode === null || listNode === void 0 ? void 0 : listNode.type.name;
|
|
80
|
+
if (listName && (listName === 'orderedList' || listName === 'bulletList')) {
|
|
81
|
+
var amount = result[listName] || 0;
|
|
82
|
+
result[listName] = amount + 1;
|
|
83
|
+
}
|
|
84
|
+
tr.join(joins[i]);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
|
+
export var moveTargetIntoList = function moveTargetIntoList(_ref) {
|
|
3
|
+
var _$target$nodeAfter;
|
|
4
|
+
var insertPosition = _ref.insertPosition,
|
|
5
|
+
$target = _ref.$target;
|
|
6
|
+
// take the text content of the paragraph and insert after the paragraph up until before the the cut
|
|
7
|
+
var from = insertPosition;
|
|
8
|
+
var to = $target.pos + (((_$target$nodeAfter = $target.nodeAfter) === null || _$target$nodeAfter === void 0 ? void 0 : _$target$nodeAfter.nodeSize) || 0); //$cut.pos + $cut.nodeAfter.nodeSize;
|
|
9
|
+
var gapFrom = $target.posAtIndex(0, $target.depth + 1); // start pos of the child
|
|
10
|
+
var gapTo = $target.doc.resolve(gapFrom).end(); // end pos of the paragraph
|
|
11
|
+
|
|
12
|
+
if (gapTo - gapFrom === 0) {
|
|
13
|
+
return new ReplaceStep(from, to, $target.doc.slice(insertPosition, $target.pos));
|
|
14
|
+
}
|
|
15
|
+
var step = new ReplaceAroundStep(from, to, gapFrom, gapTo, $target.doc.slice(insertPosition, $target.pos), 0, true);
|
|
16
|
+
return step;
|
|
17
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { findParentNodeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
+
import { isListItemNode, isListNode } from '../utils';
|
|
4
|
+
export var numberNestedLists = function numberNestedLists(resolvedPos) {
|
|
5
|
+
var count = 0;
|
|
6
|
+
for (var i = resolvedPos.depth - 1; i > 0; i--) {
|
|
7
|
+
var node = resolvedPos.node(i);
|
|
8
|
+
if (isListNode(node)) {
|
|
9
|
+
count += 1;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return count;
|
|
13
|
+
};
|
|
14
|
+
export var getListItemAttributes = function getListItemAttributes($pos) {
|
|
15
|
+
var indentLevel = numberNestedLists($pos) - 1;
|
|
16
|
+
var itemAtPos = findParentNodeClosestToPos($pos, isListItemNode);
|
|
17
|
+
|
|
18
|
+
// Get the index of the current item relative to parent (parent is at item depth - 1)
|
|
19
|
+
var itemIndex = $pos.index(itemAtPos ? itemAtPos.depth - 1 : undefined);
|
|
20
|
+
return {
|
|
21
|
+
indentLevel: indentLevel,
|
|
22
|
+
itemIndex: itemIndex
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
export var normalizeListItemsSelection = function normalizeListItemsSelection(_ref) {
|
|
26
|
+
var selection = _ref.selection,
|
|
27
|
+
doc = _ref.doc;
|
|
28
|
+
if (selection.empty) {
|
|
29
|
+
return selection;
|
|
30
|
+
}
|
|
31
|
+
var $from = selection.$from,
|
|
32
|
+
$to = selection.$to;
|
|
33
|
+
if (selection instanceof NodeSelection) {
|
|
34
|
+
var _head = resolvePositionToStartOfListItem($from);
|
|
35
|
+
return new TextSelection(_head, _head);
|
|
36
|
+
}
|
|
37
|
+
var head = resolvePositionToStartOfListItem($from);
|
|
38
|
+
var anchor = resolvePositionToEndOfListItem($to);
|
|
39
|
+
return new TextSelection(anchor, head);
|
|
40
|
+
};
|
|
41
|
+
var resolvePositionToStartOfListItem = function resolvePositionToStartOfListItem($pos) {
|
|
42
|
+
var fromRange = $pos.blockRange($pos, isListItemNode);
|
|
43
|
+
var fromPosition = fromRange && $pos.textOffset === 0 && fromRange.end - 1 === $pos.pos ? Selection.near($pos.doc.resolve(fromRange.end + 1), 1).$from : $pos;
|
|
44
|
+
return fromPosition;
|
|
45
|
+
};
|
|
46
|
+
var resolvePositionToEndOfListItem = function resolvePositionToEndOfListItem($pos) {
|
|
47
|
+
var toRange = $pos.blockRange($pos, isListItemNode);
|
|
48
|
+
var toPosition = toRange && $pos.textOffset === 0 && toRange.start + 1 === $pos.pos ? Selection.near($pos.doc.resolve(toRange.start - 1), -1).$to : $pos;
|
|
49
|
+
return toPosition;
|
|
50
|
+
};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
// eslint-disable-next-line no-duplicate-imports
|
|
3
|
+
|
|
4
|
+
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
|
|
5
|
+
var SMART_TO_ASCII = {
|
|
6
|
+
'…': '...',
|
|
7
|
+
'→': '->',
|
|
8
|
+
'←': '<-',
|
|
9
|
+
'–': '--',
|
|
10
|
+
'“': '"',
|
|
11
|
+
'”': '"',
|
|
12
|
+
'‘': "'",
|
|
13
|
+
'’': "'"
|
|
14
|
+
};
|
|
15
|
+
var FIND_SMART_CHAR = new RegExp("[".concat(Object.keys(SMART_TO_ASCII).join(''), "]"), 'g');
|
|
16
|
+
var isNodeTextBlock = function isNodeTextBlock(schema) {
|
|
17
|
+
var _schema$nodes = schema.nodes,
|
|
18
|
+
mention = _schema$nodes.mention,
|
|
19
|
+
text = _schema$nodes.text,
|
|
20
|
+
emoji = _schema$nodes.emoji;
|
|
21
|
+
return function (node, _, parent) {
|
|
22
|
+
if (node.type === mention || node.type === emoji || node.type === text) {
|
|
23
|
+
return parent === null || parent === void 0 ? void 0 : parent.isTextblock;
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
var replaceSmartCharsToAscii = function replaceSmartCharsToAscii(position, textContent, tr) {
|
|
29
|
+
var schema = tr.doc.type.schema;
|
|
30
|
+
var match;
|
|
31
|
+
while (match = FIND_SMART_CHAR.exec(textContent)) {
|
|
32
|
+
var _match = match,
|
|
33
|
+
smartChar = _match[0],
|
|
34
|
+
offset = _match.index;
|
|
35
|
+
var replacePos = tr.mapping.map(position + offset);
|
|
36
|
+
var replacementText = schema.text(SMART_TO_ASCII[smartChar]);
|
|
37
|
+
tr.replaceWith(replacePos, replacePos + smartChar.length, replacementText);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var replaceMentionOrEmojiForTextContent = function replaceMentionOrEmojiForTextContent(position, nodeSize, textContent, tr) {
|
|
41
|
+
var currentPos = tr.mapping.map(position);
|
|
42
|
+
var schema = tr.doc.type.schema;
|
|
43
|
+
tr.replaceWith(currentPos, currentPos + nodeSize, schema.text(textContent));
|
|
44
|
+
};
|
|
45
|
+
export function filterChildrenBetween(doc, from, to, predicate) {
|
|
46
|
+
var results = [];
|
|
47
|
+
doc.nodesBetween(from, to, function (node, pos, parent) {
|
|
48
|
+
if (predicate(node, pos, parent)) {
|
|
49
|
+
results.push({
|
|
50
|
+
node: node,
|
|
51
|
+
pos: pos
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return results;
|
|
56
|
+
}
|
|
57
|
+
export var transformSmartCharsMentionsAndEmojis = function transformSmartCharsMentionsAndEmojis(from, to, tr) {
|
|
58
|
+
var schema = tr.doc.type.schema;
|
|
59
|
+
var _schema$nodes2 = schema.nodes,
|
|
60
|
+
mention = _schema$nodes2.mention,
|
|
61
|
+
text = _schema$nodes2.text,
|
|
62
|
+
emoji = _schema$nodes2.emoji;
|
|
63
|
+
// Traverse through all the nodes within the range and replace them with their plaintext counterpart
|
|
64
|
+
var children = filterChildrenBetween(tr.doc, from, to, isNodeTextBlock(schema));
|
|
65
|
+
children.forEach(function (_ref) {
|
|
66
|
+
var node = _ref.node,
|
|
67
|
+
pos = _ref.pos;
|
|
68
|
+
if (node.type === mention || node.type === emoji) {
|
|
69
|
+
// Convert gracefully when no text found, ProseMirror will blow up if you try to create a node with an empty string or undefined
|
|
70
|
+
var replacementText = node.attrs.text;
|
|
71
|
+
if (typeof replacementText === 'undefined' || replacementText === '') {
|
|
72
|
+
replacementText = "".concat(node.type.name, " text missing");
|
|
73
|
+
}
|
|
74
|
+
replaceMentionOrEmojiForTextContent(pos, node.nodeSize, replacementText, tr);
|
|
75
|
+
} else if (node.type === text && node.text) {
|
|
76
|
+
var replacePosition = pos > from ? pos : from;
|
|
77
|
+
var textToReplace = pos > from ? node.text : node.text.substr(from - pos);
|
|
78
|
+
replaceSmartCharsToAscii(replacePosition, textToReplace, tr);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
export var applyMarkOnRange = function applyMarkOnRange(from, to, removeMark, mark, tr) {
|
|
83
|
+
var schema = tr.doc.type.schema;
|
|
84
|
+
var code = schema.marks.code;
|
|
85
|
+
if (mark.type === code) {
|
|
86
|
+
transformSmartCharsMentionsAndEmojis(from, to, tr);
|
|
87
|
+
}
|
|
88
|
+
tr.doc.nodesBetween(tr.mapping.map(from), tr.mapping.map(to), function (node, pos) {
|
|
89
|
+
if (!node.isText) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// This is an issue when the user selects some text.
|
|
94
|
+
// We need to check if the current node position is less than the range selection from.
|
|
95
|
+
// If it’s true, that means we should apply the mark using the range selection,
|
|
96
|
+
// not the current node position.
|
|
97
|
+
var nodeBetweenFrom = Math.max(pos, tr.mapping.map(from));
|
|
98
|
+
var nodeBetweenTo = Math.min(pos + node.nodeSize, tr.mapping.map(to));
|
|
99
|
+
if (removeMark) {
|
|
100
|
+
tr.removeMark(nodeBetweenFrom, nodeBetweenTo, mark);
|
|
101
|
+
} else {
|
|
102
|
+
tr.addMark(nodeBetweenFrom, nodeBetweenTo, mark);
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
});
|
|
106
|
+
return tr;
|
|
107
|
+
};
|
|
108
|
+
var entireSelectionContainsMark = function entireSelectionContainsMark(mark, doc, fromPos, toPos) {
|
|
109
|
+
var onlyContainsMark = true;
|
|
110
|
+
doc.nodesBetween(fromPos, toPos, function (node) {
|
|
111
|
+
// Skip recursion once we've found text which doesn't include the mark
|
|
112
|
+
if (!onlyContainsMark) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
if (node.isText) {
|
|
116
|
+
onlyContainsMark && (onlyContainsMark = mark.isInSet(node.marks));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return onlyContainsMark;
|
|
120
|
+
};
|
|
121
|
+
var toggleMarkInRange = function toggleMarkInRange(mark) {
|
|
122
|
+
return function (state, dispatch) {
|
|
123
|
+
var tr = state.tr;
|
|
124
|
+
if (state.selection instanceof CellSelection) {
|
|
125
|
+
var removeMark = true;
|
|
126
|
+
var cells = [];
|
|
127
|
+
state.selection.forEachCell(function (cell, cellPos) {
|
|
128
|
+
cells.push({
|
|
129
|
+
node: cell,
|
|
130
|
+
pos: cellPos
|
|
131
|
+
});
|
|
132
|
+
var from = cellPos;
|
|
133
|
+
var to = cellPos + cell.nodeSize;
|
|
134
|
+
removeMark && (removeMark = entireSelectionContainsMark(mark, state.doc, from, to));
|
|
135
|
+
});
|
|
136
|
+
for (var i = cells.length - 1; i >= 0; i--) {
|
|
137
|
+
var cell = cells[i];
|
|
138
|
+
var from = cell.pos;
|
|
139
|
+
var to = from + cell.node.nodeSize;
|
|
140
|
+
applyMarkOnRange(from, to, removeMark, mark, tr);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
var _state$selection = state.selection,
|
|
144
|
+
$from = _state$selection.$from,
|
|
145
|
+
$to = _state$selection.$to;
|
|
146
|
+
// We decide to remove the mark only if the entire selection contains the mark
|
|
147
|
+
// Examples with *bold* text
|
|
148
|
+
// Scenario 1: Selection contains both bold and non-bold text -> bold entire selection
|
|
149
|
+
// Scenario 2: Selection contains only bold text -> un-bold entire selection
|
|
150
|
+
// Scenario 3: Selection contains no bold text -> bold entire selection
|
|
151
|
+
var _removeMark = entireSelectionContainsMark(mark, state.doc, $from.pos, $to.pos);
|
|
152
|
+
applyMarkOnRange($from.pos, $to.pos, _removeMark, mark, tr);
|
|
153
|
+
}
|
|
154
|
+
if (tr.docChanged) {
|
|
155
|
+
if (dispatch) {
|
|
156
|
+
dispatch(tr);
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* A wrapper over the default toggleMark, except when we have a selection
|
|
166
|
+
* we only toggle marks on text nodes rather than inline nodes.
|
|
167
|
+
* @param markType
|
|
168
|
+
* @param attrs
|
|
169
|
+
*/
|
|
170
|
+
export var toggleMark = function toggleMark(markType, attrs) {
|
|
171
|
+
return function (state, dispatch) {
|
|
172
|
+
var mark = markType.create(attrs);
|
|
173
|
+
|
|
174
|
+
// For cursor selections we can use the default behaviour.
|
|
175
|
+
if (state.selection instanceof TextSelection && state.selection.$cursor) {
|
|
176
|
+
var tr = state.tr;
|
|
177
|
+
if (mark.isInSet(state.storedMarks || state.selection.$cursor.marks())) {
|
|
178
|
+
tr.removeStoredMark(mark);
|
|
179
|
+
} else {
|
|
180
|
+
tr.addStoredMark(mark);
|
|
181
|
+
}
|
|
182
|
+
if (dispatch) {
|
|
183
|
+
dispatch(tr);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
return toggleMarkInRange(mark)(state, dispatch);
|
|
189
|
+
};
|
|
190
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { transformSmartCharsMentionsAndEmojis, applyMarkOnRange, toggleMark, filterChildrenBetween } from './commands';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export var messages = defineMessages({
|
|
3
|
+
toolbarLabel: {
|
|
4
|
+
id: 'fabric.editor.toolbarLabel',
|
|
5
|
+
defaultMessage: 'Editor toolbar',
|
|
6
|
+
description: 'Label for the ARIA region landmark'
|
|
7
|
+
},
|
|
8
|
+
pageActionsLabel: {
|
|
9
|
+
id: 'fabric.editor.pageActionsLabel',
|
|
10
|
+
defaultMessage: 'Page actions',
|
|
11
|
+
description: 'Label for the ARIA region landmark'
|
|
12
|
+
},
|
|
13
|
+
editableContentLabel: {
|
|
14
|
+
id: 'fabric.editor.editableContentLabel',
|
|
15
|
+
defaultMessage: 'Editable content',
|
|
16
|
+
description: 'Label for the ARIA region landmark'
|
|
17
|
+
}
|
|
18
|
+
});
|
|
@@ -7,6 +7,7 @@ export { codeBlockButtonMessages } from './codeBlockButton';
|
|
|
7
7
|
export { toolbarInsertBlockMessages } from './insert-block';
|
|
8
8
|
export { toolbarMessages as mediaAndEmbedToolbarMessages } from './media-and-embed-toolbar';
|
|
9
9
|
export { messages as cardMessages } from './card';
|
|
10
|
+
export { messages as fullPageMessages } from './full-page';
|
|
10
11
|
export default defineMessages({
|
|
11
12
|
layoutFixedWidth: {
|
|
12
13
|
id: 'fabric.editor.layoutFixedWidth',
|
|
@@ -6,7 +6,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
6
6
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
7
7
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
8
8
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
9
|
-
var packageVersion = "74.
|
|
9
|
+
var packageVersion = "74.31.0";
|
|
10
10
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
11
11
|
// Remove URL as it has UGC
|
|
12
12
|
// TODO: Sanitise the URL instead of just removing it
|
|
@@ -100,4 +100,11 @@ export var getTableContainerWidth = function getTableContainerWidth(node) {
|
|
|
100
100
|
return node.attrs.width;
|
|
101
101
|
}
|
|
102
102
|
return layoutToWidth[node.attrs.layout];
|
|
103
|
+
};
|
|
104
|
+
export var getTableWidthWithNumberColumn = function getTableWidthWithNumberColumn(node, offset) {
|
|
105
|
+
var isNumberColumnEnabled = node.attrs.isNumberColumnEnabled;
|
|
106
|
+
if (isNumberColumnEnabled && offset > 0) {
|
|
107
|
+
return getTableContainerWidth(node) - offset;
|
|
108
|
+
}
|
|
109
|
+
return getTableContainerWidth(node);
|
|
103
110
|
};
|
|
@@ -18,7 +18,7 @@ import { themed } from '@atlaskit/theme/components';
|
|
|
18
18
|
import { borderRadius } from '@atlaskit/theme/constants';
|
|
19
19
|
import Layer from '../Layer';
|
|
20
20
|
var packageName = "@atlaskit/editor-common";
|
|
21
|
-
var packageVersion = "74.
|
|
21
|
+
var packageVersion = "74.31.0";
|
|
22
22
|
var halfFocusRing = 1;
|
|
23
23
|
var dropOffset = '0, 8';
|
|
24
24
|
var DropList = /*#__PURE__*/function (_Component) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export var EDIT_AREA_ID = 'ak-editor-textarea';
|
package/dist/esm/ui/index.js
CHANGED
|
@@ -25,4 +25,5 @@ export { snapTo, handleSides, imageAlignmentMap } from './ResizerLegacy/utils';
|
|
|
25
25
|
export { wrapperStyle } from './ResizerLegacy/styled';
|
|
26
26
|
export { panelTextInput } from './PanelTextInput/styles';
|
|
27
27
|
export { default as PanelTextInput } from './PanelTextInput';
|
|
28
|
-
export { default as Announcer } from './Announcer/announcer';
|
|
28
|
+
export { default as Announcer } from './Announcer/announcer';
|
|
29
|
+
export { EDIT_AREA_ID } from './Toolbar';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _objectDestructuringEmpty from "@babel/runtime/helpers/objectDestructuringEmpty";
|
|
1
2
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
3
|
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
4
|
import _extends from "@babel/runtime/helpers/extends";
|
|
@@ -16,7 +17,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
16
17
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
17
18
|
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
18
19
|
/** @jsx jsx */
|
|
19
|
-
import React, { PureComponent } from 'react';
|
|
20
|
+
import React, { PureComponent, useContext } from 'react';
|
|
20
21
|
import { css, jsx } from '@emotion/react';
|
|
21
22
|
import { akEditorFloatingPanelZIndex } from '@atlaskit/editor-shared-styles';
|
|
22
23
|
import { CustomItem, MenuGroup } from '@atlaskit/menu';
|
|
@@ -25,6 +26,7 @@ import { B100, DN600, DN80, N70, N900 } from '@atlaskit/theme/colors';
|
|
|
25
26
|
import { themed } from '@atlaskit/theme/components';
|
|
26
27
|
import Tooltip from '@atlaskit/tooltip';
|
|
27
28
|
import { DropdownMenuSharedCssClassName } from '../../styles';
|
|
29
|
+
import { KeyDownHandlerContext } from '../../ui-menu/ToolbarArrowKeyNavigationProvider';
|
|
28
30
|
import { withReactEditorViewOuterListeners } from '../../ui-react';
|
|
29
31
|
import DropList from '../../ui/DropList';
|
|
30
32
|
import Popup from '../../ui/Popup';
|
|
@@ -317,4 +319,15 @@ function DropdownMenuItem(_ref) {
|
|
|
317
319
|
}, dropListItem);
|
|
318
320
|
}
|
|
319
321
|
return dropListItem;
|
|
320
|
-
}
|
|
322
|
+
}
|
|
323
|
+
export var DropdownMenuWithKeyboardNavigation = /*#__PURE__*/React.memo(function (_ref2) {
|
|
324
|
+
var props = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));
|
|
325
|
+
var keyDownHandlerContext = useContext(KeyDownHandlerContext);
|
|
326
|
+
//This context is to handle the tab, Arrow Right/Left key events for dropdown.
|
|
327
|
+
//Default context has the void callbacks for above key events
|
|
328
|
+
return jsx(DropdownMenuWrapper, _extends({
|
|
329
|
+
arrowKeyNavigationProviderOptions: _objectSpread(_objectSpread({}, props.arrowKeyNavigationProviderOptions), {}, {
|
|
330
|
+
keyDownHandlerContext: keyDownHandlerContext
|
|
331
|
+
})
|
|
332
|
+
}, props));
|
|
333
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
+
var _templateObject;
|
|
3
|
+
/** @jsx jsx */
|
|
4
|
+
/* eslint-disable no-console */
|
|
5
|
+
import React, { useCallback, useLayoutEffect, useRef } from 'react';
|
|
6
|
+
import { css, jsx } from '@emotion/react';
|
|
7
|
+
import { fullPageMessages as messages } from '../../messages';
|
|
8
|
+
import { EDIT_AREA_ID } from '../../ui';
|
|
9
|
+
/*
|
|
10
|
+
** The context is used to handle the keydown events of submenus.
|
|
11
|
+
** Because the keyboard navigation is explicitly managed for main toolbar items
|
|
12
|
+
** Few key presses such as Tab,Arrow Right/Left need ot be handled here via context
|
|
13
|
+
*/
|
|
14
|
+
export var KeyDownHandlerContext = /*#__PURE__*/React.createContext({
|
|
15
|
+
handleArrowLeft: function handleArrowLeft() {},
|
|
16
|
+
handleArrowRight: function handleArrowRight() {},
|
|
17
|
+
handleTab: function handleTab() {}
|
|
18
|
+
});
|
|
19
|
+
var centeredToolbarContainer = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: flex;\n width: 100%;\n align-items: center;\n"])));
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* This component is a wrapper of main toolbar which listens to keydown events of children
|
|
23
|
+
* and handles left/right arrow key navigation for all focusable elements
|
|
24
|
+
* @param
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
export var ToolbarArrowKeyNavigationProvider = function ToolbarArrowKeyNavigationProvider(_ref) {
|
|
28
|
+
var children = _ref.children,
|
|
29
|
+
editorView = _ref.editorView,
|
|
30
|
+
childComponentSelector = _ref.childComponentSelector,
|
|
31
|
+
handleEscape = _ref.handleEscape,
|
|
32
|
+
disableArrowKeyNavigation = _ref.disableArrowKeyNavigation,
|
|
33
|
+
isShortcutToFocusToolbar = _ref.isShortcutToFocusToolbar,
|
|
34
|
+
editorAppearance = _ref.editorAppearance,
|
|
35
|
+
useStickyToolbar = _ref.useStickyToolbar,
|
|
36
|
+
intl = _ref.intl;
|
|
37
|
+
var wrapperRef = useRef(null);
|
|
38
|
+
var selectedItemIndex = useRef(0);
|
|
39
|
+
var incrementIndex = useCallback(function (list) {
|
|
40
|
+
var index = 0;
|
|
41
|
+
if (document.activeElement) {
|
|
42
|
+
index = list.indexOf(document.activeElement);
|
|
43
|
+
index = (index + 1) % list.length;
|
|
44
|
+
}
|
|
45
|
+
selectedItemIndex.current = index;
|
|
46
|
+
}, []);
|
|
47
|
+
var decrementIndex = useCallback(function (list) {
|
|
48
|
+
var index = 0;
|
|
49
|
+
if (document.activeElement) {
|
|
50
|
+
index = list.indexOf(document.activeElement);
|
|
51
|
+
index = (list.length + index - 1) % list.length;
|
|
52
|
+
}
|
|
53
|
+
selectedItemIndex.current = index;
|
|
54
|
+
}, []);
|
|
55
|
+
var handleArrowRight = function handleArrowRight() {
|
|
56
|
+
var _filteredFocusableEle;
|
|
57
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
58
|
+
incrementIndex(filteredFocusableElements);
|
|
59
|
+
(_filteredFocusableEle = filteredFocusableElements[selectedItemIndex.current]) === null || _filteredFocusableEle === void 0 ? void 0 : _filteredFocusableEle.focus();
|
|
60
|
+
};
|
|
61
|
+
var handleArrowLeft = function handleArrowLeft() {
|
|
62
|
+
var _filteredFocusableEle2;
|
|
63
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
64
|
+
decrementIndex(filteredFocusableElements);
|
|
65
|
+
(_filteredFocusableEle2 = filteredFocusableElements[selectedItemIndex.current]) === null || _filteredFocusableEle2 === void 0 ? void 0 : _filteredFocusableEle2.focus();
|
|
66
|
+
};
|
|
67
|
+
var handleTab = function handleTab() {
|
|
68
|
+
var _filteredFocusableEle3;
|
|
69
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
70
|
+
(_filteredFocusableEle3 = filteredFocusableElements[selectedItemIndex.current]) === null || _filteredFocusableEle3 === void 0 ? void 0 : _filteredFocusableEle3.focus();
|
|
71
|
+
};
|
|
72
|
+
var handleTabLocal = function handleTabLocal() {
|
|
73
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
74
|
+
filteredFocusableElements.forEach(function (element) {
|
|
75
|
+
element.setAttribute('tabindex', '-1');
|
|
76
|
+
});
|
|
77
|
+
filteredFocusableElements[selectedItemIndex.current].setAttribute('tabindex', '0');
|
|
78
|
+
};
|
|
79
|
+
var focusAndScrollToElement = function focusAndScrollToElement(element) {
|
|
80
|
+
var scrollToElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
81
|
+
if (scrollToElement) {
|
|
82
|
+
element === null || element === void 0 ? void 0 : element.scrollIntoView({
|
|
83
|
+
behavior: 'smooth',
|
|
84
|
+
block: 'center',
|
|
85
|
+
inline: 'nearest'
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
element.focus();
|
|
89
|
+
};
|
|
90
|
+
var submenuKeydownHandleContext = {
|
|
91
|
+
handleArrowLeft: handleArrowLeft,
|
|
92
|
+
handleArrowRight: handleArrowRight,
|
|
93
|
+
handleTab: handleTab
|
|
94
|
+
};
|
|
95
|
+
useLayoutEffect(function () {
|
|
96
|
+
if (!wrapperRef.current || disableArrowKeyNavigation) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
var element = wrapperRef.current;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* To handle the key events on the list
|
|
103
|
+
* @param event
|
|
104
|
+
*/
|
|
105
|
+
var handleKeyDown = function handleKeyDown(event) {
|
|
106
|
+
var _document$querySelect, _document$querySelect2, _wrapperRef$current;
|
|
107
|
+
//To trap the focus inside the horizontal toolbar for left and right arrow keys
|
|
108
|
+
var targetElement = event.target;
|
|
109
|
+
|
|
110
|
+
//To filter out the events outside the child component
|
|
111
|
+
if (!targetElement.closest("".concat(childComponentSelector))) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
//The key events are from child components such as dropdown menus / popups are ignored
|
|
116
|
+
if ((_document$querySelect = document.querySelector('[data-role="droplistContent"], [data-test-id="color-picker-menu"], [data-emoji-picker-container="true"]')) !== null && _document$querySelect !== void 0 && _document$querySelect.contains(targetElement) || (_document$querySelect2 = document.querySelector('[data-test-id="color-picker-menu"]')) !== null && _document$querySelect2 !== void 0 && _document$querySelect2.contains(targetElement) || event.key === 'ArrowUp' || event.key === 'ArrowDown' || disableArrowKeyNavigation) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
var menuWrapper = document.querySelector('.menu-key-handler-wrapper');
|
|
120
|
+
if (menuWrapper) {
|
|
121
|
+
// if menu wrapper exists, then a menu is open and arrow keys will be handled by MenuArrowKeyNavigationProvider
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
125
|
+
if (!filteredFocusableElements || (filteredFocusableElements === null || filteredFocusableElements === void 0 ? void 0 : filteredFocusableElements.length) === 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//This is kind of hack to reset the current focused toolbar item
|
|
130
|
+
//to handle some use cases such as Tab in/out of main toolbar
|
|
131
|
+
if (!((_wrapperRef$current = wrapperRef.current) !== null && _wrapperRef$current !== void 0 && _wrapperRef$current.contains(targetElement))) {
|
|
132
|
+
selectedItemIndex.current = -1;
|
|
133
|
+
} else {
|
|
134
|
+
selectedItemIndex.current = filteredFocusableElements.indexOf(targetElement) > -1 ? filteredFocusableElements.indexOf(targetElement) : selectedItemIndex.current;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//do not scroll to focused element for sticky toolbar when navigating with arrows to avoid unnesessary scroll jump
|
|
138
|
+
var allowScrollToElement = !(editorAppearance === 'comment' && !!useStickyToolbar);
|
|
139
|
+
switch (event.key) {
|
|
140
|
+
case 'ArrowRight':
|
|
141
|
+
incrementIndex(filteredFocusableElements);
|
|
142
|
+
focusAndScrollToElement(filteredFocusableElements[selectedItemIndex.current], allowScrollToElement);
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
break;
|
|
145
|
+
case 'ArrowLeft':
|
|
146
|
+
decrementIndex(filteredFocusableElements);
|
|
147
|
+
focusAndScrollToElement(filteredFocusableElements[selectedItemIndex.current], allowScrollToElement);
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
break;
|
|
150
|
+
case 'Tab':
|
|
151
|
+
handleTabLocal();
|
|
152
|
+
break;
|
|
153
|
+
case 'Escape':
|
|
154
|
+
handleEscape(event);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var globalKeyDownHandler = function globalKeyDownHandler(event) {
|
|
160
|
+
//To focus the first element in the toolbar
|
|
161
|
+
if (isShortcutToFocusToolbar(event)) {
|
|
162
|
+
var _filteredFocusableEle4, _filteredFocusableEle5;
|
|
163
|
+
var filteredFocusableElements = getFilteredFocusableElements(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current);
|
|
164
|
+
(_filteredFocusableEle4 = filteredFocusableElements[0]) === null || _filteredFocusableEle4 === void 0 ? void 0 : _filteredFocusableEle4.focus();
|
|
165
|
+
(_filteredFocusableEle5 = filteredFocusableElements[0]) === null || _filteredFocusableEle5 === void 0 ? void 0 : _filteredFocusableEle5.scrollIntoView({
|
|
166
|
+
behavior: 'smooth',
|
|
167
|
+
block: 'center',
|
|
168
|
+
inline: 'nearest'
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
element === null || element === void 0 ? void 0 : element.addEventListener('keydown', handleKeyDown);
|
|
173
|
+
var editorViewDom = editorView === null || editorView === void 0 ? void 0 : editorView.dom;
|
|
174
|
+
if (isShortcutToFocusToolbar) {
|
|
175
|
+
editorViewDom === null || editorViewDom === void 0 ? void 0 : editorViewDom.addEventListener('keydown', globalKeyDownHandler);
|
|
176
|
+
}
|
|
177
|
+
return function () {
|
|
178
|
+
element === null || element === void 0 ? void 0 : element.removeEventListener('keydown', handleKeyDown);
|
|
179
|
+
if (isShortcutToFocusToolbar) {
|
|
180
|
+
editorViewDom === null || editorViewDom === void 0 ? void 0 : editorViewDom.removeEventListener('keydown', globalKeyDownHandler);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}, [selectedItemIndex, wrapperRef, editorView, disableArrowKeyNavigation, handleEscape, childComponentSelector, incrementIndex, decrementIndex, isShortcutToFocusToolbar, editorAppearance, useStickyToolbar]);
|
|
184
|
+
return jsx("div", {
|
|
185
|
+
css: editorAppearance === 'comment' && centeredToolbarContainer,
|
|
186
|
+
className: "custom-key-handler-wrapper",
|
|
187
|
+
ref: wrapperRef,
|
|
188
|
+
role: "toolbar",
|
|
189
|
+
"aria-label": intl.formatMessage(messages.toolbarLabel),
|
|
190
|
+
"aria-controls": EDIT_AREA_ID
|
|
191
|
+
}, jsx(KeyDownHandlerContext.Provider, {
|
|
192
|
+
value: submenuKeydownHandleContext
|
|
193
|
+
}, children));
|
|
194
|
+
};
|
|
195
|
+
function getFocusableElements(rootNode) {
|
|
196
|
+
if (!rootNode) {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
var focusableModalElements = rootNode.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, div[tabindex="-1"], div[tabindex="0"]') || [];
|
|
200
|
+
return Array.from(focusableModalElements);
|
|
201
|
+
}
|
|
202
|
+
function getFilteredFocusableElements(rootNode) {
|
|
203
|
+
//The focusable elements from child components such as dropdown menus / popups are ignored
|
|
204
|
+
return getFocusableElements(rootNode).filter(function (elm) {
|
|
205
|
+
return !elm.closest('[data-role="droplistContent"]') && !elm.closest('[data-emoji-picker-container="true"]') && !elm.closest('[data-test-id="color-picker-menu"]') && !elm.closest('.scroll-buttons');
|
|
206
|
+
});
|
|
207
|
+
}
|