@atlaskit/editor-plugin-collab-edit 16.0.10 → 16.0.11
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 +19 -0
- package/dist/cjs/pm-plugins/main/agent-review-segments.js +34 -3
- package/dist/cjs/pm-plugins/main/agent-shimmer-ranges.js +50 -6
- package/dist/es2019/pm-plugins/main/agent-review-segments.js +33 -1
- package/dist/es2019/pm-plugins/main/agent-shimmer-ranges.js +46 -2
- package/dist/esm/pm-plugins/main/agent-review-segments.js +36 -4
- package/dist/esm/pm-plugins/main/agent-shimmer-ranges.js +49 -5
- package/dist/types/pm-plugins/main/agent-shimmer-ranges.d.ts +4 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-collab-edit
|
|
2
2
|
|
|
3
|
+
## 16.0.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`fd3620d4e137b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fd3620d4e137b) -
|
|
8
|
+
[CCI-18915] Surface and render formatting-only (mark) agent edits in the AI Review Moment.
|
|
9
|
+
|
|
10
|
+
Mark-only agent steps (`AddMarkStep`/`RemoveMarkStep` — e.g. making text bold, italic, or a link)
|
|
11
|
+
have an empty `StepMap`, so the agent review-segment and shimmer builders — which derived their
|
|
12
|
+
changed ranges purely from `StepMap` geometry — never produced a range for them. As a result a
|
|
13
|
+
formatting-only agent edit opened no Review Moment and showed no shimmer. Both builders now detect
|
|
14
|
+
mark steps and derive their range from `step.from`/`step.to`.
|
|
15
|
+
|
|
16
|
+
The smart-diff token encoder additionally folds each character's marks (type + attrs) into its
|
|
17
|
+
token, so once the moment opens the change renders as a real diff (e.g. a bold-only edit, or a
|
|
18
|
+
link whose `href` changes) instead of an empty one.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 16.0.10
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getAgentEditSegments = exports.REVIEW_MOMENT_AGENT_TYPES_CONFIG = void 0;
|
|
7
7
|
var _collabAgentReviewSliceCompare = require("@atlaskit/editor-common/collab-agent-review-slice-compare");
|
|
8
|
+
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
8
9
|
var _expVal = require("@atlaskit/platform-feature-experiments/exp-val");
|
|
9
10
|
var _prosemirrorCollab = require("@atlaskit/prosemirror-collab");
|
|
10
11
|
var _agentEditRequester = require("./agent-edit-requester");
|
|
@@ -150,6 +151,36 @@ var getAgentEditSegments = exports.getAgentEditSegments = function getAgentEditS
|
|
|
150
151
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
151
152
|
return;
|
|
152
153
|
}
|
|
154
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
155
|
+
// Derive their range from step.from/.to so a formatting-only agent edit still becomes a segment.
|
|
156
|
+
var markRange = (0, _agentShimmerRanges.getMarkStepRange)(steps[index]);
|
|
157
|
+
if (markRange) {
|
|
158
|
+
var mappedFrom = mapToFinalDoc(steps, markRange.from, index, -1);
|
|
159
|
+
var mappedTo = mapToFinalDoc(steps, markRange.to, index, 1);
|
|
160
|
+
var mappedOrigFrom = mapToBeforeDoc(steps, markRange.from, index, -1);
|
|
161
|
+
var mappedOrigTo = mapToBeforeDoc(steps, markRange.to, index, 1);
|
|
162
|
+
if (mappedTo > mappedFrom) {
|
|
163
|
+
try {
|
|
164
|
+
var before = tr.before.slice(mappedOrigFrom, mappedOrigTo);
|
|
165
|
+
var after = tr.doc.slice(mappedFrom, mappedTo);
|
|
166
|
+
if (!before.content.eq(after.content)) {
|
|
167
|
+
ranges.push({
|
|
168
|
+
from: mappedFrom,
|
|
169
|
+
to: mappedTo,
|
|
170
|
+
origFrom: mappedOrigFrom,
|
|
171
|
+
origTo: mappedOrigTo
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
} catch (error) {
|
|
175
|
+
// Degrade gracefully (skip this step's range) but track the error so a silent
|
|
176
|
+
// fall-through does not hide a systemic slicing problem.
|
|
177
|
+
(0, _monitoring.logException)(error, {
|
|
178
|
+
location: 'editor-plugin-collab-edit/agent-review-segments/markStepSlice'
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
153
184
|
pmStep.getMap().forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
154
185
|
var mappedFrom = mapToFinalDoc(steps, newStart, index, -1);
|
|
155
186
|
var mappedTo = mapToFinalDoc(steps, newEnd, index, 1);
|
|
@@ -162,9 +193,9 @@ var getAgentEditSegments = exports.getAgentEditSegments = function getAgentEditS
|
|
|
162
193
|
// when byte-identical, so a real same-size replacement is preserved.
|
|
163
194
|
if (oldEnd - oldStart === newEnd - newStart) {
|
|
164
195
|
try {
|
|
165
|
-
var
|
|
166
|
-
var
|
|
167
|
-
if (
|
|
196
|
+
var _before = tr.before.slice(oldStart, oldEnd);
|
|
197
|
+
var _after = tr.doc.slice(mappedFrom, mappedTo);
|
|
198
|
+
if (_before.content.eq(_after.content)) {
|
|
168
199
|
return;
|
|
169
200
|
}
|
|
170
201
|
} catch (_unused) {
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isPositionNeutralStep = exports.getAgentShimmerRanges = void 0;
|
|
6
|
+
exports.isPositionNeutralStep = exports.getMarkStepRange = exports.getAgentShimmerRanges = void 0;
|
|
7
7
|
var _collabAgentReviewSliceCompare = require("@atlaskit/editor-common/collab-agent-review-slice-compare");
|
|
8
|
+
var _monitoring = require("@atlaskit/editor-common/monitoring");
|
|
9
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
10
|
var _prosemirrorCollab = require("@atlaskit/prosemirror-collab");
|
|
9
11
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
10
12
|
// When an agent step lands we cover the top-level block(s) it wrote with a skeleton-loader shimmer
|
|
@@ -28,6 +30,20 @@ var isPositionNeutralStep = exports.isPositionNeutralStep = function isPositionN
|
|
|
28
30
|
return neutral;
|
|
29
31
|
};
|
|
30
32
|
|
|
33
|
+
// Mark-only steps (AddMarkStep / RemoveMarkStep) change no positions, so their StepMap is empty and
|
|
34
|
+
// `getMap().forEach` never yields a range. Their affected span is carried directly on `step.from` /
|
|
35
|
+
// `step.to` (valid in the step's input-doc coordinates). Returning it lets the range builders below
|
|
36
|
+
// treat a formatting-only agent edit (e.g. bold) as a real change rather than silently dropping it.
|
|
37
|
+
var getMarkStepRange = exports.getMarkStepRange = function getMarkStepRange(step) {
|
|
38
|
+
if (step instanceof _transform.AddMarkStep || step instanceof _transform.RemoveMarkStep) {
|
|
39
|
+
return {
|
|
40
|
+
from: step.from,
|
|
41
|
+
to: step.to
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
};
|
|
46
|
+
|
|
31
47
|
// Top-level block/position helpers over a doc. Kept at module scope (rather than re-created as
|
|
32
48
|
// closures on every call) so they are defined once, reusable, and unit-testable. Each clamps into
|
|
33
49
|
// valid document coordinates before resolving.
|
|
@@ -121,7 +137,7 @@ var getAgentShimmerRanges = exports.getAgentShimmerRanges = function getAgentShi
|
|
|
121
137
|
|
|
122
138
|
var infos = [];
|
|
123
139
|
json.forEach(function (rawStep, index) {
|
|
124
|
-
var _tr$docs$
|
|
140
|
+
var _tr$docs$index2;
|
|
125
141
|
if (typeof (rawStep === null || rawStep === void 0 ? void 0 : rawStep.agentType) !== 'string') {
|
|
126
142
|
return;
|
|
127
143
|
}
|
|
@@ -130,9 +146,37 @@ var getAgentShimmerRanges = exports.getAgentShimmerRanges = function getAgentShi
|
|
|
130
146
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
131
147
|
return;
|
|
132
148
|
}
|
|
149
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
150
|
+
// Derive their range from step.from/.to instead so formatting-only agent edits still shimmer.
|
|
151
|
+
var markRange = getMarkStepRange(steps[index]);
|
|
152
|
+
if (markRange) {
|
|
153
|
+
var _tr$docs$index;
|
|
154
|
+
var beforeDocForMark = (_tr$docs$index = tr.docs[index]) !== null && _tr$docs$index !== void 0 ? _tr$docs$index : tr.before;
|
|
155
|
+
var from = mapToFinalDoc(markRange.from, index, -1);
|
|
156
|
+
var to = mapToFinalDoc(markRange.to, index, 1);
|
|
157
|
+
if (to > from) {
|
|
158
|
+
try {
|
|
159
|
+
var before = beforeDocForMark.slice(markRange.from, markRange.to);
|
|
160
|
+
var after = tr.doc.slice(from, to);
|
|
161
|
+
if (!(0, _collabAgentReviewSliceCompare.slicesEqualIgnoringLocalId)(before, after)) {
|
|
162
|
+
infos.push({
|
|
163
|
+
from: from,
|
|
164
|
+
to: to
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
} catch (error) {
|
|
168
|
+
// Degrade gracefully (no shimmer for this step) but track the error so a silent
|
|
169
|
+
// fall-through does not hide a systemic slicing problem.
|
|
170
|
+
(0, _monitoring.logException)(error, {
|
|
171
|
+
location: 'editor-plugin-collab-edit/agent-shimmer-ranges/markStepSlice'
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
133
177
|
// The doc this step was applied to (its `old` coords resolve here). `tr.docs[index]` is the
|
|
134
178
|
// document state before step `index`; fall back to the batch's before-doc for the first step.
|
|
135
|
-
var beforeDoc = (_tr$docs$
|
|
179
|
+
var beforeDoc = (_tr$docs$index2 = tr.docs[index]) !== null && _tr$docs$index2 !== void 0 ? _tr$docs$index2 : tr.before;
|
|
136
180
|
pmStep.getMap().forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
137
181
|
if (newEnd <= newStart) {
|
|
138
182
|
return; // pure deletion / attribute-only — no new content to highlight
|
|
@@ -145,9 +189,9 @@ var getAgentShimmerRanges = exports.getAgentShimmerRanges = function getAgentShi
|
|
|
145
189
|
// still shimmer. Mirrors the Review-moment segment producer's guard.
|
|
146
190
|
if (oldEnd - oldStart === newEnd - newStart) {
|
|
147
191
|
try {
|
|
148
|
-
var
|
|
149
|
-
var
|
|
150
|
-
if ((0, _collabAgentReviewSliceCompare.slicesEqualIgnoringLocalId)(
|
|
192
|
+
var _before = beforeDoc.slice(oldStart, oldEnd);
|
|
193
|
+
var _after = tr.doc.slice(from, to);
|
|
194
|
+
if ((0, _collabAgentReviewSliceCompare.slicesEqualIgnoringLocalId)(_before, _after)) {
|
|
151
195
|
return;
|
|
152
196
|
}
|
|
153
197
|
} catch (_unused) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { slicesEqualIgnoringLocalId } from '@atlaskit/editor-common/collab-agent-review-slice-compare';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
2
3
|
import { expVal } from '@atlaskit/platform-feature-experiments/exp-val';
|
|
3
4
|
import { getCollabState } from '@atlaskit/prosemirror-collab';
|
|
4
5
|
import { getAgentEditRequester } from './agent-edit-requester';
|
|
5
|
-
import { isPositionNeutralStep } from './agent-shimmer-ranges';
|
|
6
|
+
import { getMarkStepRange, isPositionNeutralStep } from './agent-shimmer-ranges';
|
|
7
|
+
|
|
6
8
|
// Statsig dynamic config: which BE-streaming `agentType` values may open Review Moment.
|
|
7
9
|
// Code default is `[]` (fail closed) until the list is set in Statsig.
|
|
8
10
|
export const REVIEW_MOMENT_AGENT_TYPES_CONFIG = 'platform_editor_backend_review_moment_agent_types';
|
|
@@ -136,6 +138,36 @@ export const getAgentEditSegments = (json, steps, tr, view) => {
|
|
|
136
138
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
141
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
142
|
+
// Derive their range from step.from/.to so a formatting-only agent edit still becomes a segment.
|
|
143
|
+
const markRange = getMarkStepRange(steps[index]);
|
|
144
|
+
if (markRange) {
|
|
145
|
+
const mappedFrom = mapToFinalDoc(steps, markRange.from, index, -1);
|
|
146
|
+
const mappedTo = mapToFinalDoc(steps, markRange.to, index, 1);
|
|
147
|
+
const mappedOrigFrom = mapToBeforeDoc(steps, markRange.from, index, -1);
|
|
148
|
+
const mappedOrigTo = mapToBeforeDoc(steps, markRange.to, index, 1);
|
|
149
|
+
if (mappedTo > mappedFrom) {
|
|
150
|
+
try {
|
|
151
|
+
const before = tr.before.slice(mappedOrigFrom, mappedOrigTo);
|
|
152
|
+
const after = tr.doc.slice(mappedFrom, mappedTo);
|
|
153
|
+
if (!before.content.eq(after.content)) {
|
|
154
|
+
ranges.push({
|
|
155
|
+
from: mappedFrom,
|
|
156
|
+
to: mappedTo,
|
|
157
|
+
origFrom: mappedOrigFrom,
|
|
158
|
+
origTo: mappedOrigTo
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
// Degrade gracefully (skip this step's range) but track the error so a silent
|
|
163
|
+
// fall-through does not hide a systemic slicing problem.
|
|
164
|
+
logException(error, {
|
|
165
|
+
location: 'editor-plugin-collab-edit/agent-review-segments/markStepSlice'
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
139
171
|
pmStep.getMap().forEach((oldStart, oldEnd, newStart, newEnd) => {
|
|
140
172
|
const mappedFrom = mapToFinalDoc(steps, newStart, index, -1);
|
|
141
173
|
const mappedTo = mapToFinalDoc(steps, newEnd, index, 1);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { slicesEqualIgnoringLocalId } from '@atlaskit/editor-common/collab-agent-review-slice-compare';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
|
+
import { AddMarkStep, RemoveMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
4
|
import { getCollabState } from '@atlaskit/prosemirror-collab';
|
|
3
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
6
|
// When an agent step lands we cover the top-level block(s) it wrote with a skeleton-loader shimmer
|
|
@@ -22,6 +24,20 @@ export const isPositionNeutralStep = step => {
|
|
|
22
24
|
return neutral;
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
// Mark-only steps (AddMarkStep / RemoveMarkStep) change no positions, so their StepMap is empty and
|
|
28
|
+
// `getMap().forEach` never yields a range. Their affected span is carried directly on `step.from` /
|
|
29
|
+
// `step.to` (valid in the step's input-doc coordinates). Returning it lets the range builders below
|
|
30
|
+
// treat a formatting-only agent edit (e.g. bold) as a real change rather than silently dropping it.
|
|
31
|
+
export const getMarkStepRange = step => {
|
|
32
|
+
if (step instanceof AddMarkStep || step instanceof RemoveMarkStep) {
|
|
33
|
+
return {
|
|
34
|
+
from: step.from,
|
|
35
|
+
to: step.to
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
|
|
25
41
|
// Top-level block/position helpers over a doc. Kept at module scope (rather than re-created as
|
|
26
42
|
// closures on every call) so they are defined once, reusable, and unit-testable. Each clamps into
|
|
27
43
|
// valid document coordinates before resolving.
|
|
@@ -107,7 +123,7 @@ export const getAgentShimmerRanges = (json, steps, tr, view, shimmerDurationMs,
|
|
|
107
123
|
|
|
108
124
|
const infos = [];
|
|
109
125
|
json.forEach((rawStep, index) => {
|
|
110
|
-
var _tr$docs$
|
|
126
|
+
var _tr$docs$index2;
|
|
111
127
|
if (typeof (rawStep === null || rawStep === void 0 ? void 0 : rawStep.agentType) !== 'string') {
|
|
112
128
|
return;
|
|
113
129
|
}
|
|
@@ -116,9 +132,37 @@ export const getAgentShimmerRanges = (json, steps, tr, view, shimmerDurationMs,
|
|
|
116
132
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
117
133
|
return;
|
|
118
134
|
}
|
|
135
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
136
|
+
// Derive their range from step.from/.to instead so formatting-only agent edits still shimmer.
|
|
137
|
+
const markRange = getMarkStepRange(steps[index]);
|
|
138
|
+
if (markRange) {
|
|
139
|
+
var _tr$docs$index;
|
|
140
|
+
const beforeDocForMark = (_tr$docs$index = tr.docs[index]) !== null && _tr$docs$index !== void 0 ? _tr$docs$index : tr.before;
|
|
141
|
+
const from = mapToFinalDoc(markRange.from, index, -1);
|
|
142
|
+
const to = mapToFinalDoc(markRange.to, index, 1);
|
|
143
|
+
if (to > from) {
|
|
144
|
+
try {
|
|
145
|
+
const before = beforeDocForMark.slice(markRange.from, markRange.to);
|
|
146
|
+
const after = tr.doc.slice(from, to);
|
|
147
|
+
if (!slicesEqualIgnoringLocalId(before, after)) {
|
|
148
|
+
infos.push({
|
|
149
|
+
from,
|
|
150
|
+
to
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
// Degrade gracefully (no shimmer for this step) but track the error so a silent
|
|
155
|
+
// fall-through does not hide a systemic slicing problem.
|
|
156
|
+
logException(error, {
|
|
157
|
+
location: 'editor-plugin-collab-edit/agent-shimmer-ranges/markStepSlice'
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
119
163
|
// The doc this step was applied to (its `old` coords resolve here). `tr.docs[index]` is the
|
|
120
164
|
// document state before step `index`; fall back to the batch's before-doc for the first step.
|
|
121
|
-
const beforeDoc = (_tr$docs$
|
|
165
|
+
const beforeDoc = (_tr$docs$index2 = tr.docs[index]) !== null && _tr$docs$index2 !== void 0 ? _tr$docs$index2 : tr.before;
|
|
122
166
|
pmStep.getMap().forEach((oldStart, oldEnd, newStart, newEnd) => {
|
|
123
167
|
if (newEnd <= newStart) {
|
|
124
168
|
return; // pure deletion / attribute-only — no new content to highlight
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { slicesEqualIgnoringLocalId } from '@atlaskit/editor-common/collab-agent-review-slice-compare';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
2
3
|
import { expVal } from '@atlaskit/platform-feature-experiments/exp-val';
|
|
3
4
|
import { getCollabState } from '@atlaskit/prosemirror-collab';
|
|
4
5
|
import { getAgentEditRequester } from './agent-edit-requester';
|
|
5
|
-
import { isPositionNeutralStep } from './agent-shimmer-ranges';
|
|
6
|
+
import { getMarkStepRange, isPositionNeutralStep } from './agent-shimmer-ranges';
|
|
7
|
+
|
|
6
8
|
// Statsig dynamic config: which BE-streaming `agentType` values may open Review Moment.
|
|
7
9
|
// Code default is `[]` (fail closed) until the list is set in Statsig.
|
|
8
10
|
export var REVIEW_MOMENT_AGENT_TYPES_CONFIG = 'platform_editor_backend_review_moment_agent_types';
|
|
@@ -144,6 +146,36 @@ export var getAgentEditSegments = function getAgentEditSegments(json, steps, tr,
|
|
|
144
146
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
145
147
|
return;
|
|
146
148
|
}
|
|
149
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
150
|
+
// Derive their range from step.from/.to so a formatting-only agent edit still becomes a segment.
|
|
151
|
+
var markRange = getMarkStepRange(steps[index]);
|
|
152
|
+
if (markRange) {
|
|
153
|
+
var mappedFrom = mapToFinalDoc(steps, markRange.from, index, -1);
|
|
154
|
+
var mappedTo = mapToFinalDoc(steps, markRange.to, index, 1);
|
|
155
|
+
var mappedOrigFrom = mapToBeforeDoc(steps, markRange.from, index, -1);
|
|
156
|
+
var mappedOrigTo = mapToBeforeDoc(steps, markRange.to, index, 1);
|
|
157
|
+
if (mappedTo > mappedFrom) {
|
|
158
|
+
try {
|
|
159
|
+
var before = tr.before.slice(mappedOrigFrom, mappedOrigTo);
|
|
160
|
+
var after = tr.doc.slice(mappedFrom, mappedTo);
|
|
161
|
+
if (!before.content.eq(after.content)) {
|
|
162
|
+
ranges.push({
|
|
163
|
+
from: mappedFrom,
|
|
164
|
+
to: mappedTo,
|
|
165
|
+
origFrom: mappedOrigFrom,
|
|
166
|
+
origTo: mappedOrigTo
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
// Degrade gracefully (skip this step's range) but track the error so a silent
|
|
171
|
+
// fall-through does not hide a systemic slicing problem.
|
|
172
|
+
logException(error, {
|
|
173
|
+
location: 'editor-plugin-collab-edit/agent-review-segments/markStepSlice'
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
147
179
|
pmStep.getMap().forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
148
180
|
var mappedFrom = mapToFinalDoc(steps, newStart, index, -1);
|
|
149
181
|
var mappedTo = mapToFinalDoc(steps, newEnd, index, 1);
|
|
@@ -156,9 +188,9 @@ export var getAgentEditSegments = function getAgentEditSegments(json, steps, tr,
|
|
|
156
188
|
// when byte-identical, so a real same-size replacement is preserved.
|
|
157
189
|
if (oldEnd - oldStart === newEnd - newStart) {
|
|
158
190
|
try {
|
|
159
|
-
var
|
|
160
|
-
var
|
|
161
|
-
if (
|
|
191
|
+
var _before = tr.before.slice(oldStart, oldEnd);
|
|
192
|
+
var _after = tr.doc.slice(mappedFrom, mappedTo);
|
|
193
|
+
if (_before.content.eq(_after.content)) {
|
|
162
194
|
return;
|
|
163
195
|
}
|
|
164
196
|
} catch (_unused) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { slicesEqualIgnoringLocalId } from '@atlaskit/editor-common/collab-agent-review-slice-compare';
|
|
2
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
3
|
+
import { AddMarkStep, RemoveMarkStep } from '@atlaskit/editor-prosemirror/transform';
|
|
2
4
|
import { getCollabState } from '@atlaskit/prosemirror-collab';
|
|
3
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
6
|
// When an agent step lands we cover the top-level block(s) it wrote with a skeleton-loader shimmer
|
|
@@ -22,6 +24,20 @@ export var isPositionNeutralStep = function isPositionNeutralStep(step) {
|
|
|
22
24
|
return neutral;
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
// Mark-only steps (AddMarkStep / RemoveMarkStep) change no positions, so their StepMap is empty and
|
|
28
|
+
// `getMap().forEach` never yields a range. Their affected span is carried directly on `step.from` /
|
|
29
|
+
// `step.to` (valid in the step's input-doc coordinates). Returning it lets the range builders below
|
|
30
|
+
// treat a formatting-only agent edit (e.g. bold) as a real change rather than silently dropping it.
|
|
31
|
+
export var getMarkStepRange = function getMarkStepRange(step) {
|
|
32
|
+
if (step instanceof AddMarkStep || step instanceof RemoveMarkStep) {
|
|
33
|
+
return {
|
|
34
|
+
from: step.from,
|
|
35
|
+
to: step.to
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
};
|
|
40
|
+
|
|
25
41
|
// Top-level block/position helpers over a doc. Kept at module scope (rather than re-created as
|
|
26
42
|
// closures on every call) so they are defined once, reusable, and unit-testable. Each clamps into
|
|
27
43
|
// valid document coordinates before resolving.
|
|
@@ -115,7 +131,7 @@ export var getAgentShimmerRanges = function getAgentShimmerRanges(json, steps, t
|
|
|
115
131
|
|
|
116
132
|
var infos = [];
|
|
117
133
|
json.forEach(function (rawStep, index) {
|
|
118
|
-
var _tr$docs$
|
|
134
|
+
var _tr$docs$index2;
|
|
119
135
|
if (typeof (rawStep === null || rawStep === void 0 ? void 0 : rawStep.agentType) !== 'string') {
|
|
120
136
|
return;
|
|
121
137
|
}
|
|
@@ -124,9 +140,37 @@ export var getAgentShimmerRanges = function getAgentShimmerRanges(json, steps, t
|
|
|
124
140
|
if (typeof (pmStep === null || pmStep === void 0 ? void 0 : pmStep.getMap) !== 'function') {
|
|
125
141
|
return;
|
|
126
142
|
}
|
|
143
|
+
// Mark-only steps have an empty StepMap, so the getMap().forEach below never fires for them.
|
|
144
|
+
// Derive their range from step.from/.to instead so formatting-only agent edits still shimmer.
|
|
145
|
+
var markRange = getMarkStepRange(steps[index]);
|
|
146
|
+
if (markRange) {
|
|
147
|
+
var _tr$docs$index;
|
|
148
|
+
var beforeDocForMark = (_tr$docs$index = tr.docs[index]) !== null && _tr$docs$index !== void 0 ? _tr$docs$index : tr.before;
|
|
149
|
+
var from = mapToFinalDoc(markRange.from, index, -1);
|
|
150
|
+
var to = mapToFinalDoc(markRange.to, index, 1);
|
|
151
|
+
if (to > from) {
|
|
152
|
+
try {
|
|
153
|
+
var before = beforeDocForMark.slice(markRange.from, markRange.to);
|
|
154
|
+
var after = tr.doc.slice(from, to);
|
|
155
|
+
if (!slicesEqualIgnoringLocalId(before, after)) {
|
|
156
|
+
infos.push({
|
|
157
|
+
from: from,
|
|
158
|
+
to: to
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
} catch (error) {
|
|
162
|
+
// Degrade gracefully (no shimmer for this step) but track the error so a silent
|
|
163
|
+
// fall-through does not hide a systemic slicing problem.
|
|
164
|
+
logException(error, {
|
|
165
|
+
location: 'editor-plugin-collab-edit/agent-shimmer-ranges/markStepSlice'
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
127
171
|
// The doc this step was applied to (its `old` coords resolve here). `tr.docs[index]` is the
|
|
128
172
|
// document state before step `index`; fall back to the batch's before-doc for the first step.
|
|
129
|
-
var beforeDoc = (_tr$docs$
|
|
173
|
+
var beforeDoc = (_tr$docs$index2 = tr.docs[index]) !== null && _tr$docs$index2 !== void 0 ? _tr$docs$index2 : tr.before;
|
|
130
174
|
pmStep.getMap().forEach(function (oldStart, oldEnd, newStart, newEnd) {
|
|
131
175
|
if (newEnd <= newStart) {
|
|
132
176
|
return; // pure deletion / attribute-only — no new content to highlight
|
|
@@ -139,9 +183,9 @@ export var getAgentShimmerRanges = function getAgentShimmerRanges(json, steps, t
|
|
|
139
183
|
// still shimmer. Mirrors the Review-moment segment producer's guard.
|
|
140
184
|
if (oldEnd - oldStart === newEnd - newStart) {
|
|
141
185
|
try {
|
|
142
|
-
var
|
|
143
|
-
var
|
|
144
|
-
if (slicesEqualIgnoringLocalId(
|
|
186
|
+
var _before = beforeDoc.slice(oldStart, oldEnd);
|
|
187
|
+
var _after = tr.doc.slice(from, to);
|
|
188
|
+
if (slicesEqualIgnoringLocalId(_before, _after)) {
|
|
145
189
|
return;
|
|
146
190
|
}
|
|
147
191
|
} catch (_unused) {
|
|
@@ -4,6 +4,10 @@ import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
|
4
4
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
5
5
|
import type { AgentShimmerRange } from './agent-shimmer-decorations';
|
|
6
6
|
export declare const isPositionNeutralStep: (step: Step) => boolean;
|
|
7
|
+
export declare const getMarkStepRange: (step: Step) => {
|
|
8
|
+
from: number;
|
|
9
|
+
to: number;
|
|
10
|
+
} | null;
|
|
7
11
|
/**
|
|
8
12
|
* Derive the shimmer ranges for the agent-authored steps in a received batch, in final-doc
|
|
9
13
|
* coordinates. `agentType` present ⇒ agent-authored (per the NCS↔Editor steps contract). Each
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-collab-edit",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.11",
|
|
4
4
|
"description": "Collab Edit plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@atlaskit/adf-schema": "^57.0.0",
|
|
23
23
|
"@atlaskit/custom-steps": "^1.0.0",
|
|
24
|
-
"@atlaskit/editor-json-transformer": "^9.
|
|
24
|
+
"@atlaskit/editor-json-transformer": "^9.5.0",
|
|
25
25
|
"@atlaskit/editor-plugin-analytics": "^15.0.0",
|
|
26
26
|
"@atlaskit/editor-plugin-connectivity": "^15.0.0",
|
|
27
27
|
"@atlaskit/editor-plugin-editor-viewmode": "^17.0.0",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
33
33
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
34
34
|
"@atlaskit/prosemirror-collab": "^1.0.0",
|
|
35
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
35
|
+
"@atlaskit/tmp-editor-statsig": "^156.0.0",
|
|
36
36
|
"@atlaskit/tokens": "^16.7.0",
|
|
37
37
|
"@babel/runtime": "^7.0.0",
|
|
38
38
|
"memoize-one": "^6.0.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@atlaskit/editor-common": "^119.
|
|
41
|
+
"@atlaskit/editor-common": "^119.12.0",
|
|
42
42
|
"react": "^18.2.0 || ^19.2.0",
|
|
43
43
|
"react-dom": "^18.2.0 || ^19.2.0"
|
|
44
44
|
},
|