@atlaskit/editor-plugin-show-diff 16.1.0 → 16.2.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 +33 -0
- package/afm-products/tsconfig.json +3 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
- package/dist/cjs/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +242 -26
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +71 -37
- package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +83 -3
- package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +123 -43
- package/dist/cjs/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/cjs/pm-plugins/decorations/utils/absorbFirstChildMarginReset.js +33 -0
- package/dist/cjs/pm-plugins/decorations/utils/createMarginAbsorber.js +43 -0
- package/dist/cjs/pm-plugins/decorations/utils/createNodeShapedMarginSpacer.js +76 -0
- package/dist/cjs/pm-plugins/decorations/utils/safeResolve.js +24 -0
- package/dist/cjs/pm-plugins/getScrollableDecorations.js +48 -19
- package/dist/cjs/pm-plugins/utils/baseNodeName.js +25 -0
- package/dist/cjs/pm-plugins/utils/taggableBlockNodes.js +37 -0
- package/dist/cjs/ui/ContributorTag/contributorTagController.js +4 -4
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +39 -2
- package/dist/es2019/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +196 -10
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +51 -19
- package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +3 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +23 -14
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +83 -3
- package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +60 -7
- package/dist/es2019/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/es2019/pm-plugins/decorations/utils/absorbFirstChildMarginReset.js +29 -0
- package/dist/es2019/pm-plugins/decorations/utils/createMarginAbsorber.js +39 -0
- package/dist/es2019/pm-plugins/decorations/utils/createNodeShapedMarginSpacer.js +69 -0
- package/dist/es2019/pm-plugins/decorations/utils/safeResolve.js +18 -0
- package/dist/es2019/pm-plugins/getScrollableDecorations.js +44 -19
- package/dist/es2019/pm-plugins/utils/baseNodeName.js +18 -0
- package/dist/es2019/pm-plugins/utils/taggableBlockNodes.js +28 -0
- package/dist/es2019/ui/ContributorTag/contributorTagController.js +4 -4
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
- package/dist/esm/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +243 -26
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +71 -37
- package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
- package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -2
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +83 -3
- package/dist/esm/pm-plugins/decorations/extractContributorTags.js +123 -43
- package/dist/esm/pm-plugins/decorations/revealStyles.js +5 -1
- package/dist/esm/pm-plugins/decorations/utils/absorbFirstChildMarginReset.js +28 -0
- package/dist/esm/pm-plugins/decorations/utils/createMarginAbsorber.js +37 -0
- package/dist/esm/pm-plugins/decorations/utils/createNodeShapedMarginSpacer.js +70 -0
- package/dist/esm/pm-plugins/decorations/utils/safeResolve.js +18 -0
- package/dist/esm/pm-plugins/getScrollableDecorations.js +48 -19
- package/dist/esm/pm-plugins/utils/baseNodeName.js +20 -0
- package/dist/esm/pm-plugins/utils/taggableBlockNodes.js +32 -0
- package/dist/esm/ui/ContributorTag/contributorTagController.js +4 -4
- package/dist/types/pm-plugins/calculateDiff/simplifyChangesWithAttribution.d.ts +20 -1
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +4 -11
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +9 -8
- package/dist/types/pm-plugins/decorations/utils/absorbFirstChildMarginReset.d.ts +23 -0
- package/dist/types/pm-plugins/decorations/utils/createMarginAbsorber.d.ts +23 -0
- package/dist/types/pm-plugins/decorations/utils/createNodeShapedMarginSpacer.d.ts +26 -0
- package/dist/types/pm-plugins/decorations/utils/safeResolve.d.ts +13 -0
- package/dist/types/pm-plugins/getScrollableDecorations.d.ts +2 -2
- package/dist/types/pm-plugins/utils/baseNodeName.d.ts +16 -0
- package/dist/types/pm-plugins/utils/taggableBlockNodes.d.ts +14 -0
- package/package.json +14 -5
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
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; }
|
|
3
3
|
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; }
|
|
4
|
+
import { agentBrandColorSchemes } from '@atlaskit/agent-color/agent-brand-color-schemes';
|
|
4
5
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
5
6
|
import { getStandardDeletedTextDecorationStyle } from './getStandardDeletedTextDecorationStyle';
|
|
6
7
|
|
|
@@ -118,40 +119,48 @@ var textAccentMap = {
|
|
|
118
119
|
gray: "var(--ds-text-accent-gray, #505258)",
|
|
119
120
|
lime: "var(--ds-text-accent-lime, #4C6B1F)"
|
|
120
121
|
};
|
|
122
|
+
var getBrand = function getBrand(color) {
|
|
123
|
+
return Object.prototype.hasOwnProperty.call(agentBrandColorSchemes, color) ? agentBrandColorSchemes[color] : undefined;
|
|
124
|
+
};
|
|
121
125
|
function bgSubtlest(color) {
|
|
122
|
-
|
|
126
|
+
var _getBrand$background, _getBrand;
|
|
127
|
+
return (_getBrand$background = (_getBrand = getBrand(color)) === null || _getBrand === void 0 ? void 0 : _getBrand.background) !== null && _getBrand$background !== void 0 ? _getBrand$background : bgSubtlestMap[color];
|
|
123
128
|
}
|
|
124
129
|
function bgSubtlestPressed(color) {
|
|
125
|
-
|
|
130
|
+
var _getBrand$background2, _getBrand2;
|
|
131
|
+
return (_getBrand$background2 = (_getBrand2 = getBrand(color)) === null || _getBrand2 === void 0 ? void 0 : _getBrand2.background) !== null && _getBrand$background2 !== void 0 ? _getBrand$background2 : bgSubtlestPressedMap[color];
|
|
126
132
|
}
|
|
127
133
|
function bgSubtler(color) {
|
|
128
|
-
|
|
134
|
+
var _getBrand$border, _getBrand3;
|
|
135
|
+
return (_getBrand$border = (_getBrand3 = getBrand(color)) === null || _getBrand3 === void 0 ? void 0 : _getBrand3.border) !== null && _getBrand$border !== void 0 ? _getBrand$border : bgSubtlerMap[color];
|
|
129
136
|
}
|
|
130
137
|
function bgBolder(color) {
|
|
131
|
-
|
|
138
|
+
var _getBrand$bold, _getBrand4;
|
|
139
|
+
return (_getBrand$bold = (_getBrand4 = getBrand(color)) === null || _getBrand4 === void 0 ? void 0 : _getBrand4.bold) !== null && _getBrand$bold !== void 0 ? _getBrand$bold : bgBolderMap[color];
|
|
132
140
|
}
|
|
133
141
|
function bgSubtlerPressed(color) {
|
|
134
|
-
|
|
142
|
+
var _getBrand$background3, _getBrand5;
|
|
143
|
+
return (_getBrand$background3 = (_getBrand5 = getBrand(color)) === null || _getBrand5 === void 0 ? void 0 : _getBrand5.background) !== null && _getBrand$background3 !== void 0 ? _getBrand$background3 : bgSubtlerPressedMap[color];
|
|
135
144
|
}
|
|
136
145
|
function borderAccent(color) {
|
|
137
|
-
|
|
146
|
+
var _getBrand$border2, _getBrand6;
|
|
147
|
+
return (_getBrand$border2 = (_getBrand6 = getBrand(color)) === null || _getBrand6 === void 0 ? void 0 : _getBrand6.border) !== null && _getBrand$border2 !== void 0 ? _getBrand$border2 : borderAccentMap[color];
|
|
138
148
|
}
|
|
139
149
|
function textAccent(color) {
|
|
140
|
-
|
|
150
|
+
var _getBrand$accentText, _getBrand7;
|
|
151
|
+
return (_getBrand$accentText = (_getBrand7 = getBrand(color)) === null || _getBrand7 === void 0 ? void 0 : _getBrand7.accentText) !== null && _getBrand$accentText !== void 0 ? _getBrand$accentText : textAccentMap[color];
|
|
152
|
+
}
|
|
153
|
+
function deletedBackground(color) {
|
|
154
|
+
var _getBrand$emphasisBac, _getBrand8;
|
|
155
|
+
return (_getBrand$emphasisBac = (_getBrand8 = getBrand(color)) === null || _getBrand8 === void 0 ? void 0 : _getBrand8.emphasisBackground) !== null && _getBrand$emphasisBac !== void 0 ? _getBrand$emphasisBac : bgSubtlest(color);
|
|
141
156
|
}
|
|
142
157
|
|
|
143
|
-
/**
|
|
144
|
-
* Presentation tokens for a contributor tag in one diff colour.
|
|
145
|
-
*
|
|
146
|
-
* A `bolder` fill rather than the `subtlest` tint the highlight uses: the tag is a label on the
|
|
147
|
-
* change, and at tag size a tint reads as a second, weaker highlight sitting above the real one.
|
|
148
|
-
* `inverse` is the only text tone that reads on a bolder fill, and it needs no per-colour map —
|
|
149
|
-
* which is also why the tag carries no border: the fill alone bounds it.
|
|
150
|
-
*/
|
|
158
|
+
/** Contributor tags use a bold fill with a contrasting foreground, including branded schemes. */
|
|
151
159
|
export function getAccentTokens(color) {
|
|
160
|
+
var _getBrand$boldText, _getBrand9;
|
|
152
161
|
return {
|
|
153
162
|
background: bgBolder(color),
|
|
154
|
-
text: "var(--ds-text-inverse, #FFFFFF)"
|
|
163
|
+
text: (_getBrand$boldText = (_getBrand9 = getBrand(color)) === null || _getBrand9 === void 0 ? void 0 : _getBrand9.boldText) !== null && _getBrand$boldText !== void 0 ? _getBrand$boldText : "var(--ds-text-inverse, #FFFFFF)"
|
|
155
164
|
};
|
|
156
165
|
}
|
|
157
166
|
|
|
@@ -173,18 +182,23 @@ function deletedCellOutline(colors) {
|
|
|
173
182
|
// --- Inserted content styles ---
|
|
174
183
|
|
|
175
184
|
function insertedInlineBorderColor(colors) {
|
|
176
|
-
|
|
185
|
+
var _getBrand$border3, _getBrand0;
|
|
186
|
+
return colors.insertedInlineBorderTone === 'backgroundHovered' ? (_getBrand$border3 = (_getBrand0 = getBrand(colors.insertColor)) === null || _getBrand0 === void 0 ? void 0 : _getBrand0.border) !== null && _getBrand$border3 !== void 0 ? _getBrand$border3 : bgSubtlestHoveredMap[colors.insertColor] : borderAccent(colors.insertColor);
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
/** Inline inserted content — default state. */
|
|
180
190
|
export function buildInsertStyle(colors) {
|
|
181
|
-
|
|
182
|
-
|
|
191
|
+
var brand = getBrand(colors.insertColor);
|
|
192
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
193
|
+
background: bgSubtlest(colors.insertColor)
|
|
194
|
+
}, brand ? {
|
|
195
|
+
color: brand.text
|
|
196
|
+
} : {}), {}, {
|
|
183
197
|
textDecoration: 'underline',
|
|
184
198
|
textDecorationStyle: colors.insertUnderlineStyle,
|
|
185
199
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
186
200
|
textDecorationColor: borderAccent(colors.insertColor)
|
|
187
|
-
});
|
|
201
|
+
}));
|
|
188
202
|
}
|
|
189
203
|
|
|
190
204
|
/** Inline insert style for content within a block node (no background, underline only). */
|
|
@@ -199,11 +213,15 @@ export function buildInsertStyleInBlock(colors) {
|
|
|
199
213
|
|
|
200
214
|
/** Extended insert style — background + border-bottom underline. */
|
|
201
215
|
export function buildInsertStyleExtended(colors) {
|
|
202
|
-
|
|
203
|
-
|
|
216
|
+
var brand = getBrand(colors.insertColor);
|
|
217
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
218
|
+
background: bgSubtlest(colors.insertColor)
|
|
219
|
+
}, brand ? {
|
|
220
|
+
color: brand.text
|
|
221
|
+
} : {}), {}, {
|
|
204
222
|
borderBottom: "2px solid ".concat(insertedInlineBorderColor(colors)),
|
|
205
223
|
padding: "1px 0 2px"
|
|
206
|
-
});
|
|
224
|
+
}));
|
|
207
225
|
}
|
|
208
226
|
|
|
209
227
|
/** Extended insert style for content within a block node (border-bottom only, no background). */
|
|
@@ -216,27 +234,39 @@ export function buildInsertStyleInBlockExtended(colors) {
|
|
|
216
234
|
|
|
217
235
|
/** Active state of the extended insert style. */
|
|
218
236
|
export function buildInsertStyleExtendedActive(colors) {
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
var brand = getBrand(colors.insertColor);
|
|
238
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
239
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
240
|
+
}, brand ? {
|
|
241
|
+
color: brand.text
|
|
242
|
+
} : {}), {}, {
|
|
221
243
|
borderBottom: "2px solid ".concat(borderAccent(colors.insertColor)),
|
|
222
244
|
padding: "1px 0 2px"
|
|
223
|
-
});
|
|
245
|
+
}));
|
|
224
246
|
}
|
|
225
247
|
|
|
226
248
|
/** Extended insert style without underline — background + padding only. */
|
|
227
249
|
export function buildInsertStyleExtendedNoUnderline(colors) {
|
|
228
|
-
|
|
229
|
-
|
|
250
|
+
var brand = getBrand(colors.insertColor);
|
|
251
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
252
|
+
background: bgSubtlest(colors.insertColor)
|
|
253
|
+
}, brand ? {
|
|
254
|
+
color: brand.text
|
|
255
|
+
} : {}), {}, {
|
|
230
256
|
padding: "1px 0 2px"
|
|
231
|
-
});
|
|
257
|
+
}));
|
|
232
258
|
}
|
|
233
259
|
|
|
234
260
|
/** Active state of the no-underline extended insert style. */
|
|
235
261
|
export function buildInsertStyleExtendedNoUnderlineActive(colors) {
|
|
236
|
-
|
|
237
|
-
|
|
262
|
+
var brand = getBrand(colors.insertColor);
|
|
263
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
264
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
265
|
+
}, brand ? {
|
|
266
|
+
color: brand.text
|
|
267
|
+
} : {}), {}, {
|
|
238
268
|
padding: "1px 0 2px"
|
|
239
|
-
});
|
|
269
|
+
}));
|
|
240
270
|
}
|
|
241
271
|
|
|
242
272
|
/** No-underline extended insert style for block content (padding only). */
|
|
@@ -248,13 +278,17 @@ export function buildInsertStyleInBlockExtendedNoUnderline(_colors) {
|
|
|
248
278
|
|
|
249
279
|
/** Inline inserted content — active/focused state. */
|
|
250
280
|
export function buildInsertStyleActive(colors) {
|
|
251
|
-
|
|
252
|
-
|
|
281
|
+
var brand = getBrand(colors.insertColor);
|
|
282
|
+
return convertToInlineCss(_objectSpread(_objectSpread({
|
|
283
|
+
background: bgSubtlerPressed(colors.insertActiveColor)
|
|
284
|
+
}, brand ? {
|
|
285
|
+
color: brand.text
|
|
286
|
+
} : {}), {}, {
|
|
253
287
|
textDecoration: 'underline',
|
|
254
288
|
textDecorationStyle: colors.insertUnderlineStyle,
|
|
255
289
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
256
290
|
textDecorationColor: textAccent(colors.insertActiveColor)
|
|
257
|
-
});
|
|
291
|
+
}));
|
|
258
292
|
}
|
|
259
293
|
|
|
260
294
|
// --- Deleted inline content styles ---
|
|
@@ -612,7 +646,7 @@ export function buildDeletedInlineContentStyleExtended(colors) {
|
|
|
612
646
|
// Under 'underline' emphasis the highlight stays on its resting tint — the same one hover paints —
|
|
613
647
|
// so only the border carries the emphasis.
|
|
614
648
|
var isUnderlineEmphasis = isActive && usesUnderlineEmphasis(colors);
|
|
615
|
-
var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) :
|
|
649
|
+
var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) : deletedBackground(colors.deleteColor);
|
|
616
650
|
var borderColor = isUnderlineEmphasis ? borderAccent(colors.deleteActiveColor) : colors.deletedInlineBorderTone === 'background' ? backgroundColor : borderAccent(colors.deleteColor);
|
|
617
651
|
return convertToInlineCss({
|
|
618
652
|
backgroundColor: backgroundColor,
|
|
@@ -822,7 +856,7 @@ export function getDeletedInlineRevealColors(colors) {
|
|
|
822
856
|
* paints at rest, so hovering restores the appearance rather than introducing a third one.
|
|
823
857
|
*/
|
|
824
858
|
export function getDeletedHighlightHoverColor(colors) {
|
|
825
|
-
return
|
|
859
|
+
return deletedBackground(colors.deleteColor);
|
|
826
860
|
}
|
|
827
861
|
|
|
828
862
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
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; }
|
|
3
3
|
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; }
|
|
4
|
+
import { agentBrandColorSchemes } from '@atlaskit/agent-color/agent-brand-color-schemes';
|
|
4
5
|
import { PARTICIPANT_COLOR_SCHEMES } from './types';
|
|
5
6
|
|
|
6
7
|
/** Green insertions, red deletions. */
|
|
@@ -78,9 +79,12 @@ var createAttributionScheme = function createAttributionScheme(color) {
|
|
|
78
79
|
var attributionColorSchemes = Object.fromEntries(PARTICIPANT_COLOR_SCHEMES.map(function (color) {
|
|
79
80
|
return [color, createAttributionScheme(color)];
|
|
80
81
|
}));
|
|
82
|
+
var brandSchemes = Object.fromEntries(Object.keys(agentBrandColorSchemes).map(function (scheme) {
|
|
83
|
+
return [scheme, createAttributionScheme(scheme)];
|
|
84
|
+
}));
|
|
81
85
|
|
|
82
86
|
/** Maps public schemes and attribution-only participant slots to their data objects. */
|
|
83
|
-
export var colorSchemeRegistry = _objectSpread(_objectSpread({}, attributionColorSchemes), {}, {
|
|
87
|
+
export var colorSchemeRegistry = _objectSpread(_objectSpread(_objectSpread({}, attributionColorSchemes), brandSchemes), {}, {
|
|
84
88
|
traditional: traditionalScheme,
|
|
85
89
|
standard: standardScheme
|
|
86
90
|
});
|
|
@@ -5,8 +5,6 @@ export var PARTICIPANT_COLOR_SCHEMES = ['red', 'blue', 'green', 'yellow', 'purpl
|
|
|
5
5
|
|
|
6
6
|
/** ADS accent hues used by the public and participant colour schemes. */
|
|
7
7
|
|
|
8
|
-
/** A public scheme or an attribution participant slot resolved internally for one change. */
|
|
9
|
-
|
|
10
8
|
/**
|
|
11
9
|
* A show-diff colour scheme. Colour fields are ADS hues that `factory.ts` expands into token paths;
|
|
12
10
|
* the rest encode structural differences no colour can express. Ring widths, padding, radius and
|
|
@@ -8,6 +8,7 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
8
8
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
10
10
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
11
|
+
import { isTaggableBlockNode } from '../utils/taggableBlockNodes';
|
|
11
12
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedBlockNodeStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildInsertedBlockNodeStyle } from './colorSchemes/factory';
|
|
12
13
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
13
14
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
@@ -27,13 +28,6 @@ var UNSTYLED_NODES = ['mediaSingle', 'mediaGroup', 'table',
|
|
|
27
28
|
'heading', 'hardBreak', 'decisionList', 'taskList', 'bulletList', 'orderedList', 'layoutSection'];
|
|
28
29
|
var CELL_NODES = ['tableCell', 'tableHeader'];
|
|
29
30
|
|
|
30
|
-
/**
|
|
31
|
-
* Block nodes that host a contributor tag of their own — those whose whole box reads as one change.
|
|
32
|
-
* Lists and tables are excluded: they decorate per item and per cell, with no one-tag-per-block
|
|
33
|
-
* design yet. `blockCard` covers the datasource variant, which is the same node type.
|
|
34
|
-
*/
|
|
35
|
-
var TAGGABLE_BLOCK_NODES = new Set(['blockCard', 'blockquote', 'bodiedExtension', 'codeBlock', 'embedCard', 'expand', 'extension', 'media', 'multiBodiedExtension', 'panel', 'rule']);
|
|
36
|
-
|
|
37
31
|
/** Panels, rules and media can also sit in a table cell, which is out of scope for block tags. */
|
|
38
32
|
var isInsideTable = function isInsideTable(doc, pos) {
|
|
39
33
|
return findParentNodeClosestToPos(doc.resolve(pos), function (node) {
|
|
@@ -41,13 +35,23 @@ var isInsideTable = function isInsideTable(doc, pos) {
|
|
|
41
35
|
}) !== undefined;
|
|
42
36
|
};
|
|
43
37
|
|
|
44
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Whether this block can host a contributor tag of its own.
|
|
40
|
+
*
|
|
41
|
+
* The node type is resolved from the document rather than matched on `change.name`, so a schema
|
|
42
|
+
* variant is recognised as the type it varies — see `isTaggableBlockNode`. `from` is the node's own
|
|
43
|
+
* position, so `nodeAt` returns exactly the node being decorated.
|
|
44
|
+
*/
|
|
45
45
|
var canTagBlock = function canTagBlock(_ref) {
|
|
46
|
+
var _doc$nodeAt;
|
|
46
47
|
var diffType = _ref.diffType,
|
|
47
48
|
doc = _ref.doc,
|
|
48
|
-
from = _ref.from
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
from = _ref.from;
|
|
50
|
+
if (doc === undefined || !isExtendedEnabled(diffType)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
var nodeType = (_doc$nodeAt = doc.nodeAt(from)) === null || _doc$nodeAt === void 0 ? void 0 : _doc$nodeAt.type;
|
|
54
|
+
return nodeType !== undefined && isTaggableBlockNode(nodeType) && !isInsideTable(doc, from);
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
/** Positioning context for the cell overlay widget decorations. */
|
|
@@ -189,8 +193,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
189
193
|
var shouldTagBlock = showContributorTags && canTagBlock({
|
|
190
194
|
diffType: diffType,
|
|
191
195
|
doc: doc,
|
|
192
|
-
from: change.from
|
|
193
|
-
name: change.name
|
|
196
|
+
from: change.from
|
|
194
197
|
});
|
|
195
198
|
// Named so this block's own tag can position against it; see `createContributorTagWidget`.
|
|
196
199
|
var tagAnchorName = shouldTagBlock && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
@@ -234,7 +237,9 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
234
237
|
key: 'cell-overlay-decoration'
|
|
235
238
|
}));
|
|
236
239
|
}
|
|
237
|
-
// isInserted is only read under the extended experience, so pass it unconditionally.
|
|
240
|
+
// isInserted is only read under the extended experience, so pass it unconditionally. `change.name`
|
|
241
|
+
// verbatim: base-name resolution stays in `canTagBlock`, which needs tags on, so a schema
|
|
242
|
+
// variant's legacy style is untouched — see `resolveBaseNodeName`.
|
|
238
243
|
var nodeStyle = getBlockNodeStyle({
|
|
239
244
|
nodeName: change.name,
|
|
240
245
|
colorScheme: colorScheme,
|
|
@@ -265,6 +270,8 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
265
270
|
})));
|
|
266
271
|
}
|
|
267
272
|
if (decorations.length === 0) {
|
|
273
|
+
// An unstyled node type (paragraph, heading, list, layout, …) emits no decoration at all, so
|
|
274
|
+
// there is nothing for a tag to hang off even when the node type would otherwise be taggable.
|
|
268
275
|
return decorations;
|
|
269
276
|
}
|
|
270
277
|
if (showIndicators && doc && isExtendedEnabled(diffType)) {
|
|
@@ -9,7 +9,11 @@ import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
|
9
9
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
10
10
|
import { createContributorTagHost, unmountContributorTag } from './createContributorTagWidget';
|
|
11
11
|
import { buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopValue } from './decorationKeys';
|
|
12
|
+
import { absorbFirstChildMarginReset } from './utils/absorbFirstChildMarginReset';
|
|
13
|
+
import { createMarginAbsorber } from './utils/createMarginAbsorber';
|
|
14
|
+
import { createNodeShapedMarginSpacer } from './utils/createNodeShapedMarginSpacer';
|
|
12
15
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
16
|
+
import { safeResolve } from './utils/safeResolve';
|
|
13
17
|
import { wrapBlockNodeView, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
14
18
|
var isHeadingLevel = function isHeadingLevel(level) {
|
|
15
19
|
return typeof level === 'number' && level >= 1 && level <= 6;
|
|
@@ -183,6 +187,14 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
183
187
|
// For non-table content, use the existing span wrapper approach
|
|
184
188
|
var dom = document.createElement('span');
|
|
185
189
|
var $safeInsertPos = newDoc.resolve(safeInsertPos);
|
|
190
|
+
|
|
191
|
+
// Whether the widget renders above the very start of its parent's content — the document, a
|
|
192
|
+
// layout column, a table cell, a panel.
|
|
193
|
+
//
|
|
194
|
+
// `parentOffset === 0` is the whole test on the position side: prosemirror-view paints every
|
|
195
|
+
// widget at a position before the node starting there, so a leading widget at the parent's start
|
|
196
|
+
// always renders above its content.
|
|
197
|
+
var isVisuallyFirstInParent = !placeBelow && $safeInsertPos.parentOffset === 0;
|
|
186
198
|
var isTopLevelInsert = $safeInsertPos.depth === 0;
|
|
187
199
|
var hasPreviousBlock = ((_$safeInsertPos$nodeB = $safeInsertPos.nodeBefore) === null || _$safeInsertPos$nodeB === void 0 ? void 0 : _$safeInsertPos$nodeB.isBlock) === true;
|
|
188
200
|
var isFirstDocHeadingReplacement = isExtendedEnabled(diffType) && !placeBelow && change.fromB === 0 && ((_slice$content$firstC = slice.content.firstChild) === null || _slice$content$firstC === void 0 ? void 0 : _slice$content$firstC.type.name) === 'heading' && ((_newDoc$firstChild = newDoc.firstChild) === null || _newDoc$firstChild === void 0 ? void 0 : _newDoc$firstChild.type.name) === 'heading';
|
|
@@ -234,6 +246,20 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
234
246
|
var firstReplacedNode = slice.content.firstChild;
|
|
235
247
|
var lastReplacedNode = slice.content.lastChild;
|
|
236
248
|
var showDiffPatch1 = fg('platform_editor_ai_show_diff_patch_1');
|
|
249
|
+
// Whether the slice's outermost textblocks still hold all of their original content.
|
|
250
|
+
//
|
|
251
|
+
// `openStart`/`openEnd` say whether the cut landed inside a block, but not whether it took
|
|
252
|
+
// any text with it — a deletion stopping exactly at a block's content boundary is still
|
|
253
|
+
// reported as open. Resolving the change's own ends separates the two, so a block whose text
|
|
254
|
+
// survived intact can render as a block even though its boundary was open.
|
|
255
|
+
//
|
|
256
|
+
// Both resolves sit behind the gate that consumes them, so this adds no position arithmetic to
|
|
257
|
+
// the ungated path, and an unresolvable position degrades to the `openStart`/`openEnd` test on
|
|
258
|
+
// its own — the block is then treated as partial, which is what it rendered as before the gate.
|
|
259
|
+
var $changeFromA = fg('platform_editor_ai_show_diff_patch_2') ? safeResolve(doc, change.fromA) : null;
|
|
260
|
+
var $changeToA = fg('platform_editor_ai_show_diff_patch_2') ? safeResolve(doc, change.toA) : null;
|
|
261
|
+
var isFirstNodeContentComplete = slice.openStart === 0 || ($changeFromA === null || $changeFromA === void 0 ? void 0 : $changeFromA.parentOffset) === 0;
|
|
262
|
+
var isLastNodeContentComplete = slice.openEnd === 0 || $changeToA !== null && $changeToA.parentOffset === $changeToA.parent.content.size;
|
|
237
263
|
var isCompleteSameTypeReplacement = slice.content.childCount === 1 && firstReplacedNode !== null && replacementNode !== null && firstReplacedNode.type === replacementNode.type && replacementNode.nodeSize === change.toB - change.fromB;
|
|
238
264
|
|
|
239
265
|
/*
|
|
@@ -246,10 +272,16 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
246
272
|
var isLast = lastReplacedNode === node;
|
|
247
273
|
var isOpenAtSliceBoundary = isFirst && slice.openStart > 0 || isLast && slice.openEnd > 0;
|
|
248
274
|
var shouldPreserveCompleteMultiInlineBlock = showDiffPatch1 && node.isBlock && node.type.inlineContent && node.content.childCount > 1 && !isOpenAtSliceBoundary && isCompleteSameTypeReplacement;
|
|
275
|
+
// A textblock is otherwise serialized as its inline content only, with no `<p>`/`<h2>` wrapper.
|
|
276
|
+
// That is right when the diff cuts into an existing block — the deleted text belongs on the same
|
|
277
|
+
// line as the text that replaced it — but when the whole block went away it drops the very
|
|
278
|
+
// element that carries the block's margin, so the deleted block renders flush against its
|
|
279
|
+
// neighbours. Only the first and last children can be partial; middle ones are always complete.
|
|
280
|
+
var shouldRenderAsBlockNode = fg('platform_editor_ai_show_diff_patch_2') && node.isTextblock && (!isFirst || isFirstNodeContentComplete) && (!isLast || isLastNodeContentComplete);
|
|
249
281
|
|
|
250
282
|
// Helper function to handle multiple child nodes
|
|
251
283
|
var handleMultipleChildNodes = function handleMultipleChildNodes(node) {
|
|
252
|
-
if (!shouldPreserveCompleteMultiInlineBlock && node.content.childCount > 1 && node.type.inlineContent) {
|
|
284
|
+
if (!shouldPreserveCompleteMultiInlineBlock && !shouldRenderAsBlockNode && node.content.childCount > 1 && node.type.inlineContent) {
|
|
253
285
|
node.content.forEach(function (childNode) {
|
|
254
286
|
var childNodeView = serializer.tryCreateNodeView(childNode);
|
|
255
287
|
if (childNodeView) {
|
|
@@ -279,7 +311,7 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
279
311
|
if (handleMultipleChildNodes(node)) {
|
|
280
312
|
return;
|
|
281
313
|
}
|
|
282
|
-
if (shouldPreserveCompleteMultiInlineBlock) {
|
|
314
|
+
if (shouldPreserveCompleteMultiInlineBlock || shouldRenderAsBlockNode) {
|
|
283
315
|
fallbackSerialization = function fallbackSerialization() {
|
|
284
316
|
return serializer.serializeNode(node);
|
|
285
317
|
};
|
|
@@ -356,6 +388,21 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
356
388
|
dom.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
357
389
|
}
|
|
358
390
|
|
|
391
|
+
// A block node serialized into the widget is the widget's first child, and the editor's
|
|
392
|
+
// first-child reset is written against the parent element rather than the document position — so
|
|
393
|
+
// it zeroes the margin the block wrapper was kept for in the first place.
|
|
394
|
+
//
|
|
395
|
+
// Only away from the parent's start. There the reset is the correct outcome: the widget is the
|
|
396
|
+
// first thing in the document, column, cell or panel, and a leading gap above it would be wrong.
|
|
397
|
+
// The margin that matters at that position belongs to the node *below* the widget, which the
|
|
398
|
+
// shaped spacer pair supplies instead.
|
|
399
|
+
if (fg('platform_editor_ai_show_diff_patch_2') && !isVisuallyFirstInParent) {
|
|
400
|
+
absorbFirstChildMarginReset({
|
|
401
|
+
dom: dom,
|
|
402
|
+
testId: 'show-diff-widget-margin-absorber'
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
359
406
|
// Needed even when the indicator bar is off, because a contributor tag also anchors against the
|
|
360
407
|
// widget.
|
|
361
408
|
if ((showIndicators || showContributorTags) && isExtendedEnabled(diffType)) {
|
|
@@ -418,7 +465,40 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
418
465
|
var isPureDeletion = change.fromB === change.toB;
|
|
419
466
|
var isSingleBlock = slice.content.childCount === 1 && ((_slice$content$firstC2 = slice.content.firstChild) === null || _slice$content$firstC2 === void 0 ? void 0 : _slice$content$firstC2.isBlock);
|
|
420
467
|
var isDiffWidgetAtStartOfDoc = $safeInsertPos.depth === 0 && $safeInsertPos.index(0) === 0;
|
|
421
|
-
|
|
468
|
+
|
|
469
|
+
// A node at the start of its parent has its top margin reset, so a diff widget rendered above
|
|
470
|
+
// it sits flush against it. This applies wherever that parent is — the document, a layout
|
|
471
|
+
// column, a table cell — so it is decided from the anchor rather than from the document root
|
|
472
|
+
// (see `isVisuallyFirstInParent` above).
|
|
473
|
+
//
|
|
474
|
+
// Away from the parent's start the node below keeps its own margin, and it is the block *inside*
|
|
475
|
+
// the widget that loses one — handled by `absorbFirstChildMarginReset` above, not here.
|
|
476
|
+
var nodeAfterWidget = $safeInsertPos.nodeAfter;
|
|
477
|
+
if (fg('platform_editor_ai_show_diff_patch_2') && isExtendedEnabled(diffType) && isVisuallyFirstInParent && nodeAfterWidget) {
|
|
478
|
+
var shapedSpacer = createNodeShapedMarginSpacer({
|
|
479
|
+
node: nodeAfterWidget,
|
|
480
|
+
serializer: serializer,
|
|
481
|
+
testId: 'show-diff-shaped-margin-spacer'
|
|
482
|
+
});
|
|
483
|
+
if (shapedSpacer) {
|
|
484
|
+
// Two elements, because the two families of reset have to be handled differently. The
|
|
485
|
+
// absorber takes the document-level adjacent-sibling reset for a leading widget, whose
|
|
486
|
+
// `!important` would otherwise zero the shaped spacer's margin; the shaped spacer, now one
|
|
487
|
+
// position further along, is out of that rule's reach and keeps the margin it supplies.
|
|
488
|
+
// Inside containers the counting selectors skip both, so only the shaped one has an effect.
|
|
489
|
+
//
|
|
490
|
+
// Sides order the widgets against each other only — both still paint before the real node.
|
|
491
|
+
decorations.push(Decoration.widget(safeInsertPos, createMarginAbsorber({
|
|
492
|
+
testId: 'show-diff-margin-absorber'
|
|
493
|
+
}), {
|
|
494
|
+
side: 0
|
|
495
|
+
}));
|
|
496
|
+
decorations.push(Decoration.widget(safeInsertPos, shapedSpacer, {
|
|
497
|
+
side: 1
|
|
498
|
+
}));
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (!fg('platform_editor_ai_show_diff_patch_2') && isDiffWidgetAtStartOfDoc && isSingleBlock && isPureDeletion && isExtendedEnabled(diffType)) {
|
|
422
502
|
var followingNode = $safeInsertPos.nodeAfter;
|
|
423
503
|
var headingLevel = (followingNode === null || followingNode === void 0 ? void 0 : followingNode.type.name) === 'heading' ? followingNode.attrs.level : undefined;
|
|
424
504
|
if (isHeadingLevel(headingLevel)) {
|