@atlaskit/editor-common 112.7.5 → 112.8.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/lists/build-replacement-fragment.js +85 -0
- package/dist/cjs/lists/flatten-list.js +73 -0
- package/dist/cjs/lists/index.js +27 -0
- package/dist/cjs/lists/restore-selection.js +66 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/es2019/lists/build-replacement-fragment.js +60 -0
- package/dist/es2019/lists/flatten-list.js +72 -0
- package/dist/es2019/lists/index.js +3 -0
- package/dist/es2019/lists/restore-selection.js +59 -0
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/esm/lists/build-replacement-fragment.js +80 -0
- package/dist/esm/lists/flatten-list.js +67 -0
- package/dist/esm/lists/index.js +3 -0
- package/dist/esm/lists/restore-selection.js +59 -0
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/types/lists/build-replacement-fragment.d.ts +35 -0
- package/dist/types/lists/flatten-list.d.ts +47 -0
- package/dist/types/lists/index.d.ts +6 -0
- package/dist/types/lists/restore-selection.d.ts +41 -0
- package/dist/types-ts4.5/lists/build-replacement-fragment.d.ts +35 -0
- package/dist/types-ts4.5/lists/flatten-list.d.ts +47 -0
- package/dist/types-ts4.5/lists/index.d.ts +6 -0
- package/dist/types-ts4.5/lists/restore-selection.d.ts +41 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 112.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`65cb641586cc0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/65cb641586cc0) -
|
|
8
|
+
Extract shared list indentation utilities: restoreSelection, computeSelectionOffsets,
|
|
9
|
+
buildReplacementFragment, flattenList, and FlattenedItem
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
3
15
|
## 112.7.5
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildReplacementFragment = buildReplacementFragment;
|
|
7
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
8
|
+
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; } } }; }
|
|
9
|
+
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; } }
|
|
10
|
+
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; }
|
|
11
|
+
/** Rebuilds a list-like PM node from a flat array of items. */
|
|
12
|
+
|
|
13
|
+
/** Extracts top-level content nodes from an item being broken out past the root list. */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Build a replacement Fragment from a flat array of items.
|
|
17
|
+
*
|
|
18
|
+
* Items with depth >= 0 are grouped and rebuilt via `rebuildFn`.
|
|
19
|
+
* Items with depth < 0 are extracted via `extractContentFn`.
|
|
20
|
+
*/
|
|
21
|
+
function buildReplacementFragment(_ref) {
|
|
22
|
+
var items = _ref.items,
|
|
23
|
+
schema = _ref.schema,
|
|
24
|
+
rebuildFn = _ref.rebuildFn,
|
|
25
|
+
extractContentFn = _ref.extractContentFn;
|
|
26
|
+
var fragment = _model.Fragment.empty;
|
|
27
|
+
var pendingListSegment = [];
|
|
28
|
+
var pendingStartIdx = 0;
|
|
29
|
+
var contentStartOffsets = new Array(items.length);
|
|
30
|
+
var flushListSegment = function flushListSegment() {
|
|
31
|
+
if (pendingListSegment.length > 0) {
|
|
32
|
+
var fragmentOffset = fragment.size;
|
|
33
|
+
var result = rebuildFn(pendingListSegment, schema);
|
|
34
|
+
if (result) {
|
|
35
|
+
// Map the rebuild's content start offsets into the overall fragment.
|
|
36
|
+
for (var i = 0; i < pendingListSegment.length; i++) {
|
|
37
|
+
contentStartOffsets[pendingStartIdx + i] = fragmentOffset + result.contentStartOffsets[i];
|
|
38
|
+
}
|
|
39
|
+
fragment = fragment.addToEnd(result.node);
|
|
40
|
+
}
|
|
41
|
+
pendingListSegment = [];
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var elIdx = 0;
|
|
45
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
46
|
+
_step;
|
|
47
|
+
try {
|
|
48
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
49
|
+
var _item = _step.value;
|
|
50
|
+
if (_item.depth < 0) {
|
|
51
|
+
flushListSegment();
|
|
52
|
+
// Extracted element — content children become top-level nodes.
|
|
53
|
+
// Record offset of first content child.
|
|
54
|
+
contentStartOffsets[elIdx] = fragment.size;
|
|
55
|
+
var _iterator2 = _createForOfIteratorHelper(extractContentFn(_item, schema)),
|
|
56
|
+
_step2;
|
|
57
|
+
try {
|
|
58
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
59
|
+
var node = _step2.value;
|
|
60
|
+
fragment = fragment.addToEnd(node);
|
|
61
|
+
}
|
|
62
|
+
} catch (err) {
|
|
63
|
+
_iterator2.e(err);
|
|
64
|
+
} finally {
|
|
65
|
+
_iterator2.f();
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
if (pendingListSegment.length === 0) {
|
|
69
|
+
pendingStartIdx = elIdx;
|
|
70
|
+
}
|
|
71
|
+
pendingListSegment.push(_item);
|
|
72
|
+
}
|
|
73
|
+
elIdx++;
|
|
74
|
+
}
|
|
75
|
+
} catch (err) {
|
|
76
|
+
_iterator.e(err);
|
|
77
|
+
} finally {
|
|
78
|
+
_iterator.f();
|
|
79
|
+
}
|
|
80
|
+
flushListSegment();
|
|
81
|
+
return {
|
|
82
|
+
fragment: fragment,
|
|
83
|
+
contentStartOffsets: contentStartOffsets
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.flattenList = flattenList;
|
|
7
|
+
/**
|
|
8
|
+
* Type-specific predicates that vary between regular lists and task lists.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Flattens a list-like PM structure (regular list or task list) into an
|
|
13
|
+
* array of content-bearing items with computed depths.
|
|
14
|
+
*
|
|
15
|
+
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
|
|
16
|
+
* decisions to the provided predicates. The core algorithm — selection
|
|
17
|
+
* intersection, depth adjustment, index tracking — is shared.
|
|
18
|
+
*/
|
|
19
|
+
function flattenList(options, predicates) {
|
|
20
|
+
var doc = options.doc,
|
|
21
|
+
rootListStart = options.rootListStart,
|
|
22
|
+
rootListEnd = options.rootListEnd,
|
|
23
|
+
selectionFrom = options.selectionFrom,
|
|
24
|
+
selectionTo = options.selectionTo,
|
|
25
|
+
indentDelta = options.indentDelta,
|
|
26
|
+
maxDepth = options.maxDepth;
|
|
27
|
+
var isContentNode = predicates.isContentNode,
|
|
28
|
+
getSelectionBounds = predicates.getSelectionBounds,
|
|
29
|
+
getDepth = predicates.getDepth;
|
|
30
|
+
var items = [];
|
|
31
|
+
var startIndex = -1;
|
|
32
|
+
var endIndex = -1;
|
|
33
|
+
var exceedsMaxDepth = false;
|
|
34
|
+
var rootDepth = doc.resolve(rootListStart).depth;
|
|
35
|
+
doc.nodesBetween(rootListStart, rootListEnd, function (node, pos, parent) {
|
|
36
|
+
if (!isContentNode(node, parent) || parent == null) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
var _getSelectionBounds = getSelectionBounds(node, pos),
|
|
40
|
+
start = _getSelectionBounds.start,
|
|
41
|
+
end = _getSelectionBounds.end;
|
|
42
|
+
var isSelected = selectionFrom === selectionTo ? selectionFrom >= start && selectionFrom <= end : start < selectionTo && end > selectionFrom;
|
|
43
|
+
var resolvedDepth = doc.resolve(pos).depth;
|
|
44
|
+
var depth = getDepth(resolvedDepth, rootDepth) + (isSelected ? indentDelta : 0);
|
|
45
|
+
items.push({
|
|
46
|
+
node: node,
|
|
47
|
+
pos: pos,
|
|
48
|
+
depth: depth,
|
|
49
|
+
isSelected: isSelected,
|
|
50
|
+
listType: parent.type.name,
|
|
51
|
+
parentListAttrs: parent.attrs
|
|
52
|
+
});
|
|
53
|
+
if (isSelected) {
|
|
54
|
+
var index = items.length - 1;
|
|
55
|
+
if (startIndex === -1) {
|
|
56
|
+
startIndex = index;
|
|
57
|
+
}
|
|
58
|
+
endIndex = index;
|
|
59
|
+
if (maxDepth != null && depth >= maxDepth) {
|
|
60
|
+
exceedsMaxDepth = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
});
|
|
65
|
+
if (items.length === 0 || startIndex === -1 || exceedsMaxDepth) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
items: items,
|
|
70
|
+
startIndex: startIndex,
|
|
71
|
+
endIndex: endIndex
|
|
72
|
+
};
|
|
73
|
+
}
|
package/dist/cjs/lists/index.js
CHANGED
|
@@ -9,12 +9,30 @@ Object.defineProperty(exports, "JoinDirection", {
|
|
|
9
9
|
return _node.JoinDirection;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "buildReplacementFragment", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _buildReplacementFragment.buildReplacementFragment;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "computeSelectionOffsets", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _restoreSelection.computeSelectionOffsets;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
12
24
|
Object.defineProperty(exports, "countListItemsInSelection", {
|
|
13
25
|
enumerable: true,
|
|
14
26
|
get: function get() {
|
|
15
27
|
return _analytics.countListItemsInSelection;
|
|
16
28
|
}
|
|
17
29
|
});
|
|
30
|
+
Object.defineProperty(exports, "flattenList", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function get() {
|
|
33
|
+
return _flattenList.flattenList;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
18
36
|
Object.defineProperty(exports, "getCommonListAnalyticsAttributes", {
|
|
19
37
|
enumerable: true,
|
|
20
38
|
get: function get() {
|
|
@@ -93,10 +111,19 @@ Object.defineProperty(exports, "processNestedTaskListsInSameLevel", {
|
|
|
93
111
|
return _node.processNestedTaskListsInSameLevel;
|
|
94
112
|
}
|
|
95
113
|
});
|
|
114
|
+
Object.defineProperty(exports, "restoreSelection", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
get: function get() {
|
|
117
|
+
return _restoreSelection.restoreSelection;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
96
120
|
var _selection = require("./selection");
|
|
97
121
|
var _replaceContent = require("./replace-content");
|
|
98
122
|
var _node = require("./node");
|
|
99
123
|
var _analytics = require("./analytics");
|
|
100
124
|
var _indentation = require("./indentation");
|
|
125
|
+
var _restoreSelection = require("./restore-selection");
|
|
126
|
+
var _buildReplacementFragment = require("./build-replacement-fragment");
|
|
127
|
+
var _flattenList = require("./flatten-list");
|
|
101
128
|
var _utils = require("../utils");
|
|
102
129
|
var _messages = require("./messages");
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.computeSelectionOffsets = computeSelectionOffsets;
|
|
7
|
+
exports.restoreSelection = restoreSelection;
|
|
8
|
+
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
9
|
+
var _selection = require("../selection");
|
|
10
|
+
/**
|
|
11
|
+
* Compute the new selection offsets after list items have been moved/indented/outdented.
|
|
12
|
+
*
|
|
13
|
+
* Uses the content start offsets computed during fragment rebuild to map each
|
|
14
|
+
* selection endpoint to its new absolute position, accounting for the change
|
|
15
|
+
* in the list structure.
|
|
16
|
+
*/
|
|
17
|
+
function computeSelectionOffsets(_ref) {
|
|
18
|
+
var items = _ref.items,
|
|
19
|
+
startIndex = _ref.startIndex,
|
|
20
|
+
endIndex = _ref.endIndex,
|
|
21
|
+
originalFrom = _ref.originalFrom,
|
|
22
|
+
originalTo = _ref.originalTo,
|
|
23
|
+
contentStartOffsets = _ref.contentStartOffsets,
|
|
24
|
+
rootListStart = _ref.rootListStart,
|
|
25
|
+
docSize = _ref.docSize;
|
|
26
|
+
// +1 shifts from the outer edge of the list item node to the start of the content within
|
|
27
|
+
var fromContentStart = items[startIndex].pos + 1;
|
|
28
|
+
var toContentStart = items[endIndex].pos + 1;
|
|
29
|
+
var fromOffset = originalFrom - fromContentStart;
|
|
30
|
+
var toOffset = originalTo - toContentStart;
|
|
31
|
+
var clamp = function clamp(pos) {
|
|
32
|
+
return Math.min(Math.max(0, pos), docSize);
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
from: clamp(rootListStart + contentStartOffsets[startIndex] + fromOffset),
|
|
36
|
+
to: clamp(rootListStart + contentStartOffsets[endIndex] + toOffset)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Restore the transaction's selection after a list structural change
|
|
42
|
+
* (indent/outdent of list items or task list items).
|
|
43
|
+
*
|
|
44
|
+
* Uses the content start offsets computed during fragment rebuild to
|
|
45
|
+
* map each selection endpoint to its new absolute position.
|
|
46
|
+
*
|
|
47
|
+
* Handles NodeSelection, GapCursorSelection, and TextSelection.
|
|
48
|
+
*/
|
|
49
|
+
function restoreSelection(_ref2) {
|
|
50
|
+
var tr = _ref2.tr,
|
|
51
|
+
originalSelection = _ref2.originalSelection,
|
|
52
|
+
from = _ref2.from,
|
|
53
|
+
to = _ref2.to;
|
|
54
|
+
var maxPos = tr.doc.content.size;
|
|
55
|
+
if (originalSelection instanceof _state.NodeSelection) {
|
|
56
|
+
try {
|
|
57
|
+
tr.setSelection(_state.NodeSelection.create(tr.doc, Math.min(from, maxPos - 1)));
|
|
58
|
+
} catch (_unused) {
|
|
59
|
+
tr.setSelection(_state.Selection.near(tr.doc.resolve(from)));
|
|
60
|
+
}
|
|
61
|
+
} else if (originalSelection instanceof _selection.GapCursorSelection) {
|
|
62
|
+
tr.setSelection(new _selection.GapCursorSelection(tr.doc.resolve(from), originalSelection.side));
|
|
63
|
+
} else {
|
|
64
|
+
tr.setSelection(_state.TextSelection.create(tr.doc, from, to));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
19
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
20
20
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
21
21
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
22
|
-
var packageVersion = "
|
|
22
|
+
var packageVersion = "0.0.0-development";
|
|
23
23
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
24
24
|
// Remove URL as it has UGC
|
|
25
25
|
// Ignored via go/ees007
|
|
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
24
24
|
* @jsx jsx
|
|
25
25
|
*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
26
26
|
var packageName = "@atlaskit/editor-common";
|
|
27
|
-
var packageVersion = "
|
|
27
|
+
var packageVersion = "0.0.0-development";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
|
|
3
|
+
/** Rebuilds a list-like PM node from a flat array of items. */
|
|
4
|
+
|
|
5
|
+
/** Extracts top-level content nodes from an item being broken out past the root list. */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Build a replacement Fragment from a flat array of items.
|
|
9
|
+
*
|
|
10
|
+
* Items with depth >= 0 are grouped and rebuilt via `rebuildFn`.
|
|
11
|
+
* Items with depth < 0 are extracted via `extractContentFn`.
|
|
12
|
+
*/
|
|
13
|
+
export function buildReplacementFragment({
|
|
14
|
+
items,
|
|
15
|
+
schema,
|
|
16
|
+
rebuildFn,
|
|
17
|
+
extractContentFn
|
|
18
|
+
}) {
|
|
19
|
+
let fragment = Fragment.empty;
|
|
20
|
+
let pendingListSegment = [];
|
|
21
|
+
let pendingStartIdx = 0;
|
|
22
|
+
const contentStartOffsets = new Array(items.length);
|
|
23
|
+
const flushListSegment = () => {
|
|
24
|
+
if (pendingListSegment.length > 0) {
|
|
25
|
+
const fragmentOffset = fragment.size;
|
|
26
|
+
const result = rebuildFn(pendingListSegment, schema);
|
|
27
|
+
if (result) {
|
|
28
|
+
// Map the rebuild's content start offsets into the overall fragment.
|
|
29
|
+
for (let i = 0; i < pendingListSegment.length; i++) {
|
|
30
|
+
contentStartOffsets[pendingStartIdx + i] = fragmentOffset + result.contentStartOffsets[i];
|
|
31
|
+
}
|
|
32
|
+
fragment = fragment.addToEnd(result.node);
|
|
33
|
+
}
|
|
34
|
+
pendingListSegment = [];
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
let elIdx = 0;
|
|
38
|
+
for (const item of items) {
|
|
39
|
+
if (item.depth < 0) {
|
|
40
|
+
flushListSegment();
|
|
41
|
+
// Extracted element — content children become top-level nodes.
|
|
42
|
+
// Record offset of first content child.
|
|
43
|
+
contentStartOffsets[elIdx] = fragment.size;
|
|
44
|
+
for (const node of extractContentFn(item, schema)) {
|
|
45
|
+
fragment = fragment.addToEnd(node);
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
if (pendingListSegment.length === 0) {
|
|
49
|
+
pendingStartIdx = elIdx;
|
|
50
|
+
}
|
|
51
|
+
pendingListSegment.push(item);
|
|
52
|
+
}
|
|
53
|
+
elIdx++;
|
|
54
|
+
}
|
|
55
|
+
flushListSegment();
|
|
56
|
+
return {
|
|
57
|
+
fragment,
|
|
58
|
+
contentStartOffsets
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-specific predicates that vary between regular lists and task lists.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flattens a list-like PM structure (regular list or task list) into an
|
|
7
|
+
* array of content-bearing items with computed depths.
|
|
8
|
+
*
|
|
9
|
+
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
|
|
10
|
+
* decisions to the provided predicates. The core algorithm — selection
|
|
11
|
+
* intersection, depth adjustment, index tracking — is shared.
|
|
12
|
+
*/
|
|
13
|
+
export function flattenList(options, predicates) {
|
|
14
|
+
const {
|
|
15
|
+
doc,
|
|
16
|
+
rootListStart,
|
|
17
|
+
rootListEnd,
|
|
18
|
+
selectionFrom,
|
|
19
|
+
selectionTo,
|
|
20
|
+
indentDelta,
|
|
21
|
+
maxDepth
|
|
22
|
+
} = options;
|
|
23
|
+
const {
|
|
24
|
+
isContentNode,
|
|
25
|
+
getSelectionBounds,
|
|
26
|
+
getDepth
|
|
27
|
+
} = predicates;
|
|
28
|
+
const items = [];
|
|
29
|
+
let startIndex = -1;
|
|
30
|
+
let endIndex = -1;
|
|
31
|
+
let exceedsMaxDepth = false;
|
|
32
|
+
const rootDepth = doc.resolve(rootListStart).depth;
|
|
33
|
+
doc.nodesBetween(rootListStart, rootListEnd, (node, pos, parent) => {
|
|
34
|
+
if (!isContentNode(node, parent) || parent == null) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
const {
|
|
38
|
+
start,
|
|
39
|
+
end
|
|
40
|
+
} = getSelectionBounds(node, pos);
|
|
41
|
+
const isSelected = selectionFrom === selectionTo ? selectionFrom >= start && selectionFrom <= end : start < selectionTo && end > selectionFrom;
|
|
42
|
+
const resolvedDepth = doc.resolve(pos).depth;
|
|
43
|
+
const depth = getDepth(resolvedDepth, rootDepth) + (isSelected ? indentDelta : 0);
|
|
44
|
+
items.push({
|
|
45
|
+
node,
|
|
46
|
+
pos,
|
|
47
|
+
depth,
|
|
48
|
+
isSelected,
|
|
49
|
+
listType: parent.type.name,
|
|
50
|
+
parentListAttrs: parent.attrs
|
|
51
|
+
});
|
|
52
|
+
if (isSelected) {
|
|
53
|
+
const index = items.length - 1;
|
|
54
|
+
if (startIndex === -1) {
|
|
55
|
+
startIndex = index;
|
|
56
|
+
}
|
|
57
|
+
endIndex = index;
|
|
58
|
+
if (maxDepth != null && depth >= maxDepth) {
|
|
59
|
+
exceedsMaxDepth = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
});
|
|
64
|
+
if (items.length === 0 || startIndex === -1 || exceedsMaxDepth) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
items,
|
|
69
|
+
startIndex,
|
|
70
|
+
endIndex
|
|
71
|
+
};
|
|
72
|
+
}
|
|
@@ -6,5 +6,8 @@ export { moveTargetIntoList } from './replace-content';
|
|
|
6
6
|
export { JoinDirection, isListNodeValidContent, joinSiblingLists, processNestedTaskListsInSameLevel } from './node';
|
|
7
7
|
export { getCommonListAnalyticsAttributes, countListItemsInSelection } from './analytics';
|
|
8
8
|
export { hasValidListIndentationLevel } from './indentation';
|
|
9
|
+
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
10
|
+
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
11
|
+
export { flattenList } from './flatten-list';
|
|
9
12
|
export { isListNode, isListItemNode, isBulletList, isParagraphNode } from '../utils';
|
|
10
13
|
export { messages } from './messages';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { GapCursorSelection } from '../selection';
|
|
3
|
+
/**
|
|
4
|
+
* Compute the new selection offsets after list items have been moved/indented/outdented.
|
|
5
|
+
*
|
|
6
|
+
* Uses the content start offsets computed during fragment rebuild to map each
|
|
7
|
+
* selection endpoint to its new absolute position, accounting for the change
|
|
8
|
+
* in the list structure.
|
|
9
|
+
*/
|
|
10
|
+
export function computeSelectionOffsets({
|
|
11
|
+
items,
|
|
12
|
+
startIndex,
|
|
13
|
+
endIndex,
|
|
14
|
+
originalFrom,
|
|
15
|
+
originalTo,
|
|
16
|
+
contentStartOffsets,
|
|
17
|
+
rootListStart,
|
|
18
|
+
docSize
|
|
19
|
+
}) {
|
|
20
|
+
// +1 shifts from the outer edge of the list item node to the start of the content within
|
|
21
|
+
const fromContentStart = items[startIndex].pos + 1;
|
|
22
|
+
const toContentStart = items[endIndex].pos + 1;
|
|
23
|
+
const fromOffset = originalFrom - fromContentStart;
|
|
24
|
+
const toOffset = originalTo - toContentStart;
|
|
25
|
+
const clamp = pos => Math.min(Math.max(0, pos), docSize);
|
|
26
|
+
return {
|
|
27
|
+
from: clamp(rootListStart + contentStartOffsets[startIndex] + fromOffset),
|
|
28
|
+
to: clamp(rootListStart + contentStartOffsets[endIndex] + toOffset)
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Restore the transaction's selection after a list structural change
|
|
34
|
+
* (indent/outdent of list items or task list items).
|
|
35
|
+
*
|
|
36
|
+
* Uses the content start offsets computed during fragment rebuild to
|
|
37
|
+
* map each selection endpoint to its new absolute position.
|
|
38
|
+
*
|
|
39
|
+
* Handles NodeSelection, GapCursorSelection, and TextSelection.
|
|
40
|
+
*/
|
|
41
|
+
export function restoreSelection({
|
|
42
|
+
tr,
|
|
43
|
+
originalSelection,
|
|
44
|
+
from,
|
|
45
|
+
to
|
|
46
|
+
}) {
|
|
47
|
+
const maxPos = tr.doc.content.size;
|
|
48
|
+
if (originalSelection instanceof NodeSelection) {
|
|
49
|
+
try {
|
|
50
|
+
tr.setSelection(NodeSelection.create(tr.doc, Math.min(from, maxPos - 1)));
|
|
51
|
+
} catch {
|
|
52
|
+
tr.setSelection(Selection.near(tr.doc.resolve(from)));
|
|
53
|
+
}
|
|
54
|
+
} else if (originalSelection instanceof GapCursorSelection) {
|
|
55
|
+
tr.setSelection(new GapCursorSelection(tr.doc.resolve(from), originalSelection.side));
|
|
56
|
+
} else {
|
|
57
|
+
tr.setSelection(TextSelection.create(tr.doc, from, to));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -4,7 +4,7 @@ import { isFedRamp } from './environment';
|
|
|
4
4
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
5
5
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
6
6
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
7
|
-
const packageVersion = "
|
|
7
|
+
const packageVersion = "0.0.0-development";
|
|
8
8
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
9
9
|
// Remove URL as it has UGC
|
|
10
10
|
// Ignored via go/ees007
|
|
@@ -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 = "
|
|
17
|
+
const packageVersion = "0.0.0-development";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
2
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
3
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
4
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
5
|
+
|
|
6
|
+
/** Rebuilds a list-like PM node from a flat array of items. */
|
|
7
|
+
|
|
8
|
+
/** Extracts top-level content nodes from an item being broken out past the root list. */
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build a replacement Fragment from a flat array of items.
|
|
12
|
+
*
|
|
13
|
+
* Items with depth >= 0 are grouped and rebuilt via `rebuildFn`.
|
|
14
|
+
* Items with depth < 0 are extracted via `extractContentFn`.
|
|
15
|
+
*/
|
|
16
|
+
export function buildReplacementFragment(_ref) {
|
|
17
|
+
var items = _ref.items,
|
|
18
|
+
schema = _ref.schema,
|
|
19
|
+
rebuildFn = _ref.rebuildFn,
|
|
20
|
+
extractContentFn = _ref.extractContentFn;
|
|
21
|
+
var fragment = Fragment.empty;
|
|
22
|
+
var pendingListSegment = [];
|
|
23
|
+
var pendingStartIdx = 0;
|
|
24
|
+
var contentStartOffsets = new Array(items.length);
|
|
25
|
+
var flushListSegment = function flushListSegment() {
|
|
26
|
+
if (pendingListSegment.length > 0) {
|
|
27
|
+
var fragmentOffset = fragment.size;
|
|
28
|
+
var result = rebuildFn(pendingListSegment, schema);
|
|
29
|
+
if (result) {
|
|
30
|
+
// Map the rebuild's content start offsets into the overall fragment.
|
|
31
|
+
for (var i = 0; i < pendingListSegment.length; i++) {
|
|
32
|
+
contentStartOffsets[pendingStartIdx + i] = fragmentOffset + result.contentStartOffsets[i];
|
|
33
|
+
}
|
|
34
|
+
fragment = fragment.addToEnd(result.node);
|
|
35
|
+
}
|
|
36
|
+
pendingListSegment = [];
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var elIdx = 0;
|
|
40
|
+
var _iterator = _createForOfIteratorHelper(items),
|
|
41
|
+
_step;
|
|
42
|
+
try {
|
|
43
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
44
|
+
var _item = _step.value;
|
|
45
|
+
if (_item.depth < 0) {
|
|
46
|
+
flushListSegment();
|
|
47
|
+
// Extracted element — content children become top-level nodes.
|
|
48
|
+
// Record offset of first content child.
|
|
49
|
+
contentStartOffsets[elIdx] = fragment.size;
|
|
50
|
+
var _iterator2 = _createForOfIteratorHelper(extractContentFn(_item, schema)),
|
|
51
|
+
_step2;
|
|
52
|
+
try {
|
|
53
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
54
|
+
var node = _step2.value;
|
|
55
|
+
fragment = fragment.addToEnd(node);
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
_iterator2.e(err);
|
|
59
|
+
} finally {
|
|
60
|
+
_iterator2.f();
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
if (pendingListSegment.length === 0) {
|
|
64
|
+
pendingStartIdx = elIdx;
|
|
65
|
+
}
|
|
66
|
+
pendingListSegment.push(_item);
|
|
67
|
+
}
|
|
68
|
+
elIdx++;
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
_iterator.e(err);
|
|
72
|
+
} finally {
|
|
73
|
+
_iterator.f();
|
|
74
|
+
}
|
|
75
|
+
flushListSegment();
|
|
76
|
+
return {
|
|
77
|
+
fragment: fragment,
|
|
78
|
+
contentStartOffsets: contentStartOffsets
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-specific predicates that vary between regular lists and task lists.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flattens a list-like PM structure (regular list or task list) into an
|
|
7
|
+
* array of content-bearing items with computed depths.
|
|
8
|
+
*
|
|
9
|
+
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
|
|
10
|
+
* decisions to the provided predicates. The core algorithm — selection
|
|
11
|
+
* intersection, depth adjustment, index tracking — is shared.
|
|
12
|
+
*/
|
|
13
|
+
export function flattenList(options, predicates) {
|
|
14
|
+
var doc = options.doc,
|
|
15
|
+
rootListStart = options.rootListStart,
|
|
16
|
+
rootListEnd = options.rootListEnd,
|
|
17
|
+
selectionFrom = options.selectionFrom,
|
|
18
|
+
selectionTo = options.selectionTo,
|
|
19
|
+
indentDelta = options.indentDelta,
|
|
20
|
+
maxDepth = options.maxDepth;
|
|
21
|
+
var isContentNode = predicates.isContentNode,
|
|
22
|
+
getSelectionBounds = predicates.getSelectionBounds,
|
|
23
|
+
getDepth = predicates.getDepth;
|
|
24
|
+
var items = [];
|
|
25
|
+
var startIndex = -1;
|
|
26
|
+
var endIndex = -1;
|
|
27
|
+
var exceedsMaxDepth = false;
|
|
28
|
+
var rootDepth = doc.resolve(rootListStart).depth;
|
|
29
|
+
doc.nodesBetween(rootListStart, rootListEnd, function (node, pos, parent) {
|
|
30
|
+
if (!isContentNode(node, parent) || parent == null) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
var _getSelectionBounds = getSelectionBounds(node, pos),
|
|
34
|
+
start = _getSelectionBounds.start,
|
|
35
|
+
end = _getSelectionBounds.end;
|
|
36
|
+
var isSelected = selectionFrom === selectionTo ? selectionFrom >= start && selectionFrom <= end : start < selectionTo && end > selectionFrom;
|
|
37
|
+
var resolvedDepth = doc.resolve(pos).depth;
|
|
38
|
+
var depth = getDepth(resolvedDepth, rootDepth) + (isSelected ? indentDelta : 0);
|
|
39
|
+
items.push({
|
|
40
|
+
node: node,
|
|
41
|
+
pos: pos,
|
|
42
|
+
depth: depth,
|
|
43
|
+
isSelected: isSelected,
|
|
44
|
+
listType: parent.type.name,
|
|
45
|
+
parentListAttrs: parent.attrs
|
|
46
|
+
});
|
|
47
|
+
if (isSelected) {
|
|
48
|
+
var index = items.length - 1;
|
|
49
|
+
if (startIndex === -1) {
|
|
50
|
+
startIndex = index;
|
|
51
|
+
}
|
|
52
|
+
endIndex = index;
|
|
53
|
+
if (maxDepth != null && depth >= maxDepth) {
|
|
54
|
+
exceedsMaxDepth = true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
if (items.length === 0 || startIndex === -1 || exceedsMaxDepth) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
items: items,
|
|
64
|
+
startIndex: startIndex,
|
|
65
|
+
endIndex: endIndex
|
|
66
|
+
};
|
|
67
|
+
}
|
package/dist/esm/lists/index.js
CHANGED
|
@@ -6,5 +6,8 @@ export { moveTargetIntoList } from './replace-content';
|
|
|
6
6
|
export { JoinDirection, isListNodeValidContent, joinSiblingLists, processNestedTaskListsInSameLevel } from './node';
|
|
7
7
|
export { getCommonListAnalyticsAttributes, countListItemsInSelection } from './analytics';
|
|
8
8
|
export { hasValidListIndentationLevel } from './indentation';
|
|
9
|
+
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
10
|
+
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
11
|
+
export { flattenList } from './flatten-list';
|
|
9
12
|
export { isListNode, isListItemNode, isBulletList, isParagraphNode } from '../utils';
|
|
10
13
|
export { messages } from './messages';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { GapCursorSelection } from '../selection';
|
|
3
|
+
/**
|
|
4
|
+
* Compute the new selection offsets after list items have been moved/indented/outdented.
|
|
5
|
+
*
|
|
6
|
+
* Uses the content start offsets computed during fragment rebuild to map each
|
|
7
|
+
* selection endpoint to its new absolute position, accounting for the change
|
|
8
|
+
* in the list structure.
|
|
9
|
+
*/
|
|
10
|
+
export function computeSelectionOffsets(_ref) {
|
|
11
|
+
var items = _ref.items,
|
|
12
|
+
startIndex = _ref.startIndex,
|
|
13
|
+
endIndex = _ref.endIndex,
|
|
14
|
+
originalFrom = _ref.originalFrom,
|
|
15
|
+
originalTo = _ref.originalTo,
|
|
16
|
+
contentStartOffsets = _ref.contentStartOffsets,
|
|
17
|
+
rootListStart = _ref.rootListStart,
|
|
18
|
+
docSize = _ref.docSize;
|
|
19
|
+
// +1 shifts from the outer edge of the list item node to the start of the content within
|
|
20
|
+
var fromContentStart = items[startIndex].pos + 1;
|
|
21
|
+
var toContentStart = items[endIndex].pos + 1;
|
|
22
|
+
var fromOffset = originalFrom - fromContentStart;
|
|
23
|
+
var toOffset = originalTo - toContentStart;
|
|
24
|
+
var clamp = function clamp(pos) {
|
|
25
|
+
return Math.min(Math.max(0, pos), docSize);
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
from: clamp(rootListStart + contentStartOffsets[startIndex] + fromOffset),
|
|
29
|
+
to: clamp(rootListStart + contentStartOffsets[endIndex] + toOffset)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Restore the transaction's selection after a list structural change
|
|
35
|
+
* (indent/outdent of list items or task list items).
|
|
36
|
+
*
|
|
37
|
+
* Uses the content start offsets computed during fragment rebuild to
|
|
38
|
+
* map each selection endpoint to its new absolute position.
|
|
39
|
+
*
|
|
40
|
+
* Handles NodeSelection, GapCursorSelection, and TextSelection.
|
|
41
|
+
*/
|
|
42
|
+
export function restoreSelection(_ref2) {
|
|
43
|
+
var tr = _ref2.tr,
|
|
44
|
+
originalSelection = _ref2.originalSelection,
|
|
45
|
+
from = _ref2.from,
|
|
46
|
+
to = _ref2.to;
|
|
47
|
+
var maxPos = tr.doc.content.size;
|
|
48
|
+
if (originalSelection instanceof NodeSelection) {
|
|
49
|
+
try {
|
|
50
|
+
tr.setSelection(NodeSelection.create(tr.doc, Math.min(from, maxPos - 1)));
|
|
51
|
+
} catch (_unused) {
|
|
52
|
+
tr.setSelection(Selection.near(tr.doc.resolve(from)));
|
|
53
|
+
}
|
|
54
|
+
} else if (originalSelection instanceof GapCursorSelection) {
|
|
55
|
+
tr.setSelection(new GapCursorSelection(tr.doc.resolve(from), originalSelection.side));
|
|
56
|
+
} else {
|
|
57
|
+
tr.setSelection(TextSelection.create(tr.doc, from, to));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -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 = "
|
|
13
|
+
var packageVersion = "0.0.0-development";
|
|
14
14
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
15
15
|
// Remove URL as it has UGC
|
|
16
16
|
// Ignored via go/ees007
|
|
@@ -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 = "
|
|
24
|
+
var packageVersion = "0.0.0-development";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { FlattenedItem } from './flatten-list';
|
|
4
|
+
export interface BuildResult {
|
|
5
|
+
/**
|
|
6
|
+
* For each element (by index), the offset within the fragment where the
|
|
7
|
+
* element's content begins.
|
|
8
|
+
*
|
|
9
|
+
* To get the absolute document position after `tr.replaceWith(rangeStart, …)`,
|
|
10
|
+
* add `rangeStart` to the offset.
|
|
11
|
+
*/
|
|
12
|
+
contentStartOffsets: number[];
|
|
13
|
+
fragment: Fragment;
|
|
14
|
+
}
|
|
15
|
+
/** Rebuilds a list-like PM node from a flat array of items. */
|
|
16
|
+
type RebuildFn = (items: FlattenedItem[], schema: Schema) => {
|
|
17
|
+
contentStartOffsets: number[];
|
|
18
|
+
node: PMNode;
|
|
19
|
+
} | null;
|
|
20
|
+
/** Extracts top-level content nodes from an item being broken out past the root list. */
|
|
21
|
+
type ExtractContentFn = (item: FlattenedItem, schema: Schema) => PMNode[];
|
|
22
|
+
interface BuildReplacementFragmentOptions {
|
|
23
|
+
extractContentFn: ExtractContentFn;
|
|
24
|
+
items: FlattenedItem[];
|
|
25
|
+
rebuildFn: RebuildFn;
|
|
26
|
+
schema: Schema;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a replacement Fragment from a flat array of items.
|
|
30
|
+
*
|
|
31
|
+
* Items with depth >= 0 are grouped and rebuilt via `rebuildFn`.
|
|
32
|
+
* Items with depth < 0 are extracted via `extractContentFn`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildReplacementFragment({ items, schema, rebuildFn, extractContentFn, }: BuildReplacementFragmentOptions): BuildResult;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Attrs, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
export interface FlattenedItem {
|
|
3
|
+
depth: number;
|
|
4
|
+
isSelected: boolean;
|
|
5
|
+
listType: string;
|
|
6
|
+
node: PMNode;
|
|
7
|
+
parentListAttrs: Attrs | null;
|
|
8
|
+
pos: number;
|
|
9
|
+
}
|
|
10
|
+
export interface FlattenListOptions {
|
|
11
|
+
doc: PMNode;
|
|
12
|
+
indentDelta: number;
|
|
13
|
+
maxDepth?: number;
|
|
14
|
+
rootListStart: number;
|
|
15
|
+
rootListEnd: number;
|
|
16
|
+
selectionFrom: number;
|
|
17
|
+
selectionTo: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Type-specific predicates that vary between regular lists and task lists.
|
|
21
|
+
*/
|
|
22
|
+
interface FlattenListPredicates {
|
|
23
|
+
/** Returns true if `node` is a content-bearing item to include in the flattened output. */
|
|
24
|
+
isContentNode: (node: PMNode, parent: PMNode | null) => boolean;
|
|
25
|
+
/** Returns the selection bounds for an item, used to check selection intersection. */
|
|
26
|
+
getSelectionBounds: (node: PMNode, pos: number) => {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
};
|
|
30
|
+
/** Computes the nesting depth for a node given its resolved depth and the root's depth. */
|
|
31
|
+
getDepth: (resolvedDepth: number, rootDepth: number) => number;
|
|
32
|
+
}
|
|
33
|
+
export interface FlattenListResult {
|
|
34
|
+
items: FlattenedItem[];
|
|
35
|
+
startIndex: number;
|
|
36
|
+
endIndex: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Flattens a list-like PM structure (regular list or task list) into an
|
|
40
|
+
* array of content-bearing items with computed depths.
|
|
41
|
+
*
|
|
42
|
+
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
|
|
43
|
+
* decisions to the provided predicates. The core algorithm — selection
|
|
44
|
+
* intersection, depth adjustment, index tracking — is shared.
|
|
45
|
+
*/
|
|
46
|
+
export declare function flattenList(options: FlattenListOptions, predicates: FlattenListPredicates): FlattenListResult | null;
|
|
47
|
+
export {};
|
|
@@ -3,5 +3,11 @@ export { moveTargetIntoList } from './replace-content';
|
|
|
3
3
|
export { JoinDirection, isListNodeValidContent, joinSiblingLists, processNestedTaskListsInSameLevel, } from './node';
|
|
4
4
|
export { getCommonListAnalyticsAttributes, countListItemsInSelection } from './analytics';
|
|
5
5
|
export { hasValidListIndentationLevel } from './indentation';
|
|
6
|
+
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
7
|
+
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
8
|
+
export type { BuildResult } from './build-replacement-fragment';
|
|
9
|
+
export type { FlattenedItem } from './flatten-list';
|
|
10
|
+
export { flattenList } from './flatten-list';
|
|
11
|
+
export type { FlattenListOptions, FlattenListResult } from './flatten-list';
|
|
6
12
|
export { isListNode, isListItemNode, isBulletList, isParagraphNode } from '../utils';
|
|
7
13
|
export { messages } from './messages';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { FlattenedItem } from './flatten-list';
|
|
4
|
+
interface ComputeSelectionOffsetsOptions {
|
|
5
|
+
contentStartOffsets: number[];
|
|
6
|
+
docSize: number;
|
|
7
|
+
endIndex: number;
|
|
8
|
+
items: FlattenedItem[];
|
|
9
|
+
originalFrom: number;
|
|
10
|
+
originalTo: number;
|
|
11
|
+
rootListStart: number;
|
|
12
|
+
startIndex: number;
|
|
13
|
+
}
|
|
14
|
+
interface RestoreSelectionOptions {
|
|
15
|
+
from: number;
|
|
16
|
+
originalSelection: Selection;
|
|
17
|
+
to: number;
|
|
18
|
+
tr: Transaction;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compute the new selection offsets after list items have been moved/indented/outdented.
|
|
22
|
+
*
|
|
23
|
+
* Uses the content start offsets computed during fragment rebuild to map each
|
|
24
|
+
* selection endpoint to its new absolute position, accounting for the change
|
|
25
|
+
* in the list structure.
|
|
26
|
+
*/
|
|
27
|
+
export declare function computeSelectionOffsets({ items, startIndex, endIndex, originalFrom, originalTo, contentStartOffsets, rootListStart, docSize, }: ComputeSelectionOffsetsOptions): {
|
|
28
|
+
from: number;
|
|
29
|
+
to: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Restore the transaction's selection after a list structural change
|
|
33
|
+
* (indent/outdent of list items or task list items).
|
|
34
|
+
*
|
|
35
|
+
* Uses the content start offsets computed during fragment rebuild to
|
|
36
|
+
* map each selection endpoint to its new absolute position.
|
|
37
|
+
*
|
|
38
|
+
* Handles NodeSelection, GapCursorSelection, and TextSelection.
|
|
39
|
+
*/
|
|
40
|
+
export declare function restoreSelection({ tr, originalSelection, from, to, }: RestoreSelectionOptions): void;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Node as PMNode, Schema } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { FlattenedItem } from './flatten-list';
|
|
4
|
+
export interface BuildResult {
|
|
5
|
+
/**
|
|
6
|
+
* For each element (by index), the offset within the fragment where the
|
|
7
|
+
* element's content begins.
|
|
8
|
+
*
|
|
9
|
+
* To get the absolute document position after `tr.replaceWith(rangeStart, …)`,
|
|
10
|
+
* add `rangeStart` to the offset.
|
|
11
|
+
*/
|
|
12
|
+
contentStartOffsets: number[];
|
|
13
|
+
fragment: Fragment;
|
|
14
|
+
}
|
|
15
|
+
/** Rebuilds a list-like PM node from a flat array of items. */
|
|
16
|
+
type RebuildFn = (items: FlattenedItem[], schema: Schema) => {
|
|
17
|
+
contentStartOffsets: number[];
|
|
18
|
+
node: PMNode;
|
|
19
|
+
} | null;
|
|
20
|
+
/** Extracts top-level content nodes from an item being broken out past the root list. */
|
|
21
|
+
type ExtractContentFn = (item: FlattenedItem, schema: Schema) => PMNode[];
|
|
22
|
+
interface BuildReplacementFragmentOptions {
|
|
23
|
+
extractContentFn: ExtractContentFn;
|
|
24
|
+
items: FlattenedItem[];
|
|
25
|
+
rebuildFn: RebuildFn;
|
|
26
|
+
schema: Schema;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build a replacement Fragment from a flat array of items.
|
|
30
|
+
*
|
|
31
|
+
* Items with depth >= 0 are grouped and rebuilt via `rebuildFn`.
|
|
32
|
+
* Items with depth < 0 are extracted via `extractContentFn`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildReplacementFragment({ items, schema, rebuildFn, extractContentFn, }: BuildReplacementFragmentOptions): BuildResult;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Attrs, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
export interface FlattenedItem {
|
|
3
|
+
depth: number;
|
|
4
|
+
isSelected: boolean;
|
|
5
|
+
listType: string;
|
|
6
|
+
node: PMNode;
|
|
7
|
+
parentListAttrs: Attrs | null;
|
|
8
|
+
pos: number;
|
|
9
|
+
}
|
|
10
|
+
export interface FlattenListOptions {
|
|
11
|
+
doc: PMNode;
|
|
12
|
+
indentDelta: number;
|
|
13
|
+
maxDepth?: number;
|
|
14
|
+
rootListStart: number;
|
|
15
|
+
rootListEnd: number;
|
|
16
|
+
selectionFrom: number;
|
|
17
|
+
selectionTo: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Type-specific predicates that vary between regular lists and task lists.
|
|
21
|
+
*/
|
|
22
|
+
interface FlattenListPredicates {
|
|
23
|
+
/** Returns true if `node` is a content-bearing item to include in the flattened output. */
|
|
24
|
+
isContentNode: (node: PMNode, parent: PMNode | null) => boolean;
|
|
25
|
+
/** Returns the selection bounds for an item, used to check selection intersection. */
|
|
26
|
+
getSelectionBounds: (node: PMNode, pos: number) => {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
};
|
|
30
|
+
/** Computes the nesting depth for a node given its resolved depth and the root's depth. */
|
|
31
|
+
getDepth: (resolvedDepth: number, rootDepth: number) => number;
|
|
32
|
+
}
|
|
33
|
+
export interface FlattenListResult {
|
|
34
|
+
items: FlattenedItem[];
|
|
35
|
+
startIndex: number;
|
|
36
|
+
endIndex: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Flattens a list-like PM structure (regular list or task list) into an
|
|
40
|
+
* array of content-bearing items with computed depths.
|
|
41
|
+
*
|
|
42
|
+
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
|
|
43
|
+
* decisions to the provided predicates. The core algorithm — selection
|
|
44
|
+
* intersection, depth adjustment, index tracking — is shared.
|
|
45
|
+
*/
|
|
46
|
+
export declare function flattenList(options: FlattenListOptions, predicates: FlattenListPredicates): FlattenListResult | null;
|
|
47
|
+
export {};
|
|
@@ -3,5 +3,11 @@ export { moveTargetIntoList } from './replace-content';
|
|
|
3
3
|
export { JoinDirection, isListNodeValidContent, joinSiblingLists, processNestedTaskListsInSameLevel, } from './node';
|
|
4
4
|
export { getCommonListAnalyticsAttributes, countListItemsInSelection } from './analytics';
|
|
5
5
|
export { hasValidListIndentationLevel } from './indentation';
|
|
6
|
+
export { restoreSelection, computeSelectionOffsets } from './restore-selection';
|
|
7
|
+
export { buildReplacementFragment } from './build-replacement-fragment';
|
|
8
|
+
export type { BuildResult } from './build-replacement-fragment';
|
|
9
|
+
export type { FlattenedItem } from './flatten-list';
|
|
10
|
+
export { flattenList } from './flatten-list';
|
|
11
|
+
export type { FlattenListOptions, FlattenListResult } from './flatten-list';
|
|
6
12
|
export { isListNode, isListItemNode, isBulletList, isParagraphNode } from '../utils';
|
|
7
13
|
export { messages } from './messages';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
3
|
+
import type { FlattenedItem } from './flatten-list';
|
|
4
|
+
interface ComputeSelectionOffsetsOptions {
|
|
5
|
+
contentStartOffsets: number[];
|
|
6
|
+
docSize: number;
|
|
7
|
+
endIndex: number;
|
|
8
|
+
items: FlattenedItem[];
|
|
9
|
+
originalFrom: number;
|
|
10
|
+
originalTo: number;
|
|
11
|
+
rootListStart: number;
|
|
12
|
+
startIndex: number;
|
|
13
|
+
}
|
|
14
|
+
interface RestoreSelectionOptions {
|
|
15
|
+
from: number;
|
|
16
|
+
originalSelection: Selection;
|
|
17
|
+
to: number;
|
|
18
|
+
tr: Transaction;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Compute the new selection offsets after list items have been moved/indented/outdented.
|
|
22
|
+
*
|
|
23
|
+
* Uses the content start offsets computed during fragment rebuild to map each
|
|
24
|
+
* selection endpoint to its new absolute position, accounting for the change
|
|
25
|
+
* in the list structure.
|
|
26
|
+
*/
|
|
27
|
+
export declare function computeSelectionOffsets({ items, startIndex, endIndex, originalFrom, originalTo, contentStartOffsets, rootListStart, docSize, }: ComputeSelectionOffsetsOptions): {
|
|
28
|
+
from: number;
|
|
29
|
+
to: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Restore the transaction's selection after a list structural change
|
|
33
|
+
* (indent/outdent of list items or task list items).
|
|
34
|
+
*
|
|
35
|
+
* Uses the content start offsets computed during fragment rebuild to
|
|
36
|
+
* map each selection endpoint to its new absolute position.
|
|
37
|
+
*
|
|
38
|
+
* Handles NodeSelection, GapCursorSelection, and TextSelection.
|
|
39
|
+
*/
|
|
40
|
+
export declare function restoreSelection({ tr, originalSelection, from, to, }: RestoreSelectionOptions): void;
|
|
41
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-common",
|
|
3
|
-
"version": "112.
|
|
3
|
+
"version": "112.8.0",
|
|
4
4
|
"description": "A package that contains common classes and components for editor and renderer",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@atlaskit/status": "^3.1.0",
|
|
82
82
|
"@atlaskit/task-decision": "^19.3.0",
|
|
83
83
|
"@atlaskit/textfield": "^8.2.0",
|
|
84
|
-
"@atlaskit/tmp-editor-statsig": "^44.
|
|
84
|
+
"@atlaskit/tmp-editor-statsig": "^44.1.0",
|
|
85
85
|
"@atlaskit/tokens": "^11.1.0",
|
|
86
86
|
"@atlaskit/tooltip": "^21.0.0",
|
|
87
87
|
"@atlaskit/width-detector": "^5.0.0",
|