@atlaskit/editor-common 122.5.0 → 122.6.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 +35 -0
- package/collab-agent-edit-changed-ranges/package.json +10 -0
- package/dist/cjs/collab/agent-edit-changed-ranges.js +304 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/transforms/getFormattedNode.js +1 -5
- package/dist/cjs/transforms/list-transforms.js +2 -8
- package/dist/cjs/transforms/transformTaskListToBlockNodes.js +1 -5
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/es2019/collab/agent-edit-changed-ranges.js +255 -0
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/transforms/getFormattedNode.js +1 -5
- package/dist/es2019/transforms/list-transforms.js +2 -8
- package/dist/es2019/transforms/transformTaskListToBlockNodes.js +1 -5
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/esm/collab/agent-edit-changed-ranges.js +297 -0
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/transforms/getFormattedNode.js +1 -5
- package/dist/esm/transforms/list-transforms.js +2 -8
- package/dist/esm/transforms/transformTaskListToBlockNodes.js +1 -5
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/types/collab/agent-edit-changed-ranges.d.ts +12 -0
- package/dist/types/provider-factory/profile-card-provider.d.ts +5 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 122.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`b9d1af39046dc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b9d1af39046dc) -
|
|
8
|
+
Add a shared applied-step range detector for AI activity. Connect local streaming under
|
|
9
|
+
platform_editor_ai_streaming_ux_experience_m1 and incoming agent edits under the existing backend
|
|
10
|
+
streaming rollout to this detector. Refine shared chrome highlights to affected nested textblock
|
|
11
|
+
content for all existing shared-chrome consumers.
|
|
12
|
+
|
|
13
|
+
Preserve node attribute activity through cumulative replacements that retain its markup while
|
|
14
|
+
changing descendant content. Reuse existing highlight styles and the grouped cursor.
|
|
15
|
+
|
|
16
|
+
Expose a transaction-only AI activity action and connect direct orchestrator attribute, move, wrap
|
|
17
|
+
and remove mutations under platform_editor_ai_streaming_ux_experience_m1. Keep review segments and
|
|
18
|
+
existing streaming cadence unchanged.
|
|
19
|
+
|
|
20
|
+
Reuse lazily built node-identity indexes per transaction snapshot to avoid repeated full-document
|
|
21
|
+
lookups when changed blocks survive cumulative replacements.
|
|
22
|
+
|
|
23
|
+
Let the chrome plugin map and accumulate existing highlights without restamping stale positions
|
|
24
|
+
from before direct orchestrator mutations.
|
|
25
|
+
|
|
26
|
+
- [`276b5526e198a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/276b5526e198a) -
|
|
27
|
+
Show the user profile card on hover in the mentions typeahead, behind the
|
|
28
|
+
`platform_editor_mention_typeahead_user_profilecard` experiment
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- [`9e6211ceb4ceb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9e6211ceb4ceb) -
|
|
33
|
+
Clean up the fully rolled-out `platform_editor_small_font_size` experiment and make its permanent
|
|
34
|
+
`true` behavior unconditional across editor formatting, task and list handling, paste behavior,
|
|
35
|
+
controls, and rendering.
|
|
36
|
+
- Updated dependencies
|
|
37
|
+
|
|
3
38
|
## 122.5.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/editor-common/collab-agent-edit-changed-ranges",
|
|
3
|
+
"main": "../dist/cjs/collab/agent-edit-changed-ranges.js",
|
|
4
|
+
"module": "../dist/esm/collab/agent-edit-changed-ranges.js",
|
|
5
|
+
"module:es2019": "../dist/es2019/collab/agent-edit-changed-ranges.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"**/*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../dist/types/collab/agent-edit-changed-ranges.d.ts"
|
|
10
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getAgentEditChangedRanges = getAgentEditChangedRanges;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
10
|
+
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; } } }; }
|
|
11
|
+
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; } }
|
|
12
|
+
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; }
|
|
13
|
+
// localId is identity metadata: regenerating it alone should not create activity.
|
|
14
|
+
var sameAttrs = function sameAttrs(left, right) {
|
|
15
|
+
var keys = Object.keys(left).filter(function (key) {
|
|
16
|
+
return key !== 'localId';
|
|
17
|
+
});
|
|
18
|
+
return keys.length === Object.keys(right).filter(function (key) {
|
|
19
|
+
return key !== 'localId';
|
|
20
|
+
}).length && keys.every(function (key) {
|
|
21
|
+
return (0, _isEqual.default)(left[key], right[key]);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Compare the node's own type, attributes and marks, without comparing its children.
|
|
26
|
+
var sameMarkup = function sameMarkup(left, right) {
|
|
27
|
+
return left.type === right.type && sameAttrs(left.attrs, right.attrs) && left.marks.length === right.marks.length && left.marks.every(function (mark, index) {
|
|
28
|
+
return mark.type === right.marks[index].type && sameAttrs(mark.attrs, right.marks[index].attrs);
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
var _sameNode = function sameNode(left, right) {
|
|
32
|
+
if (left === right) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (!sameMarkup(left, right) || left.text !== right.text || left.childCount !== right.childCount) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
for (var index = 0; index < left.childCount; index++) {
|
|
39
|
+
if (!_sameNode(left.child(index), right.child(index))) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Positions include document structure, not just character offsets. A non-leaf node
|
|
47
|
+
// uses one position for each opening/closing boundary, plus the size of its content.
|
|
48
|
+
// Example: paragraph('Hi') at pos 0 has nodeSize 4, outer range [0, 4),
|
|
49
|
+
// and text content [1, 3). All ranges here use an exclusive end position.
|
|
50
|
+
|
|
51
|
+
// Keep the reason internally so a panel attribute change can survive child edits.
|
|
52
|
+
// Only ordinary { from, to } ranges are returned to the chrome consumer.
|
|
53
|
+
|
|
54
|
+
var _collectChanges = function collectChanges(before, after, map, ranges) {
|
|
55
|
+
var node = after.node,
|
|
56
|
+
pos = after.pos;
|
|
57
|
+
if (before && _sameNode(before.node, node)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Text edits belong to their textblock. A node's own markup change instead
|
|
61
|
+
// owns its full content, so we stop here rather than adding child ranges too.
|
|
62
|
+
var markupChanged = !!before && node.isBlock && !sameMarkup(before.node, node);
|
|
63
|
+
if (node.isTextblock || markupChanged) {
|
|
64
|
+
if (node.content.size > 0) {
|
|
65
|
+
ranges.push({
|
|
66
|
+
from: pos,
|
|
67
|
+
to: pos + node.nodeSize,
|
|
68
|
+
markupChanged: markupChanged
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
var byPosition = new Map();
|
|
74
|
+
var byId = new Map();
|
|
75
|
+
var oldChildren = [];
|
|
76
|
+
before === null || before === void 0 || before.node.forEach(function (child, offset) {
|
|
77
|
+
// forEach offsets start inside the parent. Skip its opening boundary (+1)
|
|
78
|
+
// to convert this child offset into an absolute document position.
|
|
79
|
+
var previous = {
|
|
80
|
+
node: child,
|
|
81
|
+
pos: before.pos + 1 + offset
|
|
82
|
+
};
|
|
83
|
+
oldChildren.push(previous);
|
|
84
|
+
// This 1 is a mapping bias, not an added offset: follow the right side
|
|
85
|
+
// of an insertion at the child's start, keeping the original child after it.
|
|
86
|
+
var mapped = map.mapResult(previous.pos, 1);
|
|
87
|
+
if (!mapped.deleted) {
|
|
88
|
+
byPosition.set(mapped.pos, previous);
|
|
89
|
+
}
|
|
90
|
+
var id = child.attrs.localId;
|
|
91
|
+
if (typeof id === 'string' && id) {
|
|
92
|
+
// Duplicate IDs cannot identify a unique old child.
|
|
93
|
+
byId.set(id, byId.has(id) ? null : previous);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
var nextChildren = [];
|
|
97
|
+
node.forEach(function (child, offset) {
|
|
98
|
+
return nextChildren.push({
|
|
99
|
+
node: child,
|
|
100
|
+
pos: pos + 1 + offset
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
// Narrow edits usually preserve mapped positions. Whole-container replacements
|
|
104
|
+
// may erase those positions, so stable child IDs provide a second way to match.
|
|
105
|
+
var preferred = nextChildren.map(function (next) {
|
|
106
|
+
var _ref, _byPosition$get;
|
|
107
|
+
return (_ref = (_byPosition$get = byPosition.get(next.pos)) !== null && _byPosition$get !== void 0 ? _byPosition$get : byId.get(next.node.attrs.localId)) !== null && _ref !== void 0 ? _ref : undefined;
|
|
108
|
+
});
|
|
109
|
+
var claims = new Map();
|
|
110
|
+
var _iterator = _createForOfIteratorHelper(preferred),
|
|
111
|
+
_step;
|
|
112
|
+
try {
|
|
113
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
114
|
+
var match = _step.value;
|
|
115
|
+
if (match) {
|
|
116
|
+
var _claims$get;
|
|
117
|
+
claims.set(match, ((_claims$get = claims.get(match)) !== null && _claims$get !== void 0 ? _claims$get : 0) + 1);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} catch (err) {
|
|
121
|
+
_iterator.e(err);
|
|
122
|
+
} finally {
|
|
123
|
+
_iterator.f();
|
|
124
|
+
}
|
|
125
|
+
nextChildren.forEach(function (next, index) {
|
|
126
|
+
var match = preferred[index];
|
|
127
|
+
// Same-index fallback supports replacements that regenerate IDs but keep
|
|
128
|
+
// the child structure. Different child counts make that correspondence unsafe.
|
|
129
|
+
var aligned = oldChildren.length === node.childCount ? oldChildren[index] : undefined;
|
|
130
|
+
// Reserve every position/ID match before fallback, including later siblings.
|
|
131
|
+
// Reusing one old sibling can otherwise disguise an equal-text insertion.
|
|
132
|
+
var previous = match && claims.get(match) === 1 ? match : aligned && !claims.has(aligned) ? aligned : undefined;
|
|
133
|
+
_collectChanges(previous, next, map, ranges);
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
var findPreservedNode = function findPreservedNode(doc, previous, markupChanged, indexes) {
|
|
137
|
+
var id = previous.attrs.localId;
|
|
138
|
+
if (typeof id !== 'string' || !id) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
var byId = indexes.get(doc);
|
|
142
|
+
if (!byId) {
|
|
143
|
+
// Build only when mapping loses a candidate, then reuse for every range
|
|
144
|
+
// visiting this immutable snapshot. Ordinary mapped edits need no scan.
|
|
145
|
+
var nodeIndex = new Map();
|
|
146
|
+
doc.descendants(function (node, pos) {
|
|
147
|
+
var localId = node.attrs.localId;
|
|
148
|
+
if (typeof localId === 'string' && localId) {
|
|
149
|
+
// Keep duplicates ambiguous, including IDs outside the changed subtree.
|
|
150
|
+
nodeIndex.set(localId, nodeIndex.has(localId) ? null : {
|
|
151
|
+
node: node,
|
|
152
|
+
pos: pos
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
indexes.set(doc, nodeIndex);
|
|
157
|
+
byId = nodeIndex;
|
|
158
|
+
}
|
|
159
|
+
var match = byId.get(id);
|
|
160
|
+
// Attribute/mark activity belongs to the node even when its children are edited.
|
|
161
|
+
// Content-only activity still requires the entire candidate to survive unchanged.
|
|
162
|
+
var isPreserved = markupChanged ? sameMarkup : _sameNode;
|
|
163
|
+
return match && isPreserved(previous, match.node) ? match : undefined;
|
|
164
|
+
};
|
|
165
|
+
var mapToFinalBlocks = function mapToFinalBlocks(tr, index, range, indexes) {
|
|
166
|
+
var _tr$docs;
|
|
167
|
+
var from = range.from,
|
|
168
|
+
to = range.to;
|
|
169
|
+
// Track inner content separately from outer node bounds: +1 skips the opening
|
|
170
|
+
// boundary and -1 excludes the closing boundary (see paragraph example above).
|
|
171
|
+
var contentFrom = from + 1;
|
|
172
|
+
var contentTo = to - 1;
|
|
173
|
+
// docs[i] is the document BEFORE step i, so docs[i + 1] is its result.
|
|
174
|
+
// The last step has no next snapshot; tr.doc is its result instead.
|
|
175
|
+
var node = ((_tr$docs = tr.docs[index + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc).nodeAt(from);
|
|
176
|
+
if (!node) {
|
|
177
|
+
return [];
|
|
178
|
+
}
|
|
179
|
+
// Later non-AI steps also shift/delete existing activity, even though they
|
|
180
|
+
// cannot create new activity themselves. Process every intermediate document.
|
|
181
|
+
for (var next = index + 1; next < tr.steps.length; next++) {
|
|
182
|
+
var _tr$docs2;
|
|
183
|
+
var map = tr.mapping.maps[next];
|
|
184
|
+
var after = (_tr$docs2 = tr.docs[next + 1]) !== null && _tr$docs2 !== void 0 ? _tr$docs2 : tr.doc;
|
|
185
|
+
// Mapping biases +1 (right) and -1 (left) keep boundary insertions outside
|
|
186
|
+
// the tracked content. These arguments do not add/subtract document positions.
|
|
187
|
+
var start = map.mapResult(contentFrom, 1);
|
|
188
|
+
var end = map.mapResult(contentTo, -1);
|
|
189
|
+
if (start.deleted && end.deleted || end.pos <= start.pos) {
|
|
190
|
+
// A cumulative replacement can preserve the candidate content or owned markup.
|
|
191
|
+
// Check every intermediate doc so deletion then reinsertion never resurrects it.
|
|
192
|
+
var preserved = findPreservedNode(after, node, range.markupChanged, indexes);
|
|
193
|
+
if (!preserved) {
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
from = preserved.pos;
|
|
197
|
+
to = from + preserved.node.nodeSize;
|
|
198
|
+
contentFrom = from + 1;
|
|
199
|
+
contentTo = to - 1;
|
|
200
|
+
node = preserved.node;
|
|
201
|
+
} else {
|
|
202
|
+
// Apply the same inward biases to the outer node bounds.
|
|
203
|
+
from = map.map(from, 1);
|
|
204
|
+
to = map.map(to, -1);
|
|
205
|
+
contentFrom = start.pos;
|
|
206
|
+
contentTo = end.pos;
|
|
207
|
+
var current = after.nodeAt(from);
|
|
208
|
+
if (current && current.nodeSize === to - from) {
|
|
209
|
+
node = current;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (from < 0 || to > tr.doc.content.size || contentTo <= contentFrom) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
var finalNode = tr.doc.nodeAt(from);
|
|
217
|
+
if (finalNode !== null && finalNode !== void 0 && finalNode.isBlock && finalNode.nodeSize === to - from) {
|
|
218
|
+
return [{
|
|
219
|
+
from: from,
|
|
220
|
+
to: to
|
|
221
|
+
}];
|
|
222
|
+
}
|
|
223
|
+
// Joins/splits can leave mapped boundaries inside the final textblock.
|
|
224
|
+
var blocks = [];
|
|
225
|
+
tr.doc.nodesBetween(contentFrom, contentTo, function (child, pos) {
|
|
226
|
+
if (child.isTextblock) {
|
|
227
|
+
blocks.push({
|
|
228
|
+
from: pos,
|
|
229
|
+
to: pos + child.nodeSize
|
|
230
|
+
});
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
return blocks;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Returns whole content-block ranges for selected applied steps, in tr.doc coordinates.
|
|
239
|
+
* Callers select actual AI writes (excluding restores, acknowledgments and preparation)
|
|
240
|
+
* and own experiment/lifecycle decisions. This helper does not dispatch or render.
|
|
241
|
+
*
|
|
242
|
+
* Comparing each step's snapshots also handles attribute/mark steps with empty maps.
|
|
243
|
+
* Shared unchanged subtrees are skipped by reference. Only localId changes are ignored;
|
|
244
|
+
* meaningful attributes and marks retain the affected node's full content scope.
|
|
245
|
+
*/
|
|
246
|
+
function getAgentEditChangedRanges(tr, includedStepIndexes) {
|
|
247
|
+
// Positions belong to each intermediate document, not just tr.doc. Keep the
|
|
248
|
+
// lazy indexes local to this call so deletion/reinsertion checks stay intact
|
|
249
|
+
// and no cache is retained between transactions or streaming chunks.
|
|
250
|
+
var indexes = new WeakMap();
|
|
251
|
+
var ranges = [];
|
|
252
|
+
var _iterator2 = _createForOfIteratorHelper(new Set(includedStepIndexes)),
|
|
253
|
+
_step2;
|
|
254
|
+
try {
|
|
255
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
256
|
+
var _tr$docs3;
|
|
257
|
+
var index = _step2.value;
|
|
258
|
+
if (!Number.isInteger(index) || index < 0 || index >= tr.steps.length) {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
var changed = [];
|
|
262
|
+
// The root document has no opening boundary. Using -1 makes the recursive
|
|
263
|
+
// parent.pos + 1 + offset formula place its first child at position 0.
|
|
264
|
+
_collectChanges({
|
|
265
|
+
node: tr.docs[index],
|
|
266
|
+
pos: -1
|
|
267
|
+
}, {
|
|
268
|
+
node: (_tr$docs3 = tr.docs[index + 1]) !== null && _tr$docs3 !== void 0 ? _tr$docs3 : tr.doc,
|
|
269
|
+
pos: -1
|
|
270
|
+
}, tr.steps[index].getMap(), changed);
|
|
271
|
+
for (var _i = 0, _changed = changed; _i < _changed.length; _i++) {
|
|
272
|
+
var range = _changed[_i];
|
|
273
|
+
ranges.push.apply(ranges, (0, _toConsumableArray2.default)(mapToFinalBlocks(tr, index, range, indexes)));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Return only the surviving final-document ranges, never intermediate step states.
|
|
278
|
+
// Sort outer ranges before their children, then discard duplicates/contained ranges.
|
|
279
|
+
// Separate ranges stay separate; this must not highlight the untouched gaps.
|
|
280
|
+
} catch (err) {
|
|
281
|
+
_iterator2.e(err);
|
|
282
|
+
} finally {
|
|
283
|
+
_iterator2.f();
|
|
284
|
+
}
|
|
285
|
+
var unique = [];
|
|
286
|
+
var _iterator3 = _createForOfIteratorHelper(ranges.sort(function (left, right) {
|
|
287
|
+
return left.from - right.from || right.to - left.to;
|
|
288
|
+
})),
|
|
289
|
+
_step3;
|
|
290
|
+
try {
|
|
291
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
292
|
+
var _range = _step3.value;
|
|
293
|
+
var previous = unique[unique.length - 1];
|
|
294
|
+
if (!previous || _range.to > previous.to) {
|
|
295
|
+
unique.push(_range);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} catch (err) {
|
|
299
|
+
_iterator3.e(err);
|
|
300
|
+
} finally {
|
|
301
|
+
_iterator3.f();
|
|
302
|
+
}
|
|
303
|
+
return unique;
|
|
304
|
+
}
|
|
@@ -27,7 +27,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
27
27
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
28
28
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
29
29
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
30
|
-
var packageVersion = "122.
|
|
30
|
+
var packageVersion = "122.5.0";
|
|
31
31
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
32
32
|
// Remove URL as it has UGC
|
|
33
33
|
// Ignored via go/ees007
|
|
@@ -5,14 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getFormattedNode = void 0;
|
|
7
7
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
8
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
9
8
|
var getFormattedNode = exports.getFormattedNode = function getFormattedNode(tr) {
|
|
10
9
|
var selection = tr.selection;
|
|
11
10
|
var nodes = tr.doc.type.schema.nodes;
|
|
12
|
-
|
|
13
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
14
|
-
// but keep this solution general
|
|
15
|
-
var isBlockTaskItemEnabled = !!nodes.blockTaskItem && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
11
|
+
var isBlockTaskItemEnabled = !!nodes.blockTaskItem;
|
|
16
12
|
|
|
17
13
|
// Find the node to format from the current selection
|
|
18
14
|
var nodeToFormat;
|
|
@@ -39,7 +39,6 @@ exports.transformToTaskList = void 0;
|
|
|
39
39
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
40
40
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
41
41
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
42
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
43
42
|
var _convertBlockToInlineContent = require("./convertBlockToInlineContent");
|
|
44
43
|
var _createBlockTaskItem = require("./createBlockTaskItem");
|
|
45
44
|
var _isBulletOrOrderedList = require("./isBulletOrOrderedList");
|
|
@@ -76,10 +75,7 @@ var _transformListRecursively = exports.transformListRecursively = function tran
|
|
|
76
75
|
taskItem = _schema$nodes.taskItem,
|
|
77
76
|
paragraph = _schema$nodes.paragraph,
|
|
78
77
|
blockTaskItem = _schema$nodes.blockTaskItem;
|
|
79
|
-
|
|
80
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
81
|
-
// but keep this solution general
|
|
82
|
-
var isBlockTaskEnabled = !!blockTaskItem && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
78
|
+
var isBlockTaskEnabled = !!blockTaskItem;
|
|
83
79
|
|
|
84
80
|
/**
|
|
85
81
|
* Extracts paragraph children from a blockTaskItem, preserving their marks.
|
|
@@ -239,9 +235,7 @@ var transformToTaskList = exports.transformToTaskList = function transformToTask
|
|
|
239
235
|
var taskItem = nodes.taskItem,
|
|
240
236
|
paragraph = nodes.paragraph,
|
|
241
237
|
blockTaskItem = nodes.blockTaskItem;
|
|
242
|
-
|
|
243
|
-
// but keep this solution general
|
|
244
|
-
var isBlockTaskItemEnabled = !!blockTaskItem && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
238
|
+
var isBlockTaskItemEnabled = !!blockTaskItem;
|
|
245
239
|
var listItems = [];
|
|
246
240
|
|
|
247
241
|
// Process each block in the range
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.transformTaskListToBlockNodes = void 0;
|
|
7
7
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
8
8
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
9
|
-
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
10
9
|
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; } } }; }
|
|
11
10
|
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; } }
|
|
12
11
|
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; }
|
|
@@ -19,10 +18,7 @@ var transformTaskListToBlockNodes = exports.transformTaskListToBlockNodes = func
|
|
|
19
18
|
var selection = tr.selection;
|
|
20
19
|
var schema = selection.$from.doc.type.schema;
|
|
21
20
|
var blockTaskItem = schema.nodes.blockTaskItem;
|
|
22
|
-
|
|
23
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
24
|
-
// but keep this solution general
|
|
25
|
-
var isBlockTaskItemEnabled = !!blockTaskItem && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
|
|
21
|
+
var isBlockTaskItemEnabled = !!blockTaskItem;
|
|
26
22
|
if (isBlockTaskItemEnabled) {
|
|
27
23
|
var blockTaskItemsResult = (0, _utils.findChildrenByType)(sourceNode, blockTaskItem);
|
|
28
24
|
if (blockTaskItemsResult.length > 0 && targetNodeType === schema.nodes.paragraph) {
|
|
@@ -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 = "122.
|
|
27
|
+
var packageVersion = "122.5.0";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import isEqual from 'lodash/isEqual';
|
|
2
|
+
// localId is identity metadata: regenerating it alone should not create activity.
|
|
3
|
+
const sameAttrs = (left, right) => {
|
|
4
|
+
const keys = Object.keys(left).filter(key => key !== 'localId');
|
|
5
|
+
return keys.length === Object.keys(right).filter(key => key !== 'localId').length && keys.every(key => isEqual(left[key], right[key]));
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// Compare the node's own type, attributes and marks, without comparing its children.
|
|
9
|
+
const sameMarkup = (left, right) => left.type === right.type && sameAttrs(left.attrs, right.attrs) && left.marks.length === right.marks.length && left.marks.every((mark, index) => mark.type === right.marks[index].type && sameAttrs(mark.attrs, right.marks[index].attrs));
|
|
10
|
+
const sameNode = (left, right) => {
|
|
11
|
+
if (left === right) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
if (!sameMarkup(left, right) || left.text !== right.text || left.childCount !== right.childCount) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
for (let index = 0; index < left.childCount; index++) {
|
|
18
|
+
if (!sameNode(left.child(index), right.child(index))) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Positions include document structure, not just character offsets. A non-leaf node
|
|
26
|
+
// uses one position for each opening/closing boundary, plus the size of its content.
|
|
27
|
+
// Example: paragraph('Hi') at pos 0 has nodeSize 4, outer range [0, 4),
|
|
28
|
+
// and text content [1, 3). All ranges here use an exclusive end position.
|
|
29
|
+
|
|
30
|
+
// Keep the reason internally so a panel attribute change can survive child edits.
|
|
31
|
+
// Only ordinary { from, to } ranges are returned to the chrome consumer.
|
|
32
|
+
|
|
33
|
+
const collectChanges = (before, after, map, ranges) => {
|
|
34
|
+
const {
|
|
35
|
+
node,
|
|
36
|
+
pos
|
|
37
|
+
} = after;
|
|
38
|
+
if (before && sameNode(before.node, node)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
// Text edits belong to their textblock. A node's own markup change instead
|
|
42
|
+
// owns its full content, so we stop here rather than adding child ranges too.
|
|
43
|
+
const markupChanged = !!before && node.isBlock && !sameMarkup(before.node, node);
|
|
44
|
+
if (node.isTextblock || markupChanged) {
|
|
45
|
+
if (node.content.size > 0) {
|
|
46
|
+
ranges.push({
|
|
47
|
+
from: pos,
|
|
48
|
+
to: pos + node.nodeSize,
|
|
49
|
+
markupChanged
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const byPosition = new Map();
|
|
55
|
+
const byId = new Map();
|
|
56
|
+
const oldChildren = [];
|
|
57
|
+
before === null || before === void 0 ? void 0 : before.node.forEach((child, offset) => {
|
|
58
|
+
// forEach offsets start inside the parent. Skip its opening boundary (+1)
|
|
59
|
+
// to convert this child offset into an absolute document position.
|
|
60
|
+
const previous = {
|
|
61
|
+
node: child,
|
|
62
|
+
pos: before.pos + 1 + offset
|
|
63
|
+
};
|
|
64
|
+
oldChildren.push(previous);
|
|
65
|
+
// This 1 is a mapping bias, not an added offset: follow the right side
|
|
66
|
+
// of an insertion at the child's start, keeping the original child after it.
|
|
67
|
+
const mapped = map.mapResult(previous.pos, 1);
|
|
68
|
+
if (!mapped.deleted) {
|
|
69
|
+
byPosition.set(mapped.pos, previous);
|
|
70
|
+
}
|
|
71
|
+
const id = child.attrs.localId;
|
|
72
|
+
if (typeof id === 'string' && id) {
|
|
73
|
+
// Duplicate IDs cannot identify a unique old child.
|
|
74
|
+
byId.set(id, byId.has(id) ? null : previous);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const nextChildren = [];
|
|
78
|
+
node.forEach((child, offset) => nextChildren.push({
|
|
79
|
+
node: child,
|
|
80
|
+
pos: pos + 1 + offset
|
|
81
|
+
}));
|
|
82
|
+
// Narrow edits usually preserve mapped positions. Whole-container replacements
|
|
83
|
+
// may erase those positions, so stable child IDs provide a second way to match.
|
|
84
|
+
const preferred = nextChildren.map(next => {
|
|
85
|
+
var _ref, _byPosition$get;
|
|
86
|
+
return (_ref = (_byPosition$get = byPosition.get(next.pos)) !== null && _byPosition$get !== void 0 ? _byPosition$get : byId.get(next.node.attrs.localId)) !== null && _ref !== void 0 ? _ref : undefined;
|
|
87
|
+
});
|
|
88
|
+
const claims = new Map();
|
|
89
|
+
for (const match of preferred) {
|
|
90
|
+
if (match) {
|
|
91
|
+
var _claims$get;
|
|
92
|
+
claims.set(match, ((_claims$get = claims.get(match)) !== null && _claims$get !== void 0 ? _claims$get : 0) + 1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
nextChildren.forEach((next, index) => {
|
|
96
|
+
const match = preferred[index];
|
|
97
|
+
// Same-index fallback supports replacements that regenerate IDs but keep
|
|
98
|
+
// the child structure. Different child counts make that correspondence unsafe.
|
|
99
|
+
const aligned = oldChildren.length === node.childCount ? oldChildren[index] : undefined;
|
|
100
|
+
// Reserve every position/ID match before fallback, including later siblings.
|
|
101
|
+
// Reusing one old sibling can otherwise disguise an equal-text insertion.
|
|
102
|
+
const previous = match && claims.get(match) === 1 ? match : aligned && !claims.has(aligned) ? aligned : undefined;
|
|
103
|
+
collectChanges(previous, next, map, ranges);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
const findPreservedNode = (doc, previous, markupChanged, indexes) => {
|
|
107
|
+
const id = previous.attrs.localId;
|
|
108
|
+
if (typeof id !== 'string' || !id) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
let byId = indexes.get(doc);
|
|
112
|
+
if (!byId) {
|
|
113
|
+
// Build only when mapping loses a candidate, then reuse for every range
|
|
114
|
+
// visiting this immutable snapshot. Ordinary mapped edits need no scan.
|
|
115
|
+
const nodeIndex = new Map();
|
|
116
|
+
doc.descendants((node, pos) => {
|
|
117
|
+
const localId = node.attrs.localId;
|
|
118
|
+
if (typeof localId === 'string' && localId) {
|
|
119
|
+
// Keep duplicates ambiguous, including IDs outside the changed subtree.
|
|
120
|
+
nodeIndex.set(localId, nodeIndex.has(localId) ? null : {
|
|
121
|
+
node,
|
|
122
|
+
pos
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
indexes.set(doc, nodeIndex);
|
|
127
|
+
byId = nodeIndex;
|
|
128
|
+
}
|
|
129
|
+
const match = byId.get(id);
|
|
130
|
+
// Attribute/mark activity belongs to the node even when its children are edited.
|
|
131
|
+
// Content-only activity still requires the entire candidate to survive unchanged.
|
|
132
|
+
const isPreserved = markupChanged ? sameMarkup : sameNode;
|
|
133
|
+
return match && isPreserved(previous, match.node) ? match : undefined;
|
|
134
|
+
};
|
|
135
|
+
const mapToFinalBlocks = (tr, index, range, indexes) => {
|
|
136
|
+
var _tr$docs;
|
|
137
|
+
let {
|
|
138
|
+
from,
|
|
139
|
+
to
|
|
140
|
+
} = range;
|
|
141
|
+
// Track inner content separately from outer node bounds: +1 skips the opening
|
|
142
|
+
// boundary and -1 excludes the closing boundary (see paragraph example above).
|
|
143
|
+
let contentFrom = from + 1;
|
|
144
|
+
let contentTo = to - 1;
|
|
145
|
+
// docs[i] is the document BEFORE step i, so docs[i + 1] is its result.
|
|
146
|
+
// The last step has no next snapshot; tr.doc is its result instead.
|
|
147
|
+
let node = ((_tr$docs = tr.docs[index + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc).nodeAt(from);
|
|
148
|
+
if (!node) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
// Later non-AI steps also shift/delete existing activity, even though they
|
|
152
|
+
// cannot create new activity themselves. Process every intermediate document.
|
|
153
|
+
for (let next = index + 1; next < tr.steps.length; next++) {
|
|
154
|
+
var _tr$docs2;
|
|
155
|
+
const map = tr.mapping.maps[next];
|
|
156
|
+
const after = (_tr$docs2 = tr.docs[next + 1]) !== null && _tr$docs2 !== void 0 ? _tr$docs2 : tr.doc;
|
|
157
|
+
// Mapping biases +1 (right) and -1 (left) keep boundary insertions outside
|
|
158
|
+
// the tracked content. These arguments do not add/subtract document positions.
|
|
159
|
+
const start = map.mapResult(contentFrom, 1);
|
|
160
|
+
const end = map.mapResult(contentTo, -1);
|
|
161
|
+
if (start.deleted && end.deleted || end.pos <= start.pos) {
|
|
162
|
+
// A cumulative replacement can preserve the candidate content or owned markup.
|
|
163
|
+
// Check every intermediate doc so deletion then reinsertion never resurrects it.
|
|
164
|
+
const preserved = findPreservedNode(after, node, range.markupChanged, indexes);
|
|
165
|
+
if (!preserved) {
|
|
166
|
+
return [];
|
|
167
|
+
}
|
|
168
|
+
from = preserved.pos;
|
|
169
|
+
to = from + preserved.node.nodeSize;
|
|
170
|
+
contentFrom = from + 1;
|
|
171
|
+
contentTo = to - 1;
|
|
172
|
+
node = preserved.node;
|
|
173
|
+
} else {
|
|
174
|
+
// Apply the same inward biases to the outer node bounds.
|
|
175
|
+
from = map.map(from, 1);
|
|
176
|
+
to = map.map(to, -1);
|
|
177
|
+
contentFrom = start.pos;
|
|
178
|
+
contentTo = end.pos;
|
|
179
|
+
const current = after.nodeAt(from);
|
|
180
|
+
if (current && current.nodeSize === to - from) {
|
|
181
|
+
node = current;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (from < 0 || to > tr.doc.content.size || contentTo <= contentFrom) {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
const finalNode = tr.doc.nodeAt(from);
|
|
189
|
+
if (finalNode !== null && finalNode !== void 0 && finalNode.isBlock && finalNode.nodeSize === to - from) {
|
|
190
|
+
return [{
|
|
191
|
+
from,
|
|
192
|
+
to
|
|
193
|
+
}];
|
|
194
|
+
}
|
|
195
|
+
// Joins/splits can leave mapped boundaries inside the final textblock.
|
|
196
|
+
const blocks = [];
|
|
197
|
+
tr.doc.nodesBetween(contentFrom, contentTo, (child, pos) => {
|
|
198
|
+
if (child.isTextblock) {
|
|
199
|
+
blocks.push({
|
|
200
|
+
from: pos,
|
|
201
|
+
to: pos + child.nodeSize
|
|
202
|
+
});
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
return blocks;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Returns whole content-block ranges for selected applied steps, in tr.doc coordinates.
|
|
211
|
+
* Callers select actual AI writes (excluding restores, acknowledgments and preparation)
|
|
212
|
+
* and own experiment/lifecycle decisions. This helper does not dispatch or render.
|
|
213
|
+
*
|
|
214
|
+
* Comparing each step's snapshots also handles attribute/mark steps with empty maps.
|
|
215
|
+
* Shared unchanged subtrees are skipped by reference. Only localId changes are ignored;
|
|
216
|
+
* meaningful attributes and marks retain the affected node's full content scope.
|
|
217
|
+
*/
|
|
218
|
+
export function getAgentEditChangedRanges(tr, includedStepIndexes) {
|
|
219
|
+
// Positions belong to each intermediate document, not just tr.doc. Keep the
|
|
220
|
+
// lazy indexes local to this call so deletion/reinsertion checks stay intact
|
|
221
|
+
// and no cache is retained between transactions or streaming chunks.
|
|
222
|
+
const indexes = new WeakMap();
|
|
223
|
+
const ranges = [];
|
|
224
|
+
for (const index of new Set(includedStepIndexes)) {
|
|
225
|
+
var _tr$docs3;
|
|
226
|
+
if (!Number.isInteger(index) || index < 0 || index >= tr.steps.length) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
const changed = [];
|
|
230
|
+
// The root document has no opening boundary. Using -1 makes the recursive
|
|
231
|
+
// parent.pos + 1 + offset formula place its first child at position 0.
|
|
232
|
+
collectChanges({
|
|
233
|
+
node: tr.docs[index],
|
|
234
|
+
pos: -1
|
|
235
|
+
}, {
|
|
236
|
+
node: (_tr$docs3 = tr.docs[index + 1]) !== null && _tr$docs3 !== void 0 ? _tr$docs3 : tr.doc,
|
|
237
|
+
pos: -1
|
|
238
|
+
}, tr.steps[index].getMap(), changed);
|
|
239
|
+
for (const range of changed) {
|
|
240
|
+
ranges.push(...mapToFinalBlocks(tr, index, range, indexes));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Return only the surviving final-document ranges, never intermediate step states.
|
|
245
|
+
// Sort outer ranges before their children, then discard duplicates/contained ranges.
|
|
246
|
+
// Separate ranges stay separate; this must not highlight the untouched gaps.
|
|
247
|
+
const unique = [];
|
|
248
|
+
for (const range of ranges.sort((left, right) => left.from - right.from || right.to - left.to)) {
|
|
249
|
+
const previous = unique[unique.length - 1];
|
|
250
|
+
if (!previous || range.to > previous.to) {
|
|
251
|
+
unique.push(range);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return unique;
|
|
255
|
+
}
|
|
@@ -13,7 +13,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
13
13
|
const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
14
14
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
15
15
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
16
|
-
const packageVersion = "122.
|
|
16
|
+
const packageVersion = "122.5.0";
|
|
17
17
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
18
18
|
// Remove URL as it has UGC
|
|
19
19
|
// Ignored via go/ees007
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
2
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
2
|
export const getFormattedNode = tr => {
|
|
4
3
|
const {
|
|
5
4
|
selection
|
|
@@ -7,10 +6,7 @@ export const getFormattedNode = tr => {
|
|
|
7
6
|
const {
|
|
8
7
|
nodes
|
|
9
8
|
} = tr.doc.type.schema;
|
|
10
|
-
|
|
11
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
12
|
-
// but keep this solution general
|
|
13
|
-
const isBlockTaskItemEnabled = !!nodes.blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
9
|
+
const isBlockTaskItemEnabled = !!nodes.blockTaskItem;
|
|
14
10
|
|
|
15
11
|
// Find the node to format from the current selection
|
|
16
12
|
let nodeToFormat;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
2
|
import { convertBlockToInlineContent } from './convertBlockToInlineContent';
|
|
4
3
|
import { createBlockTaskItem } from './createBlockTaskItem';
|
|
5
4
|
import { isBulletOrOrderedList } from './isBulletOrOrderedList';
|
|
@@ -34,10 +33,7 @@ export const transformListRecursively = (props, onhandleUnsupportedContent) => {
|
|
|
34
33
|
paragraph,
|
|
35
34
|
blockTaskItem
|
|
36
35
|
} = schema.nodes;
|
|
37
|
-
|
|
38
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
39
|
-
// but keep this solution general
|
|
40
|
-
const isBlockTaskEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
36
|
+
const isBlockTaskEnabled = !!blockTaskItem;
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* Extracts paragraph children from a blockTaskItem, preserving their marks.
|
|
@@ -204,9 +200,7 @@ export const transformToTaskList = (tr, range, targetNodeType, targetAttrs, node
|
|
|
204
200
|
paragraph,
|
|
205
201
|
blockTaskItem
|
|
206
202
|
} = nodes;
|
|
207
|
-
|
|
208
|
-
// but keep this solution general
|
|
209
|
-
const isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
203
|
+
const isBlockTaskItemEnabled = !!blockTaskItem;
|
|
210
204
|
const listItems = [];
|
|
211
205
|
|
|
212
206
|
// Process each block in the range
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
2
2
|
import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
|
|
3
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
3
|
export const transformTaskListToBlockNodes = context => {
|
|
5
4
|
const {
|
|
6
5
|
tr,
|
|
@@ -16,10 +15,7 @@ export const transformTaskListToBlockNodes = context => {
|
|
|
16
15
|
const {
|
|
17
16
|
blockTaskItem
|
|
18
17
|
} = schema.nodes;
|
|
19
|
-
|
|
20
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
21
|
-
// but keep this solution general
|
|
22
|
-
const isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
18
|
+
const isBlockTaskItemEnabled = !!blockTaskItem;
|
|
23
19
|
if (isBlockTaskItemEnabled) {
|
|
24
20
|
const blockTaskItemsResult = findChildrenByType(sourceNode, blockTaskItem);
|
|
25
21
|
if (blockTaskItemsResult.length > 0 && targetNodeType === schema.nodes.paragraph) {
|
|
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
14
14
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
15
15
|
import Layer from '../Layer';
|
|
16
16
|
const packageName = "@atlaskit/editor-common";
|
|
17
|
-
const packageVersion = "122.
|
|
17
|
+
const packageVersion = "122.5.0";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
import isEqual from 'lodash/isEqual';
|
|
6
|
+
// localId is identity metadata: regenerating it alone should not create activity.
|
|
7
|
+
var sameAttrs = function sameAttrs(left, right) {
|
|
8
|
+
var keys = Object.keys(left).filter(function (key) {
|
|
9
|
+
return key !== 'localId';
|
|
10
|
+
});
|
|
11
|
+
return keys.length === Object.keys(right).filter(function (key) {
|
|
12
|
+
return key !== 'localId';
|
|
13
|
+
}).length && keys.every(function (key) {
|
|
14
|
+
return isEqual(left[key], right[key]);
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Compare the node's own type, attributes and marks, without comparing its children.
|
|
19
|
+
var sameMarkup = function sameMarkup(left, right) {
|
|
20
|
+
return left.type === right.type && sameAttrs(left.attrs, right.attrs) && left.marks.length === right.marks.length && left.marks.every(function (mark, index) {
|
|
21
|
+
return mark.type === right.marks[index].type && sameAttrs(mark.attrs, right.marks[index].attrs);
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
var _sameNode = function sameNode(left, right) {
|
|
25
|
+
if (left === right) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
if (!sameMarkup(left, right) || left.text !== right.text || left.childCount !== right.childCount) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
for (var index = 0; index < left.childCount; index++) {
|
|
32
|
+
if (!_sameNode(left.child(index), right.child(index))) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Positions include document structure, not just character offsets. A non-leaf node
|
|
40
|
+
// uses one position for each opening/closing boundary, plus the size of its content.
|
|
41
|
+
// Example: paragraph('Hi') at pos 0 has nodeSize 4, outer range [0, 4),
|
|
42
|
+
// and text content [1, 3). All ranges here use an exclusive end position.
|
|
43
|
+
|
|
44
|
+
// Keep the reason internally so a panel attribute change can survive child edits.
|
|
45
|
+
// Only ordinary { from, to } ranges are returned to the chrome consumer.
|
|
46
|
+
|
|
47
|
+
var _collectChanges = function collectChanges(before, after, map, ranges) {
|
|
48
|
+
var node = after.node,
|
|
49
|
+
pos = after.pos;
|
|
50
|
+
if (before && _sameNode(before.node, node)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Text edits belong to their textblock. A node's own markup change instead
|
|
54
|
+
// owns its full content, so we stop here rather than adding child ranges too.
|
|
55
|
+
var markupChanged = !!before && node.isBlock && !sameMarkup(before.node, node);
|
|
56
|
+
if (node.isTextblock || markupChanged) {
|
|
57
|
+
if (node.content.size > 0) {
|
|
58
|
+
ranges.push({
|
|
59
|
+
from: pos,
|
|
60
|
+
to: pos + node.nodeSize,
|
|
61
|
+
markupChanged: markupChanged
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
var byPosition = new Map();
|
|
67
|
+
var byId = new Map();
|
|
68
|
+
var oldChildren = [];
|
|
69
|
+
before === null || before === void 0 || before.node.forEach(function (child, offset) {
|
|
70
|
+
// forEach offsets start inside the parent. Skip its opening boundary (+1)
|
|
71
|
+
// to convert this child offset into an absolute document position.
|
|
72
|
+
var previous = {
|
|
73
|
+
node: child,
|
|
74
|
+
pos: before.pos + 1 + offset
|
|
75
|
+
};
|
|
76
|
+
oldChildren.push(previous);
|
|
77
|
+
// This 1 is a mapping bias, not an added offset: follow the right side
|
|
78
|
+
// of an insertion at the child's start, keeping the original child after it.
|
|
79
|
+
var mapped = map.mapResult(previous.pos, 1);
|
|
80
|
+
if (!mapped.deleted) {
|
|
81
|
+
byPosition.set(mapped.pos, previous);
|
|
82
|
+
}
|
|
83
|
+
var id = child.attrs.localId;
|
|
84
|
+
if (typeof id === 'string' && id) {
|
|
85
|
+
// Duplicate IDs cannot identify a unique old child.
|
|
86
|
+
byId.set(id, byId.has(id) ? null : previous);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
var nextChildren = [];
|
|
90
|
+
node.forEach(function (child, offset) {
|
|
91
|
+
return nextChildren.push({
|
|
92
|
+
node: child,
|
|
93
|
+
pos: pos + 1 + offset
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
// Narrow edits usually preserve mapped positions. Whole-container replacements
|
|
97
|
+
// may erase those positions, so stable child IDs provide a second way to match.
|
|
98
|
+
var preferred = nextChildren.map(function (next) {
|
|
99
|
+
var _ref, _byPosition$get;
|
|
100
|
+
return (_ref = (_byPosition$get = byPosition.get(next.pos)) !== null && _byPosition$get !== void 0 ? _byPosition$get : byId.get(next.node.attrs.localId)) !== null && _ref !== void 0 ? _ref : undefined;
|
|
101
|
+
});
|
|
102
|
+
var claims = new Map();
|
|
103
|
+
var _iterator = _createForOfIteratorHelper(preferred),
|
|
104
|
+
_step;
|
|
105
|
+
try {
|
|
106
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
107
|
+
var match = _step.value;
|
|
108
|
+
if (match) {
|
|
109
|
+
var _claims$get;
|
|
110
|
+
claims.set(match, ((_claims$get = claims.get(match)) !== null && _claims$get !== void 0 ? _claims$get : 0) + 1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
_iterator.e(err);
|
|
115
|
+
} finally {
|
|
116
|
+
_iterator.f();
|
|
117
|
+
}
|
|
118
|
+
nextChildren.forEach(function (next, index) {
|
|
119
|
+
var match = preferred[index];
|
|
120
|
+
// Same-index fallback supports replacements that regenerate IDs but keep
|
|
121
|
+
// the child structure. Different child counts make that correspondence unsafe.
|
|
122
|
+
var aligned = oldChildren.length === node.childCount ? oldChildren[index] : undefined;
|
|
123
|
+
// Reserve every position/ID match before fallback, including later siblings.
|
|
124
|
+
// Reusing one old sibling can otherwise disguise an equal-text insertion.
|
|
125
|
+
var previous = match && claims.get(match) === 1 ? match : aligned && !claims.has(aligned) ? aligned : undefined;
|
|
126
|
+
_collectChanges(previous, next, map, ranges);
|
|
127
|
+
});
|
|
128
|
+
};
|
|
129
|
+
var findPreservedNode = function findPreservedNode(doc, previous, markupChanged, indexes) {
|
|
130
|
+
var id = previous.attrs.localId;
|
|
131
|
+
if (typeof id !== 'string' || !id) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
var byId = indexes.get(doc);
|
|
135
|
+
if (!byId) {
|
|
136
|
+
// Build only when mapping loses a candidate, then reuse for every range
|
|
137
|
+
// visiting this immutable snapshot. Ordinary mapped edits need no scan.
|
|
138
|
+
var nodeIndex = new Map();
|
|
139
|
+
doc.descendants(function (node, pos) {
|
|
140
|
+
var localId = node.attrs.localId;
|
|
141
|
+
if (typeof localId === 'string' && localId) {
|
|
142
|
+
// Keep duplicates ambiguous, including IDs outside the changed subtree.
|
|
143
|
+
nodeIndex.set(localId, nodeIndex.has(localId) ? null : {
|
|
144
|
+
node: node,
|
|
145
|
+
pos: pos
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
indexes.set(doc, nodeIndex);
|
|
150
|
+
byId = nodeIndex;
|
|
151
|
+
}
|
|
152
|
+
var match = byId.get(id);
|
|
153
|
+
// Attribute/mark activity belongs to the node even when its children are edited.
|
|
154
|
+
// Content-only activity still requires the entire candidate to survive unchanged.
|
|
155
|
+
var isPreserved = markupChanged ? sameMarkup : _sameNode;
|
|
156
|
+
return match && isPreserved(previous, match.node) ? match : undefined;
|
|
157
|
+
};
|
|
158
|
+
var mapToFinalBlocks = function mapToFinalBlocks(tr, index, range, indexes) {
|
|
159
|
+
var _tr$docs;
|
|
160
|
+
var from = range.from,
|
|
161
|
+
to = range.to;
|
|
162
|
+
// Track inner content separately from outer node bounds: +1 skips the opening
|
|
163
|
+
// boundary and -1 excludes the closing boundary (see paragraph example above).
|
|
164
|
+
var contentFrom = from + 1;
|
|
165
|
+
var contentTo = to - 1;
|
|
166
|
+
// docs[i] is the document BEFORE step i, so docs[i + 1] is its result.
|
|
167
|
+
// The last step has no next snapshot; tr.doc is its result instead.
|
|
168
|
+
var node = ((_tr$docs = tr.docs[index + 1]) !== null && _tr$docs !== void 0 ? _tr$docs : tr.doc).nodeAt(from);
|
|
169
|
+
if (!node) {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
// Later non-AI steps also shift/delete existing activity, even though they
|
|
173
|
+
// cannot create new activity themselves. Process every intermediate document.
|
|
174
|
+
for (var next = index + 1; next < tr.steps.length; next++) {
|
|
175
|
+
var _tr$docs2;
|
|
176
|
+
var map = tr.mapping.maps[next];
|
|
177
|
+
var after = (_tr$docs2 = tr.docs[next + 1]) !== null && _tr$docs2 !== void 0 ? _tr$docs2 : tr.doc;
|
|
178
|
+
// Mapping biases +1 (right) and -1 (left) keep boundary insertions outside
|
|
179
|
+
// the tracked content. These arguments do not add/subtract document positions.
|
|
180
|
+
var start = map.mapResult(contentFrom, 1);
|
|
181
|
+
var end = map.mapResult(contentTo, -1);
|
|
182
|
+
if (start.deleted && end.deleted || end.pos <= start.pos) {
|
|
183
|
+
// A cumulative replacement can preserve the candidate content or owned markup.
|
|
184
|
+
// Check every intermediate doc so deletion then reinsertion never resurrects it.
|
|
185
|
+
var preserved = findPreservedNode(after, node, range.markupChanged, indexes);
|
|
186
|
+
if (!preserved) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
from = preserved.pos;
|
|
190
|
+
to = from + preserved.node.nodeSize;
|
|
191
|
+
contentFrom = from + 1;
|
|
192
|
+
contentTo = to - 1;
|
|
193
|
+
node = preserved.node;
|
|
194
|
+
} else {
|
|
195
|
+
// Apply the same inward biases to the outer node bounds.
|
|
196
|
+
from = map.map(from, 1);
|
|
197
|
+
to = map.map(to, -1);
|
|
198
|
+
contentFrom = start.pos;
|
|
199
|
+
contentTo = end.pos;
|
|
200
|
+
var current = after.nodeAt(from);
|
|
201
|
+
if (current && current.nodeSize === to - from) {
|
|
202
|
+
node = current;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (from < 0 || to > tr.doc.content.size || contentTo <= contentFrom) {
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
var finalNode = tr.doc.nodeAt(from);
|
|
210
|
+
if (finalNode !== null && finalNode !== void 0 && finalNode.isBlock && finalNode.nodeSize === to - from) {
|
|
211
|
+
return [{
|
|
212
|
+
from: from,
|
|
213
|
+
to: to
|
|
214
|
+
}];
|
|
215
|
+
}
|
|
216
|
+
// Joins/splits can leave mapped boundaries inside the final textblock.
|
|
217
|
+
var blocks = [];
|
|
218
|
+
tr.doc.nodesBetween(contentFrom, contentTo, function (child, pos) {
|
|
219
|
+
if (child.isTextblock) {
|
|
220
|
+
blocks.push({
|
|
221
|
+
from: pos,
|
|
222
|
+
to: pos + child.nodeSize
|
|
223
|
+
});
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
return blocks;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Returns whole content-block ranges for selected applied steps, in tr.doc coordinates.
|
|
232
|
+
* Callers select actual AI writes (excluding restores, acknowledgments and preparation)
|
|
233
|
+
* and own experiment/lifecycle decisions. This helper does not dispatch or render.
|
|
234
|
+
*
|
|
235
|
+
* Comparing each step's snapshots also handles attribute/mark steps with empty maps.
|
|
236
|
+
* Shared unchanged subtrees are skipped by reference. Only localId changes are ignored;
|
|
237
|
+
* meaningful attributes and marks retain the affected node's full content scope.
|
|
238
|
+
*/
|
|
239
|
+
export function getAgentEditChangedRanges(tr, includedStepIndexes) {
|
|
240
|
+
// Positions belong to each intermediate document, not just tr.doc. Keep the
|
|
241
|
+
// lazy indexes local to this call so deletion/reinsertion checks stay intact
|
|
242
|
+
// and no cache is retained between transactions or streaming chunks.
|
|
243
|
+
var indexes = new WeakMap();
|
|
244
|
+
var ranges = [];
|
|
245
|
+
var _iterator2 = _createForOfIteratorHelper(new Set(includedStepIndexes)),
|
|
246
|
+
_step2;
|
|
247
|
+
try {
|
|
248
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
249
|
+
var _tr$docs3;
|
|
250
|
+
var index = _step2.value;
|
|
251
|
+
if (!Number.isInteger(index) || index < 0 || index >= tr.steps.length) {
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
var changed = [];
|
|
255
|
+
// The root document has no opening boundary. Using -1 makes the recursive
|
|
256
|
+
// parent.pos + 1 + offset formula place its first child at position 0.
|
|
257
|
+
_collectChanges({
|
|
258
|
+
node: tr.docs[index],
|
|
259
|
+
pos: -1
|
|
260
|
+
}, {
|
|
261
|
+
node: (_tr$docs3 = tr.docs[index + 1]) !== null && _tr$docs3 !== void 0 ? _tr$docs3 : tr.doc,
|
|
262
|
+
pos: -1
|
|
263
|
+
}, tr.steps[index].getMap(), changed);
|
|
264
|
+
for (var _i = 0, _changed = changed; _i < _changed.length; _i++) {
|
|
265
|
+
var range = _changed[_i];
|
|
266
|
+
ranges.push.apply(ranges, _toConsumableArray(mapToFinalBlocks(tr, index, range, indexes)));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Return only the surviving final-document ranges, never intermediate step states.
|
|
271
|
+
// Sort outer ranges before their children, then discard duplicates/contained ranges.
|
|
272
|
+
// Separate ranges stay separate; this must not highlight the untouched gaps.
|
|
273
|
+
} catch (err) {
|
|
274
|
+
_iterator2.e(err);
|
|
275
|
+
} finally {
|
|
276
|
+
_iterator2.f();
|
|
277
|
+
}
|
|
278
|
+
var unique = [];
|
|
279
|
+
var _iterator3 = _createForOfIteratorHelper(ranges.sort(function (left, right) {
|
|
280
|
+
return left.from - right.from || right.to - left.to;
|
|
281
|
+
})),
|
|
282
|
+
_step3;
|
|
283
|
+
try {
|
|
284
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
285
|
+
var _range = _step3.value;
|
|
286
|
+
var previous = unique[unique.length - 1];
|
|
287
|
+
if (!previous || _range.to > previous.to) {
|
|
288
|
+
unique.push(_range);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
} catch (err) {
|
|
292
|
+
_iterator3.e(err);
|
|
293
|
+
} finally {
|
|
294
|
+
_iterator3.f();
|
|
295
|
+
}
|
|
296
|
+
return unique;
|
|
297
|
+
}
|
|
@@ -19,7 +19,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
19
19
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
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 = "122.
|
|
22
|
+
var packageVersion = "122.5.0";
|
|
23
23
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
24
24
|
// Remove URL as it has UGC
|
|
25
25
|
// Ignored via go/ees007
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
2
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
3
2
|
export var getFormattedNode = function getFormattedNode(tr) {
|
|
4
3
|
var selection = tr.selection;
|
|
5
4
|
var nodes = tr.doc.type.schema.nodes;
|
|
6
|
-
|
|
7
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
8
|
-
// but keep this solution general
|
|
9
|
-
var isBlockTaskItemEnabled = !!nodes.blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
5
|
+
var isBlockTaskItemEnabled = !!nodes.blockTaskItem;
|
|
10
6
|
|
|
11
7
|
// Find the node to format from the current selection
|
|
12
8
|
var nodeToFormat;
|
|
@@ -3,7 +3,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
3
3
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
4
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
5
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
6
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
6
|
import { convertBlockToInlineContent } from './convertBlockToInlineContent';
|
|
8
7
|
import { createBlockTaskItem } from './createBlockTaskItem';
|
|
9
8
|
import { isBulletOrOrderedList } from './isBulletOrOrderedList';
|
|
@@ -35,10 +34,7 @@ var _transformListRecursively = function transformListRecursively(props, onhandl
|
|
|
35
34
|
taskItem = _schema$nodes.taskItem,
|
|
36
35
|
paragraph = _schema$nodes.paragraph,
|
|
37
36
|
blockTaskItem = _schema$nodes.blockTaskItem;
|
|
38
|
-
|
|
39
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
40
|
-
// but keep this solution general
|
|
41
|
-
var isBlockTaskEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
37
|
+
var isBlockTaskEnabled = !!blockTaskItem;
|
|
42
38
|
|
|
43
39
|
/**
|
|
44
40
|
* Extracts paragraph children from a blockTaskItem, preserving their marks.
|
|
@@ -199,9 +195,7 @@ export var transformToTaskList = function transformToTaskList(tr, range, targetN
|
|
|
199
195
|
var taskItem = nodes.taskItem,
|
|
200
196
|
paragraph = nodes.paragraph,
|
|
201
197
|
blockTaskItem = nodes.blockTaskItem;
|
|
202
|
-
|
|
203
|
-
// but keep this solution general
|
|
204
|
-
var isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
198
|
+
var isBlockTaskItemEnabled = !!blockTaskItem;
|
|
205
199
|
var listItems = [];
|
|
206
200
|
|
|
207
201
|
// Process each block in the range
|
|
@@ -3,7 +3,6 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
3
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
4
|
import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
|
|
5
5
|
import { findChildrenByType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
-
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
7
6
|
export var transformTaskListToBlockNodes = function transformTaskListToBlockNodes(context) {
|
|
8
7
|
var tr = context.tr,
|
|
9
8
|
targetNodeType = context.targetNodeType,
|
|
@@ -13,10 +12,7 @@ export var transformTaskListToBlockNodes = function transformTaskListToBlockNode
|
|
|
13
12
|
var selection = tr.selection;
|
|
14
13
|
var schema = selection.$from.doc.type.schema;
|
|
15
14
|
var blockTaskItem = schema.nodes.blockTaskItem;
|
|
16
|
-
|
|
17
|
-
// gating behind platform_editor_small_font_size to support task lists with font size applied,
|
|
18
|
-
// but keep this solution general
|
|
19
|
-
var isBlockTaskItemEnabled = !!blockTaskItem && expValEquals('platform_editor_small_font_size', 'isEnabled', true);
|
|
15
|
+
var isBlockTaskItemEnabled = !!blockTaskItem;
|
|
20
16
|
if (isBlockTaskItemEnabled) {
|
|
21
17
|
var blockTaskItemsResult = findChildrenByType(sourceNode, blockTaskItem);
|
|
22
18
|
if (blockTaskItemsResult.length > 0 && targetNodeType === schema.nodes.paragraph) {
|
|
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
21
21
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
22
22
|
import Layer from '../Layer';
|
|
23
23
|
var packageName = "@atlaskit/editor-common";
|
|
24
|
-
var packageVersion = "122.
|
|
24
|
+
var packageVersion = "122.5.0";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
import type { AgentEditChromeRange } from './agent-edit-chrome';
|
|
3
|
+
/**
|
|
4
|
+
* Returns whole content-block ranges for selected applied steps, in tr.doc coordinates.
|
|
5
|
+
* Callers select actual AI writes (excluding restores, acknowledgments and preparation)
|
|
6
|
+
* and own experiment/lifecycle decisions. This helper does not dispatch or render.
|
|
7
|
+
*
|
|
8
|
+
* Comparing each step's snapshots also handles attribute/mark steps with empty maps.
|
|
9
|
+
* Shared unchanged subtrees are skipped by reference. Only localId changes are ignored;
|
|
10
|
+
* meaningful attributes and marks retain the affected node's full content scope.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getAgentEditChangedRanges(tr: Transaction, includedStepIndexes: readonly number[]): AgentEditChromeRange[];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import type { Placement } from '@atlaskit/popper/main';
|
|
2
3
|
import type { ProfileCardAction } from '@atlaskit/profilecard/types';
|
|
3
4
|
import type ProfileClient from '@atlaskit/profilecard/profile-card-client';
|
|
4
5
|
/**
|
|
@@ -16,8 +17,12 @@ import type ProfileClient from '@atlaskit/profilecard/profile-card-client';
|
|
|
16
17
|
export type RenderUserMentionCard = (props: {
|
|
17
18
|
children: ReactNode;
|
|
18
19
|
cloudId: string;
|
|
20
|
+
/** Renders a reduced, non-interactive card with the header + manager section only */
|
|
21
|
+
isReduced?: boolean;
|
|
19
22
|
/** Optional mention-local marker supplied by the renderer. */
|
|
20
23
|
localId?: string;
|
|
24
|
+
/** Popper placement for the card relative to the `referenceElement`. */
|
|
25
|
+
placement?: Placement;
|
|
21
26
|
/** Known identity to prefill the card with, giving its trigger a concrete accessible name. */
|
|
22
27
|
prefilledProfileData?: {
|
|
23
28
|
accountId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-common",
|
|
3
|
-
"version": "122.
|
|
3
|
+
"version": "122.6.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/"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@atlaskit/task-decision": "^21.10.0",
|
|
85
85
|
"@atlaskit/teams-app-config": "^3.1.0",
|
|
86
86
|
"@atlaskit/textfield": "^10.2.0",
|
|
87
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
87
|
+
"@atlaskit/tmp-editor-statsig": "^194.0.0",
|
|
88
88
|
"@atlaskit/tokens": "^16.12.0",
|
|
89
89
|
"@atlaskit/tooltip": "^24.3.0",
|
|
90
90
|
"@atlaskit/width-detector": "^7.2.0",
|