@atlaskit/editor-plugin-show-diff 16.0.8 → 16.0.10
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 +15 -0
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +10 -1
- package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +20 -4
- package/dist/cjs/pm-plugins/decorations/decorationKeys.js +3 -1
- package/dist/cjs/ui/ContributorTag/buildContributorTagDom.js +10 -1
- package/dist/cjs/ui/ContributorTag/contributorTagController.js +1 -1
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +12 -3
- package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +17 -3
- package/dist/es2019/pm-plugins/decorations/decorationKeys.js +3 -1
- package/dist/es2019/ui/ContributorTag/buildContributorTagDom.js +10 -1
- package/dist/es2019/ui/ContributorTag/contributorTagController.js +1 -1
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +12 -3
- package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +20 -4
- package/dist/esm/pm-plugins/decorations/decorationKeys.js +3 -1
- package/dist/esm/ui/ContributorTag/buildContributorTagDom.js +10 -1
- package/dist/esm/ui/ContributorTag/contributorTagController.js +1 -1
- package/dist/types/pm-plugins/decorations/createContributorTagWidget.d.ts +9 -2
- package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +2 -0
- package/dist/types/ui/ContributorTag/buildContributorTagDom.d.ts +3 -1
- package/dist/types/ui/ContributorTag/contributorTagController.d.ts +2 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 16.0.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 16.0.9
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`c00ea38023074`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c00ea38023074) -
|
|
14
|
+
[ux] Contributor tags on changed block nodes now sit on the block's own top-left corner, instead
|
|
15
|
+
of drifting by that node type's margin. Behind `confluence_ncs_step_diffing_version_history`.
|
|
16
|
+
- Updated dependencies
|
|
17
|
+
|
|
3
18
|
## 16.0.8
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -198,6 +198,11 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
198
198
|
from: change.from,
|
|
199
199
|
name: change.name
|
|
200
200
|
});
|
|
201
|
+
// Named so this block's own tag can position against it; see `createContributorTagWidget`.
|
|
202
|
+
var tagAnchorName = shouldTagBlock && (0, _createContributorTagWidget.isContributorTagWidgetEnabled)() ? (0, _decorationKeys.buildAnchorDecorationKey)({
|
|
203
|
+
diffId: diffId,
|
|
204
|
+
anchorType: _decorationKeys.AnchorTypeKey.tag
|
|
205
|
+
}) : undefined;
|
|
201
206
|
if (shouldHideDeleted) {
|
|
202
207
|
return [_view.Decoration.node(change.from, change.to, {
|
|
203
208
|
style: displayNoneStyle
|
|
@@ -236,13 +241,16 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
236
241
|
}));
|
|
237
242
|
}
|
|
238
243
|
// isInserted is only read under the extended experience, so pass it unconditionally.
|
|
239
|
-
var
|
|
244
|
+
var nodeStyle = getBlockNodeStyle({
|
|
240
245
|
nodeName: change.name,
|
|
241
246
|
colorScheme: colorScheme,
|
|
242
247
|
isInserted: isInserted,
|
|
243
248
|
isActive: isActive,
|
|
244
249
|
diffType: diffType
|
|
245
250
|
});
|
|
251
|
+
var style = tagAnchorName ? [nodeStyle, (0, _lazyNodeView.convertToInlineCss)({
|
|
252
|
+
anchorName: "--".concat(tagAnchorName)
|
|
253
|
+
})].filter(Boolean).join(' ') : nodeStyle;
|
|
246
254
|
var className = getNodeClass(change.name);
|
|
247
255
|
if (style || className) {
|
|
248
256
|
decorations.push(_view.Decoration.node(change.from, change.to, _objectSpread({
|
|
@@ -280,6 +288,7 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
280
288
|
if (shouldTagBlock && doc) {
|
|
281
289
|
var tagWidget = (0, _createContributorTagWidget.createContributorTagWidget)({
|
|
282
290
|
anchorAtRangeStart: true,
|
|
291
|
+
anchorName: tagAnchorName,
|
|
283
292
|
doc: doc,
|
|
284
293
|
from: change.from,
|
|
285
294
|
to: change.to,
|
|
@@ -38,13 +38,15 @@ var isContributorTagWidgetEnabled = exports.isContributorTagWidgetEnabled = func
|
|
|
38
38
|
* (EDITOR-8702).
|
|
39
39
|
*/
|
|
40
40
|
var mountContributorTag = exports.mountContributorTag = function mountContributorTag(_ref) {
|
|
41
|
-
var
|
|
41
|
+
var anchorName = _ref.anchorName,
|
|
42
|
+
diffId = _ref.diffId,
|
|
42
43
|
host = _ref.host,
|
|
43
44
|
mountContext = _ref.mountContext;
|
|
44
45
|
if (!mountContext) {
|
|
45
46
|
return undefined;
|
|
46
47
|
}
|
|
47
48
|
var controller = new _contributorTagController.ContributorTagController(_objectSpread(_objectSpread({}, mountContext), {}, {
|
|
49
|
+
anchorName: anchorName,
|
|
48
50
|
diffId: diffId
|
|
49
51
|
}));
|
|
50
52
|
controller.mount(host);
|
|
@@ -76,14 +78,25 @@ var unmountContributorTag = exports.unmountContributorTag = function unmountCont
|
|
|
76
78
|
/**
|
|
77
79
|
* A zero-size inline host for one contributor tag. `position: relative` makes it the containing
|
|
78
80
|
* block of the absolutely positioned tag, so the tag sits on the change with no measurement.
|
|
81
|
+
*
|
|
82
|
+
* An anchored tag takes a static host instead: an anchor is only acceptable when it sits inside the
|
|
83
|
+
* tag's containing block, and the block node is not inside this host. Measured in Chrome 153 — a
|
|
84
|
+
* relative host makes the `anchor()` insets resolve to `auto`.
|
|
79
85
|
*/
|
|
80
|
-
var buildContributorTagHost = function buildContributorTagHost(diffId) {
|
|
86
|
+
var buildContributorTagHost = function buildContributorTagHost(diffId, anchorName) {
|
|
81
87
|
var host = document.createElement('span');
|
|
82
88
|
host.setAttribute(CONTRIBUTOR_TAG_HOST_ATTRIBUTE, diffId);
|
|
83
|
-
|
|
89
|
+
if (!anchorName) {
|
|
90
|
+
host.style.setProperty('position', 'relative');
|
|
91
|
+
}
|
|
84
92
|
return host;
|
|
85
93
|
};
|
|
86
94
|
|
|
95
|
+
/** Without anchor positioning the tag keeps its host-relative placement. */
|
|
96
|
+
var supportsAnchorPositioning = function supportsAnchorPositioning() {
|
|
97
|
+
return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('bottom', 'anchor(--a top)');
|
|
98
|
+
};
|
|
99
|
+
|
|
87
100
|
/**
|
|
88
101
|
* The host for a tag on deleted content, which renders inside its own widget decoration rather than
|
|
89
102
|
* needing one of its own. Unmount with `unmountContributorTag` from that widget's `destroy`.
|
|
@@ -183,6 +196,7 @@ var resolveCodeBlockStart = function resolveCodeBlockStart(doc, pos) {
|
|
|
183
196
|
var createContributorTagWidget = exports.createContributorTagWidget = function createContributorTagWidget(_ref3) {
|
|
184
197
|
var _ref3$anchorAtRangeSt = _ref3.anchorAtRangeStart,
|
|
185
198
|
anchorAtRangeStart = _ref3$anchorAtRangeSt === void 0 ? false : _ref3$anchorAtRangeSt,
|
|
199
|
+
anchorName = _ref3.anchorName,
|
|
186
200
|
doc = _ref3.doc,
|
|
187
201
|
from = _ref3.from,
|
|
188
202
|
to = _ref3.to,
|
|
@@ -191,6 +205,7 @@ var createContributorTagWidget = exports.createContributorTagWidget = function c
|
|
|
191
205
|
if (!isContributorTagWidgetEnabled()) {
|
|
192
206
|
return undefined;
|
|
193
207
|
}
|
|
208
|
+
var tagAnchorName = anchorName && supportsAnchorPositioning() ? anchorName : undefined;
|
|
194
209
|
|
|
195
210
|
// Reassigned when ProseMirror redraws this decoration, which it may do more than once for the
|
|
196
211
|
// same `Decoration` instance.
|
|
@@ -201,8 +216,9 @@ var createContributorTagWidget = exports.createContributorTagWidget = function c
|
|
|
201
216
|
return _view.Decoration.widget(
|
|
202
217
|
// Keep the host out of the table row's grid (EDITOR-8442).
|
|
203
218
|
(0, _createAnchorDecorationWidgets.clampAnchorPosIntoCell)(doc, codeBlockPos !== null && codeBlockPos !== void 0 ? codeBlockPos : anchorPos, 1), function () {
|
|
204
|
-
var host = buildContributorTagHost(diffId);
|
|
219
|
+
var host = buildContributorTagHost(diffId, tagAnchorName);
|
|
205
220
|
mount = mountContributorTag({
|
|
221
|
+
anchorName: tagAnchorName,
|
|
206
222
|
diffId: diffId,
|
|
207
223
|
host: host,
|
|
208
224
|
mountContext: mountContext
|
|
@@ -25,7 +25,9 @@ var AnchorTypeKey = exports.AnchorTypeKey = {
|
|
|
25
25
|
from: 'from',
|
|
26
26
|
to: 'to',
|
|
27
27
|
left: 'left',
|
|
28
|
-
docMargin: 'doc-margin'
|
|
28
|
+
docMargin: 'doc-margin',
|
|
29
|
+
/** The decorated block itself, which its contributor tag positions against. */
|
|
30
|
+
tag: 'tag'
|
|
29
31
|
};
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -186,10 +186,19 @@ var createSpan = function createSpan(doc, style) {
|
|
|
186
186
|
*
|
|
187
187
|
* Built element by element rather than through `DOMSerializer.renderSpec`, which returns `Node` and
|
|
188
188
|
* would need a cast per reference below.
|
|
189
|
+
*
|
|
190
|
+
* `anchorName` is the `anchor-name` its block carries — see `createContributorTagWidget`.
|
|
189
191
|
*/
|
|
190
|
-
var buildContributorTagDom = exports.buildContributorTagDom = function buildContributorTagDom(doc) {
|
|
192
|
+
var buildContributorTagDom = exports.buildContributorTagDom = function buildContributorTagDom(doc, anchorName) {
|
|
191
193
|
var labelId = generateLabelId();
|
|
192
194
|
var root = createSpan(doc, constraintStyle);
|
|
195
|
+
if (anchorName) {
|
|
196
|
+
// Anchored to the block's own box, so the tag clears whatever margin its node type has — the
|
|
197
|
+
// same `anchor()` insets the `IndicatorBar` uses. A browser without anchor positioning rejects
|
|
198
|
+
// these values and keeps the `bottom: 100%` fallback above.
|
|
199
|
+
root.style.setProperty('bottom', "anchor(--".concat(anchorName, " top)"));
|
|
200
|
+
root.style.setProperty('inset-inline-start', "anchor(--".concat(anchorName, " left)"));
|
|
201
|
+
}
|
|
193
202
|
var tag = createSpan(doc, tagStyle, {
|
|
194
203
|
class: CONTRIBUTOR_TAG_CLASS,
|
|
195
204
|
'data-testid': CONTRIBUTOR_TAG_TESTID,
|
|
@@ -186,7 +186,7 @@ var ContributorTagController = exports.ContributorTagController = /*#__PURE__*/f
|
|
|
186
186
|
return;
|
|
187
187
|
}
|
|
188
188
|
if (!this.dom) {
|
|
189
|
-
this.dom = (0, _buildContributorTagDom.buildContributorTagDom)(host.ownerDocument);
|
|
189
|
+
this.dom = (0, _buildContributorTagDom.buildContributorTagDom)(host.ownerDocument, this.options.anchorName);
|
|
190
190
|
this.bindTag(this.dom);
|
|
191
191
|
host.appendChild(this.dom.root);
|
|
192
192
|
}
|
|
@@ -6,8 +6,8 @@ import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
|
6
6
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedBlockNodeStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildInsertedBlockNodeStyle } from './colorSchemes/factory';
|
|
7
7
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
8
8
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
9
|
-
import { createContributorTagWidget } from './createContributorTagWidget';
|
|
10
|
-
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
9
|
+
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
10
|
+
import { AnchorTypeKey, buildAnchorDecorationKey, buildDiffDecorationSpec } from './decorationKeys';
|
|
11
11
|
import { getBlockNodeStyleLegacy, resolveCellOverlayStyleLegacy } from './createBlockChangedDecoration.styles.legacy';
|
|
12
12
|
const displayNoneStyle = convertToInlineCss({
|
|
13
13
|
display: 'none'
|
|
@@ -178,6 +178,11 @@ export const createBlockChangedDecoration = ({
|
|
|
178
178
|
from: change.from,
|
|
179
179
|
name: change.name
|
|
180
180
|
});
|
|
181
|
+
// Named so this block's own tag can position against it; see `createContributorTagWidget`.
|
|
182
|
+
const tagAnchorName = shouldTagBlock && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
183
|
+
diffId,
|
|
184
|
+
anchorType: AnchorTypeKey.tag
|
|
185
|
+
}) : undefined;
|
|
181
186
|
if (shouldHideDeleted) {
|
|
182
187
|
return [Decoration.node(change.from, change.to, {
|
|
183
188
|
style: displayNoneStyle
|
|
@@ -216,13 +221,16 @@ export const createBlockChangedDecoration = ({
|
|
|
216
221
|
}));
|
|
217
222
|
}
|
|
218
223
|
// isInserted is only read under the extended experience, so pass it unconditionally.
|
|
219
|
-
const
|
|
224
|
+
const nodeStyle = getBlockNodeStyle({
|
|
220
225
|
nodeName: change.name,
|
|
221
226
|
colorScheme,
|
|
222
227
|
isInserted,
|
|
223
228
|
isActive,
|
|
224
229
|
diffType
|
|
225
230
|
});
|
|
231
|
+
const style = tagAnchorName ? [nodeStyle, convertToInlineCss({
|
|
232
|
+
anchorName: `--${tagAnchorName}`
|
|
233
|
+
})].filter(Boolean).join(' ') : nodeStyle;
|
|
226
234
|
const className = getNodeClass(change.name);
|
|
227
235
|
if (style || className) {
|
|
228
236
|
decorations.push(Decoration.node(change.from, change.to, {
|
|
@@ -262,6 +270,7 @@ export const createBlockChangedDecoration = ({
|
|
|
262
270
|
if (shouldTagBlock && doc) {
|
|
263
271
|
const tagWidget = createContributorTagWidget({
|
|
264
272
|
anchorAtRangeStart: true,
|
|
273
|
+
anchorName: tagAnchorName,
|
|
265
274
|
doc,
|
|
266
275
|
from: change.from,
|
|
267
276
|
to: change.to,
|
|
@@ -27,6 +27,7 @@ export const isContributorTagWidgetEnabled = () => fg('confluence_ncs_step_diffi
|
|
|
27
27
|
* (EDITOR-8702).
|
|
28
28
|
*/
|
|
29
29
|
export const mountContributorTag = ({
|
|
30
|
+
anchorName,
|
|
30
31
|
diffId,
|
|
31
32
|
host,
|
|
32
33
|
mountContext
|
|
@@ -36,6 +37,7 @@ export const mountContributorTag = ({
|
|
|
36
37
|
}
|
|
37
38
|
const controller = new ContributorTagController({
|
|
38
39
|
...mountContext,
|
|
40
|
+
anchorName,
|
|
39
41
|
diffId
|
|
40
42
|
});
|
|
41
43
|
controller.mount(host);
|
|
@@ -65,14 +67,23 @@ export const unmountContributorTag = mount => {
|
|
|
65
67
|
/**
|
|
66
68
|
* A zero-size inline host for one contributor tag. `position: relative` makes it the containing
|
|
67
69
|
* block of the absolutely positioned tag, so the tag sits on the change with no measurement.
|
|
70
|
+
*
|
|
71
|
+
* An anchored tag takes a static host instead: an anchor is only acceptable when it sits inside the
|
|
72
|
+
* tag's containing block, and the block node is not inside this host. Measured in Chrome 153 — a
|
|
73
|
+
* relative host makes the `anchor()` insets resolve to `auto`.
|
|
68
74
|
*/
|
|
69
|
-
const buildContributorTagHost = diffId => {
|
|
75
|
+
const buildContributorTagHost = (diffId, anchorName) => {
|
|
70
76
|
const host = document.createElement('span');
|
|
71
77
|
host.setAttribute(CONTRIBUTOR_TAG_HOST_ATTRIBUTE, diffId);
|
|
72
|
-
|
|
78
|
+
if (!anchorName) {
|
|
79
|
+
host.style.setProperty('position', 'relative');
|
|
80
|
+
}
|
|
73
81
|
return host;
|
|
74
82
|
};
|
|
75
83
|
|
|
84
|
+
/** Without anchor positioning the tag keeps its host-relative placement. */
|
|
85
|
+
const supportsAnchorPositioning = () => typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('bottom', 'anchor(--a top)');
|
|
86
|
+
|
|
76
87
|
/**
|
|
77
88
|
* The host for a tag on deleted content, which renders inside its own widget decoration rather than
|
|
78
89
|
* needing one of its own. Unmount with `unmountContributorTag` from that widget's `destroy`.
|
|
@@ -171,6 +182,7 @@ const resolveCodeBlockStart = (doc, pos) => {
|
|
|
171
182
|
*/
|
|
172
183
|
export const createContributorTagWidget = ({
|
|
173
184
|
anchorAtRangeStart = false,
|
|
185
|
+
anchorName,
|
|
174
186
|
doc,
|
|
175
187
|
from,
|
|
176
188
|
to,
|
|
@@ -180,6 +192,7 @@ export const createContributorTagWidget = ({
|
|
|
180
192
|
if (!isContributorTagWidgetEnabled()) {
|
|
181
193
|
return undefined;
|
|
182
194
|
}
|
|
195
|
+
const tagAnchorName = anchorName && supportsAnchorPositioning() ? anchorName : undefined;
|
|
183
196
|
|
|
184
197
|
// Reassigned when ProseMirror redraws this decoration, which it may do more than once for the
|
|
185
198
|
// same `Decoration` instance.
|
|
@@ -190,8 +203,9 @@ export const createContributorTagWidget = ({
|
|
|
190
203
|
return Decoration.widget(
|
|
191
204
|
// Keep the host out of the table row's grid (EDITOR-8442).
|
|
192
205
|
clampAnchorPosIntoCell(doc, codeBlockPos !== null && codeBlockPos !== void 0 ? codeBlockPos : anchorPos, 1), () => {
|
|
193
|
-
const host = buildContributorTagHost(diffId);
|
|
206
|
+
const host = buildContributorTagHost(diffId, tagAnchorName);
|
|
194
207
|
mount = mountContributorTag({
|
|
208
|
+
anchorName: tagAnchorName,
|
|
195
209
|
diffId,
|
|
196
210
|
host,
|
|
197
211
|
mountContext
|
|
@@ -172,10 +172,19 @@ const createSpan = (doc, style, attributes = {}) => {
|
|
|
172
172
|
*
|
|
173
173
|
* Built element by element rather than through `DOMSerializer.renderSpec`, which returns `Node` and
|
|
174
174
|
* would need a cast per reference below.
|
|
175
|
+
*
|
|
176
|
+
* `anchorName` is the `anchor-name` its block carries — see `createContributorTagWidget`.
|
|
175
177
|
*/
|
|
176
|
-
export const buildContributorTagDom = doc => {
|
|
178
|
+
export const buildContributorTagDom = (doc, anchorName) => {
|
|
177
179
|
const labelId = generateLabelId();
|
|
178
180
|
const root = createSpan(doc, constraintStyle);
|
|
181
|
+
if (anchorName) {
|
|
182
|
+
// Anchored to the block's own box, so the tag clears whatever margin its node type has — the
|
|
183
|
+
// same `anchor()` insets the `IndicatorBar` uses. A browser without anchor positioning rejects
|
|
184
|
+
// these values and keeps the `bottom: 100%` fallback above.
|
|
185
|
+
root.style.setProperty('bottom', `anchor(--${anchorName} top)`);
|
|
186
|
+
root.style.setProperty('inset-inline-start', `anchor(--${anchorName} left)`);
|
|
187
|
+
}
|
|
179
188
|
const tag = createSpan(doc, tagStyle, {
|
|
180
189
|
class: CONTRIBUTOR_TAG_CLASS,
|
|
181
190
|
'data-testid': CONTRIBUTOR_TAG_TESTID,
|
|
@@ -160,7 +160,7 @@ export class ContributorTagController {
|
|
|
160
160
|
return;
|
|
161
161
|
}
|
|
162
162
|
if (!this.dom) {
|
|
163
|
-
this.dom = buildContributorTagDom(host.ownerDocument);
|
|
163
|
+
this.dom = buildContributorTagDom(host.ownerDocument, this.options.anchorName);
|
|
164
164
|
this.bindTag(this.dom);
|
|
165
165
|
host.appendChild(this.dom.root);
|
|
166
166
|
}
|
|
@@ -10,8 +10,8 @@ import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
|
10
10
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedBlockNodeStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildInsertedBlockNodeStyle } from './colorSchemes/factory';
|
|
11
11
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
12
12
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
13
|
-
import { createContributorTagWidget } from './createContributorTagWidget';
|
|
14
|
-
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
13
|
+
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
14
|
+
import { AnchorTypeKey, buildAnchorDecorationKey, buildDiffDecorationSpec } from './decorationKeys';
|
|
15
15
|
import { getBlockNodeStyleLegacy, resolveCellOverlayStyleLegacy } from './createBlockChangedDecoration.styles.legacy';
|
|
16
16
|
var displayNoneStyle = convertToInlineCss({
|
|
17
17
|
display: 'none'
|
|
@@ -191,6 +191,11 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
191
191
|
from: change.from,
|
|
192
192
|
name: change.name
|
|
193
193
|
});
|
|
194
|
+
// Named so this block's own tag can position against it; see `createContributorTagWidget`.
|
|
195
|
+
var tagAnchorName = shouldTagBlock && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
196
|
+
diffId: diffId,
|
|
197
|
+
anchorType: AnchorTypeKey.tag
|
|
198
|
+
}) : undefined;
|
|
194
199
|
if (shouldHideDeleted) {
|
|
195
200
|
return [Decoration.node(change.from, change.to, {
|
|
196
201
|
style: displayNoneStyle
|
|
@@ -229,13 +234,16 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
229
234
|
}));
|
|
230
235
|
}
|
|
231
236
|
// isInserted is only read under the extended experience, so pass it unconditionally.
|
|
232
|
-
var
|
|
237
|
+
var nodeStyle = getBlockNodeStyle({
|
|
233
238
|
nodeName: change.name,
|
|
234
239
|
colorScheme: colorScheme,
|
|
235
240
|
isInserted: isInserted,
|
|
236
241
|
isActive: isActive,
|
|
237
242
|
diffType: diffType
|
|
238
243
|
});
|
|
244
|
+
var style = tagAnchorName ? [nodeStyle, convertToInlineCss({
|
|
245
|
+
anchorName: "--".concat(tagAnchorName)
|
|
246
|
+
})].filter(Boolean).join(' ') : nodeStyle;
|
|
239
247
|
var className = getNodeClass(change.name);
|
|
240
248
|
if (style || className) {
|
|
241
249
|
decorations.push(Decoration.node(change.from, change.to, _objectSpread({
|
|
@@ -273,6 +281,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
273
281
|
if (shouldTagBlock && doc) {
|
|
274
282
|
var tagWidget = createContributorTagWidget({
|
|
275
283
|
anchorAtRangeStart: true,
|
|
284
|
+
anchorName: tagAnchorName,
|
|
276
285
|
doc: doc,
|
|
277
286
|
from: change.from,
|
|
278
287
|
to: change.to,
|
|
@@ -32,13 +32,15 @@ export var isContributorTagWidgetEnabled = function isContributorTagWidgetEnable
|
|
|
32
32
|
* (EDITOR-8702).
|
|
33
33
|
*/
|
|
34
34
|
export var mountContributorTag = function mountContributorTag(_ref) {
|
|
35
|
-
var
|
|
35
|
+
var anchorName = _ref.anchorName,
|
|
36
|
+
diffId = _ref.diffId,
|
|
36
37
|
host = _ref.host,
|
|
37
38
|
mountContext = _ref.mountContext;
|
|
38
39
|
if (!mountContext) {
|
|
39
40
|
return undefined;
|
|
40
41
|
}
|
|
41
42
|
var controller = new ContributorTagController(_objectSpread(_objectSpread({}, mountContext), {}, {
|
|
43
|
+
anchorName: anchorName,
|
|
42
44
|
diffId: diffId
|
|
43
45
|
}));
|
|
44
46
|
controller.mount(host);
|
|
@@ -70,14 +72,25 @@ export var unmountContributorTag = function unmountContributorTag(mount) {
|
|
|
70
72
|
/**
|
|
71
73
|
* A zero-size inline host for one contributor tag. `position: relative` makes it the containing
|
|
72
74
|
* block of the absolutely positioned tag, so the tag sits on the change with no measurement.
|
|
75
|
+
*
|
|
76
|
+
* An anchored tag takes a static host instead: an anchor is only acceptable when it sits inside the
|
|
77
|
+
* tag's containing block, and the block node is not inside this host. Measured in Chrome 153 — a
|
|
78
|
+
* relative host makes the `anchor()` insets resolve to `auto`.
|
|
73
79
|
*/
|
|
74
|
-
var buildContributorTagHost = function buildContributorTagHost(diffId) {
|
|
80
|
+
var buildContributorTagHost = function buildContributorTagHost(diffId, anchorName) {
|
|
75
81
|
var host = document.createElement('span');
|
|
76
82
|
host.setAttribute(CONTRIBUTOR_TAG_HOST_ATTRIBUTE, diffId);
|
|
77
|
-
|
|
83
|
+
if (!anchorName) {
|
|
84
|
+
host.style.setProperty('position', 'relative');
|
|
85
|
+
}
|
|
78
86
|
return host;
|
|
79
87
|
};
|
|
80
88
|
|
|
89
|
+
/** Without anchor positioning the tag keeps its host-relative placement. */
|
|
90
|
+
var supportsAnchorPositioning = function supportsAnchorPositioning() {
|
|
91
|
+
return typeof CSS !== 'undefined' && typeof CSS.supports === 'function' && CSS.supports('bottom', 'anchor(--a top)');
|
|
92
|
+
};
|
|
93
|
+
|
|
81
94
|
/**
|
|
82
95
|
* The host for a tag on deleted content, which renders inside its own widget decoration rather than
|
|
83
96
|
* needing one of its own. Unmount with `unmountContributorTag` from that widget's `destroy`.
|
|
@@ -177,6 +190,7 @@ var resolveCodeBlockStart = function resolveCodeBlockStart(doc, pos) {
|
|
|
177
190
|
export var createContributorTagWidget = function createContributorTagWidget(_ref3) {
|
|
178
191
|
var _ref3$anchorAtRangeSt = _ref3.anchorAtRangeStart,
|
|
179
192
|
anchorAtRangeStart = _ref3$anchorAtRangeSt === void 0 ? false : _ref3$anchorAtRangeSt,
|
|
193
|
+
anchorName = _ref3.anchorName,
|
|
180
194
|
doc = _ref3.doc,
|
|
181
195
|
from = _ref3.from,
|
|
182
196
|
to = _ref3.to,
|
|
@@ -185,6 +199,7 @@ export var createContributorTagWidget = function createContributorTagWidget(_ref
|
|
|
185
199
|
if (!isContributorTagWidgetEnabled()) {
|
|
186
200
|
return undefined;
|
|
187
201
|
}
|
|
202
|
+
var tagAnchorName = anchorName && supportsAnchorPositioning() ? anchorName : undefined;
|
|
188
203
|
|
|
189
204
|
// Reassigned when ProseMirror redraws this decoration, which it may do more than once for the
|
|
190
205
|
// same `Decoration` instance.
|
|
@@ -195,8 +210,9 @@ export var createContributorTagWidget = function createContributorTagWidget(_ref
|
|
|
195
210
|
return Decoration.widget(
|
|
196
211
|
// Keep the host out of the table row's grid (EDITOR-8442).
|
|
197
212
|
clampAnchorPosIntoCell(doc, codeBlockPos !== null && codeBlockPos !== void 0 ? codeBlockPos : anchorPos, 1), function () {
|
|
198
|
-
var host = buildContributorTagHost(diffId);
|
|
213
|
+
var host = buildContributorTagHost(diffId, tagAnchorName);
|
|
199
214
|
mount = mountContributorTag({
|
|
215
|
+
anchorName: tagAnchorName,
|
|
200
216
|
diffId: diffId,
|
|
201
217
|
host: host,
|
|
202
218
|
mountContext: mountContext
|
|
@@ -179,10 +179,19 @@ var createSpan = function createSpan(doc, style) {
|
|
|
179
179
|
*
|
|
180
180
|
* Built element by element rather than through `DOMSerializer.renderSpec`, which returns `Node` and
|
|
181
181
|
* would need a cast per reference below.
|
|
182
|
+
*
|
|
183
|
+
* `anchorName` is the `anchor-name` its block carries — see `createContributorTagWidget`.
|
|
182
184
|
*/
|
|
183
|
-
export var buildContributorTagDom = function buildContributorTagDom(doc) {
|
|
185
|
+
export var buildContributorTagDom = function buildContributorTagDom(doc, anchorName) {
|
|
184
186
|
var labelId = generateLabelId();
|
|
185
187
|
var root = createSpan(doc, constraintStyle);
|
|
188
|
+
if (anchorName) {
|
|
189
|
+
// Anchored to the block's own box, so the tag clears whatever margin its node type has — the
|
|
190
|
+
// same `anchor()` insets the `IndicatorBar` uses. A browser without anchor positioning rejects
|
|
191
|
+
// these values and keeps the `bottom: 100%` fallback above.
|
|
192
|
+
root.style.setProperty('bottom', "anchor(--".concat(anchorName, " top)"));
|
|
193
|
+
root.style.setProperty('inset-inline-start', "anchor(--".concat(anchorName, " left)"));
|
|
194
|
+
}
|
|
186
195
|
var tag = createSpan(doc, tagStyle, {
|
|
187
196
|
class: CONTRIBUTOR_TAG_CLASS,
|
|
188
197
|
'data-testid': CONTRIBUTOR_TAG_TESTID,
|
|
@@ -179,7 +179,7 @@ export var ContributorTagController = /*#__PURE__*/function () {
|
|
|
179
179
|
return;
|
|
180
180
|
}
|
|
181
181
|
if (!this.dom) {
|
|
182
|
-
this.dom = buildContributorTagDom(host.ownerDocument);
|
|
182
|
+
this.dom = buildContributorTagDom(host.ownerDocument, this.options.anchorName);
|
|
183
183
|
this.bindTag(this.dom);
|
|
184
184
|
host.appendChild(this.dom.root);
|
|
185
185
|
}
|
|
@@ -28,7 +28,8 @@ export type ContributorTagMount = {
|
|
|
28
28
|
* destroying the one it replaces, the outgoing `destroy` cannot take the incoming tag down with it
|
|
29
29
|
* (EDITOR-8702).
|
|
30
30
|
*/
|
|
31
|
-
export declare const mountContributorTag: ({ diffId, host, mountContext, }: {
|
|
31
|
+
export declare const mountContributorTag: ({ anchorName, diffId, host, mountContext, }: {
|
|
32
|
+
anchorName?: string;
|
|
32
33
|
diffId: string;
|
|
33
34
|
host: HTMLElement;
|
|
34
35
|
mountContext: ContributorTagMountContext | undefined;
|
|
@@ -50,12 +51,18 @@ export declare const createContributorTagHost: (diffId: string, mountContext?: C
|
|
|
50
51
|
* The tag is mounted in `toDOM` and taken down in `destroy`, so it lives exactly as long as the host
|
|
51
52
|
* element ProseMirror drew it into — see `mountContributorTag`.
|
|
52
53
|
*/
|
|
53
|
-
export declare const createContributorTagWidget: ({ anchorAtRangeStart, doc, from, to, diffId, mountContext, }: {
|
|
54
|
+
export declare const createContributorTagWidget: ({ anchorAtRangeStart, anchorName, doc, from, to, diffId, mountContext, }: {
|
|
54
55
|
/**
|
|
55
56
|
* Anchor the host at `from` instead of the range's first inline content, so a block range hosts
|
|
56
57
|
* its tag outside the node rather than inside its content DOM.
|
|
57
58
|
*/
|
|
58
59
|
anchorAtRangeStart?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The `anchor-name` the block's own decoration carries, so the tag positions against that box
|
|
62
|
+
* rather than against its host — the block's margin and padding are then the browser's to
|
|
63
|
+
* resolve, and the tag sits on the same corner for every node type (EDITOR-8933).
|
|
64
|
+
*/
|
|
65
|
+
anchorName?: string;
|
|
59
66
|
diffId: string;
|
|
60
67
|
doc: PMNode;
|
|
61
68
|
from: number;
|
|
@@ -46,6 +46,8 @@ export declare const AnchorTypeKey: {
|
|
|
46
46
|
readonly to: 'to';
|
|
47
47
|
readonly left: 'left';
|
|
48
48
|
readonly docMargin: 'doc-margin';
|
|
49
|
+
/** The decorated block itself, which its contributor tag positions against. */
|
|
50
|
+
readonly tag: 'tag';
|
|
49
51
|
};
|
|
50
52
|
export type InlineAnchorType = Exclude<(typeof AnchorTypeKey)[keyof typeof AnchorTypeKey], typeof AnchorTypeKey.docMargin>;
|
|
51
53
|
export type AnchorDecorationSpec = (BaseDecorationSpec<typeof DecorationFamily.anchor> & {
|
|
@@ -60,5 +60,7 @@ export type ContributorTagDom = {
|
|
|
60
60
|
*
|
|
61
61
|
* Built element by element rather than through `DOMSerializer.renderSpec`, which returns `Node` and
|
|
62
62
|
* would need a cast per reference below.
|
|
63
|
+
*
|
|
64
|
+
* `anchorName` is the `anchor-name` its block carries — see `createContributorTagWidget`.
|
|
63
65
|
*/
|
|
64
|
-
export declare const buildContributorTagDom: (doc: Document) => ContributorTagDom;
|
|
66
|
+
export declare const buildContributorTagDom: (doc: Document, anchorName?: string) => ContributorTagDom;
|
|
@@ -2,6 +2,8 @@ import type { IntlShape } from 'react-intl';
|
|
|
2
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
3
|
import type { ShowDiffPlugin } from '../../showDiffPluginType';
|
|
4
4
|
export type ContributorTagControllerOptions = {
|
|
5
|
+
/** The `anchor-name` of the block this tag captions, when it has one. */
|
|
6
|
+
anchorName?: string;
|
|
5
7
|
api?: ExtractInjectionAPI<ShowDiffPlugin>;
|
|
6
8
|
diffId: string;
|
|
7
9
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.10",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
33
33
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
34
34
|
"@atlaskit/primitives": "^22.5.0",
|
|
35
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
35
|
+
"@atlaskit/tmp-editor-statsig": "^194.0.0",
|
|
36
36
|
"@atlaskit/tokens": "^16.12.0",
|
|
37
37
|
"@babel/runtime": "^7.0.0",
|
|
38
38
|
"@compiled/react": "^1.0.2",
|
|
@@ -57,14 +57,14 @@
|
|
|
57
57
|
"@atlassian/confluence-presets": "workspace:^",
|
|
58
58
|
"@atlassian/content-reconciliation": "^0.1.3506",
|
|
59
59
|
"@atlassian/editor-ai-injected-editors": "^32.0.0",
|
|
60
|
-
"@atlassian/editor-plugin-ai": "^72.
|
|
60
|
+
"@atlassian/editor-plugin-ai": "^72.2.0",
|
|
61
61
|
"@atlassian/structured-docs-types": "workspace:^",
|
|
62
62
|
"react": "^19.2.0",
|
|
63
63
|
"react-dom": "^19.2.0",
|
|
64
64
|
"react-intl": "^7.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@atlaskit/editor-common": "^122.
|
|
67
|
+
"@atlaskit/editor-common": "^122.6.0",
|
|
68
68
|
"react": "^18.2.0 || ^19.2.0",
|
|
69
69
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
70
70
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|