@atlaskit/editor-plugin-show-diff 13.0.5 → 13.0.7
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/calculateDiff/attrAwareTokenEncoder.js +13 -32
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +1 -1
- package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +1 -1
- package/dist/cjs/pm-plugins/decorations/utils/diffableAttrs.js +96 -0
- package/dist/cjs/pm-plugins/decorations/utils/getAttrChangeRanges.js +12 -23
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +1 -1
- package/dist/es2019/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +14 -32
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +3 -3
- package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +3 -3
- package/dist/es2019/pm-plugins/decorations/utils/diffableAttrs.js +88 -0
- package/dist/es2019/pm-plugins/decorations/utils/getAttrChangeRanges.js +12 -23
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +3 -3
- package/dist/esm/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +14 -32
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +3 -3
- package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +3 -3
- package/dist/esm/pm-plugins/decorations/utils/diffableAttrs.js +90 -0
- package/dist/esm/pm-plugins/decorations/utils/getAttrChangeRanges.js +12 -23
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +3 -3
- package/dist/types/pm-plugins/calculateDiff/attrAwareTokenEncoder.d.ts +0 -5
- package/dist/types/pm-plugins/decorations/utils/diffableAttrs.d.ts +20 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 13.0.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`2c712e57d3793`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/2c712e57d3793) -
|
|
8
|
+
Consolidate diffable-attribute rules into a single shared source of truth (`diffableAttrs`) used
|
|
9
|
+
by both the changeset token encoder (detection) and `getAttrChangeRanges` (rendering), and extend
|
|
10
|
+
the encoder to fold all mapped node types.
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
13
|
+
## 13.0.6
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [`7393a83aff767`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7393a83aff767) -
|
|
18
|
+
[ux] Fix inserted table diff overlays to follow rounded table corners when
|
|
19
|
+
platform_editor_table_diff_rounded_corners is enabled.
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 13.0.5
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -4,33 +4,19 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.attrAwareTokenEncoder = void 0;
|
|
7
|
+
var _diffableAttrs = require("../decorations/utils/diffableAttrs");
|
|
7
8
|
/**
|
|
8
|
-
* Attribute-aware token encoder for `prosemirror-changeset`.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* change at all.
|
|
14
|
-
*
|
|
15
|
-
* This encoder folds an allow-listed set of attributes into the open token so
|
|
16
|
-
* such changes register. Everything else encodes exactly as the default. The
|
|
17
|
-
* allow-list is deliberately narrow — folding in ephemeral attrs like `localId`
|
|
18
|
-
* would produce phantom diffs.
|
|
9
|
+
* Attribute-aware token encoder for `prosemirror-changeset`. The default encoder
|
|
10
|
+
* reduces a node to `node.type.name`, so an attribute-only change (e.g. a table
|
|
11
|
+
* cell recolour) tokenises identically on both sides and goes undetected. This
|
|
12
|
+
* folds the diffable attributes (from the shared `diffableAttrs` map) into the
|
|
13
|
+
* open token so such changes register.
|
|
19
14
|
*/
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
tableCell: ['background', 'colspan', 'rowspan'],
|
|
23
|
-
tableHeader: ['background', 'colspan', 'rowspan']
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Builds a stable composite token. Iterates the allow-list rather than
|
|
28
|
-
* `Object.keys` so ordering is deterministic for string comparison.
|
|
29
|
-
*/
|
|
16
|
+
// Stable composite token; attr names are pre-ordered by the caller.
|
|
30
17
|
var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
|
|
31
18
|
var _node$attrs;
|
|
32
19
|
var attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
33
|
-
// Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
|
|
34
20
|
var parts = attrNames.map(function (name) {
|
|
35
21
|
var _attrs$name;
|
|
36
22
|
return "".concat(name, "=").concat(JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null));
|
|
@@ -38,18 +24,16 @@ var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
|
|
|
38
24
|
return "".concat(node.type.name, "|").concat(parts.join('|'));
|
|
39
25
|
};
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* their allow-listed attributes into the open token. Characters and node-end
|
|
44
|
-
* tokens are left as-is, hence the `string | number` token type.
|
|
45
|
-
*/
|
|
27
|
+
// Like the library default, but node types with a `diffableAttrs` rule fold their
|
|
28
|
+
// attrs into the open token. Chars/node-end are unchanged, hence `string | number`.
|
|
46
29
|
var attrAwareTokenEncoder = exports.attrAwareTokenEncoder = {
|
|
47
30
|
encodeCharacter: function encodeCharacter(char, _marks) {
|
|
48
31
|
return char;
|
|
49
32
|
},
|
|
50
33
|
encodeNodeStart: function encodeNodeStart(node) {
|
|
51
|
-
var
|
|
52
|
-
|
|
34
|
+
var _node$attrs2;
|
|
35
|
+
var attrNames = (0, _diffableAttrs.getDiffableAttrNames)(node.type.name, (_node$attrs2 = node.attrs) !== null && _node$attrs2 !== void 0 ? _node$attrs2 : {});
|
|
36
|
+
if (attrNames && attrNames.length > 0) {
|
|
53
37
|
return encodeNodeWithAttrs(node, attrNames);
|
|
54
38
|
}
|
|
55
39
|
return node.type.name;
|
|
@@ -62,10 +46,7 @@ var attrAwareTokenEncoder = exports.attrAwareTokenEncoder = {
|
|
|
62
46
|
}
|
|
63
47
|
};
|
|
64
48
|
|
|
65
|
-
|
|
66
|
-
* Mirrors the library's private `typeID` so node-end tokens match the default
|
|
67
|
-
* encoding exactly. Reimplemented here because it is not exported.
|
|
68
|
-
*/
|
|
49
|
+
// Mirrors the library's private (unexported) `typeID` so node-end tokens match.
|
|
69
50
|
function typeID(type) {
|
|
70
51
|
var cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
|
|
71
52
|
var id = cache[type.name];
|
|
@@ -184,7 +184,7 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
184
184
|
var cellOverlay = document.createElement('div');
|
|
185
185
|
var isTraditional = colorScheme === 'traditional';
|
|
186
186
|
var isRoundedTable = (0, _expValEquals.expValEquals)('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
187
|
-
var addedCellStyle = isTraditional ? _traditional.traditionalAddedCellOverlayStyle : _standard.addedCellOverlayStyle;
|
|
187
|
+
var addedCellStyle = isTraditional ? isRoundedTable ? _traditional.traditionalAddedCellOverlayRoundedStyle : _traditional.traditionalAddedCellOverlayStyle : isRoundedTable ? _standard.addedCellOverlayRoundedStyle : _standard.addedCellOverlayStyle;
|
|
188
188
|
var deletedCellStyle = isTraditional ? isRoundedTable ? _traditional.deletedTraditionalCellOverlayRoundedStyle : _traditional.deletedTraditionalCellOverlayStyle : isRoundedTable ? _standard.deletedCellOverlayRoundedStyle : _standard.deletedCellOverlayStyle;
|
|
189
189
|
|
|
190
190
|
// On an inverted diff, an empty cell being filled is an addition, so give it the
|
|
@@ -154,7 +154,7 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, cellEdgeAttrs, n
|
|
|
154
154
|
var overlay = document.createElement('span');
|
|
155
155
|
var isRoundedTable = (0, _expValEquals.expValEquals)('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
156
156
|
var isTraditional = colorScheme === 'traditional';
|
|
157
|
-
var deletedCellStyle = isTraditional ? _traditional.deletedTraditionalCellOverlayStyle : _standard.deletedCellOverlayStyle;
|
|
157
|
+
var deletedCellStyle = isTraditional ? isRoundedTable ? _traditional.deletedTraditionalCellOverlayRoundedStyle : _traditional.deletedTraditionalCellOverlayStyle : isRoundedTable ? _standard.deletedCellOverlayRoundedStyle : _standard.deletedCellOverlayStyle;
|
|
158
158
|
var addedCellStyle = isTraditional ? isRoundedTable ? _traditional.traditionalAddedCellOverlayRoundedStyle : _traditional.traditionalAddedCellOverlayStyle : isRoundedTable ? _standard.addedCellOverlayRoundedStyle : _standard.addedCellOverlayStyle;
|
|
159
159
|
var overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
160
160
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isDiffableAttr = exports.getRequiredIncludedDiffableAttrs = exports.getIncludedDiffableAttrs = exports.getDiffableAttrNames = exports.DIFFABLE_ATTRS_BY_NODE_TYPE = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Single source of truth for which attributes of a node type represent a
|
|
9
|
+
* meaningful change. Shared by `attrAwareTokenEncoder` (changeset detection)
|
|
10
|
+
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Node types absent from this map have no attribute-level diffing.
|
|
14
|
+
var DIFFABLE_ATTRS_BY_NODE_TYPE = exports.DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
15
|
+
tableCell: {
|
|
16
|
+
include: ['background', 'colspan', 'rowspan']
|
|
17
|
+
},
|
|
18
|
+
tableHeader: {
|
|
19
|
+
include: ['background', 'colspan', 'rowspan']
|
|
20
|
+
},
|
|
21
|
+
// Inline nodes whose identity is their attrs.
|
|
22
|
+
date: {
|
|
23
|
+
include: ['timestamp']
|
|
24
|
+
},
|
|
25
|
+
emoji: {
|
|
26
|
+
include: ['shortName', 'id', 'text']
|
|
27
|
+
},
|
|
28
|
+
mention: {
|
|
29
|
+
include: ['id', 'text']
|
|
30
|
+
},
|
|
31
|
+
status: {
|
|
32
|
+
include: ['text', 'color']
|
|
33
|
+
},
|
|
34
|
+
taskItem: {
|
|
35
|
+
include: ['state']
|
|
36
|
+
},
|
|
37
|
+
// Media: id/collection/url identify the image.
|
|
38
|
+
media: {
|
|
39
|
+
include: ['id', 'collection', 'url']
|
|
40
|
+
},
|
|
41
|
+
// Extensions: any attribute change is meaningful except localId.
|
|
42
|
+
extension: {
|
|
43
|
+
exclude: ['localId']
|
|
44
|
+
},
|
|
45
|
+
inlineExtension: {
|
|
46
|
+
exclude: ['localId']
|
|
47
|
+
},
|
|
48
|
+
bodiedExtension: {
|
|
49
|
+
exclude: ['localId']
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. False if no rule.
|
|
54
|
+
var isDiffableAttr = exports.isDiffableAttr = function isDiffableAttr(nodeTypeName, attrName) {
|
|
55
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
56
|
+
if (!rule) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// The fixed include list for a node type, or `undefined` for no/exclude rule.
|
|
63
|
+
// Use where a node-independent attr list is needed (e.g. the inline node map).
|
|
64
|
+
var getIncludedDiffableAttrs = exports.getIncludedDiffableAttrs = function getIncludedDiffableAttrs(nodeTypeName) {
|
|
65
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
66
|
+
return rule && 'include' in rule ? rule.include : undefined;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Like `getIncludedDiffableAttrs` but asserts the include rule exists, so a
|
|
70
|
+
// consumer relying on a fixed list fails loudly if the rule is removed or
|
|
71
|
+
// switched to an exclude rule rather than silently drifting.
|
|
72
|
+
var getRequiredIncludedDiffableAttrs = exports.getRequiredIncludedDiffableAttrs = function getRequiredIncludedDiffableAttrs(nodeTypeName) {
|
|
73
|
+
var attrs = getIncludedDiffableAttrs(nodeTypeName);
|
|
74
|
+
if (!attrs) {
|
|
75
|
+
throw new Error("diffableAttrs: expected an include rule for \"".concat(nodeTypeName, "\""));
|
|
76
|
+
}
|
|
77
|
+
return attrs;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Concrete attr names to diff for a node instance, honouring include and exclude
|
|
82
|
+
* rules; `undefined` when the type has no rule. Exclude rules read the node's
|
|
83
|
+
* attrs and sort them, since key order isn't stable across the two diffed docs.
|
|
84
|
+
*/
|
|
85
|
+
var getDiffableAttrNames = exports.getDiffableAttrNames = function getDiffableAttrNames(nodeTypeName, attrs) {
|
|
86
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
87
|
+
if (!rule) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
if ('include' in rule) {
|
|
91
|
+
return rule.include;
|
|
92
|
+
}
|
|
93
|
+
return Object.keys(attrs).filter(function (name) {
|
|
94
|
+
return !rule.exclude.includes(name);
|
|
95
|
+
}).sort();
|
|
96
|
+
};
|
|
@@ -10,29 +10,20 @@ var _steps = require("@atlaskit/adf-schema/steps");
|
|
|
10
10
|
var _deprecatedPlatformFeatureExperiments = require("@atlaskit/editor-common/deprecated-platform-feature-experiments");
|
|
11
11
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
12
12
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
13
|
+
var _diffableAttrs = require("./diffableAttrs");
|
|
13
14
|
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; }
|
|
14
15
|
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) { (0, _defineProperty2.default)(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; }
|
|
15
16
|
var filterUndefined = function filterUndefined(x) {
|
|
16
17
|
return !!x;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
|
-
//
|
|
20
|
-
var mediaAttrs =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var taskItemAttrs = ['state'];
|
|
27
|
-
|
|
28
|
-
// Attributes that indicate an emoji change
|
|
29
|
-
var emojiAttrs = ['shortName', 'id', 'text'];
|
|
30
|
-
|
|
31
|
-
// Attributes that indicate a mention change (who is mentioned)
|
|
32
|
-
var mentionAttrs = ['id', 'text'];
|
|
33
|
-
|
|
34
|
-
// Attributes that indicate a status change (label or colour)
|
|
35
|
-
var statusAttrs = ['text', 'color'];
|
|
20
|
+
// Attr lists sourced from the shared `diffableAttrs` map (shared with the encoder).
|
|
21
|
+
var mediaAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('media');
|
|
22
|
+
var dateAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('date');
|
|
23
|
+
var taskItemAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('taskItem');
|
|
24
|
+
var emojiAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('emoji');
|
|
25
|
+
var mentionAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('mention');
|
|
26
|
+
var statusAttrs = (0, _diffableAttrs.getRequiredIncludedDiffableAttrs)('status');
|
|
36
27
|
|
|
37
28
|
// Map of node type name → the attrs that represent a meaningful content change for that node
|
|
38
29
|
var inlineNodeAttrMap = {
|
|
@@ -45,10 +36,8 @@ var isInlineAttrChangeNodeName = function isInlineAttrChangeNodeName(nodeName) {
|
|
|
45
36
|
return nodeName in inlineNodeAttrMap;
|
|
46
37
|
};
|
|
47
38
|
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Extension node type names
|
|
39
|
+
// Extension node type names. Their "any attr except localId" exclude rule lives
|
|
40
|
+
// in the shared `diffableAttrs` map and is applied via `isDiffableAttr` below.
|
|
52
41
|
var extensionNodeNames = ['extension', 'inlineExtension', 'bodiedExtension'];
|
|
53
42
|
var getStepAttrs = function getStepAttrs(step) {
|
|
54
43
|
if (step instanceof _transform.AttrStep) {
|
|
@@ -118,9 +107,9 @@ var getAttrChangeRanges = exports.getAttrChangeRanges = function getAttrChangeRa
|
|
|
118
107
|
};
|
|
119
108
|
}
|
|
120
109
|
|
|
121
|
-
// extension nodes: any
|
|
110
|
+
// extension nodes: highlight on any diffable attr change (exclude rule in shared map)
|
|
122
111
|
if (nodeAtPos && extensionNodeNames.includes(nodeAtPos.type.name) && stepAttrs.some(function (v) {
|
|
123
|
-
return
|
|
112
|
+
return (0, _diffableAttrs.isDiffableAttr)(nodeAtPos.type.name, v);
|
|
124
113
|
})) {
|
|
125
114
|
var isInline = nodeAtPos.type.name === 'inlineExtension';
|
|
126
115
|
return {
|
|
@@ -183,7 +183,7 @@ var applyCellOverlayStyles = function applyCellOverlayStyles(_ref2) {
|
|
|
183
183
|
element.querySelectorAll('td, th').forEach(function (cell) {
|
|
184
184
|
var overlay = document.createElement('span');
|
|
185
185
|
var isTraditional = colorScheme === 'traditional';
|
|
186
|
-
var deletedCellStyle = isTraditional ? _traditional.deletedTraditionalCellOverlayStyle : _standard.deletedCellOverlayStyle;
|
|
186
|
+
var deletedCellStyle = isTraditional ? isRoundedTable ? _traditional.deletedTraditionalCellOverlayRoundedStyle : _traditional.deletedTraditionalCellOverlayStyle : isRoundedTable ? _standard.deletedCellOverlayRoundedStyle : _standard.deletedCellOverlayStyle;
|
|
187
187
|
var addedCellStyle = isTraditional ? isRoundedTable ? _traditional.traditionalAddedCellOverlayRoundedStyle : _traditional.traditionalAddedCellOverlayStyleNew : isRoundedTable ? _standard.addedCellOverlayRoundedStyle : _standard.addedCellOverlayStyle;
|
|
188
188
|
var overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
189
189
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -1,30 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
* Attribute-aware token encoder for `prosemirror-changeset`.
|
|
3
|
-
*
|
|
4
|
-
* The library's default encoder reduces a node's open token to `node.type.name`,
|
|
5
|
-
* ignoring attributes. An attribute-only change (e.g. recolouring a table cell's
|
|
6
|
-
* `background`) therefore tokenises identically on both sides and reports no
|
|
7
|
-
* change at all.
|
|
8
|
-
*
|
|
9
|
-
* This encoder folds an allow-listed set of attributes into the open token so
|
|
10
|
-
* such changes register. Everything else encodes exactly as the default. The
|
|
11
|
-
* allow-list is deliberately narrow — folding in ephemeral attrs like `localId`
|
|
12
|
-
* would produce phantom diffs.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const DIFFED_ATTRS_BY_NODE_TYPE = {
|
|
16
|
-
tableCell: ['background', 'colspan', 'rowspan'],
|
|
17
|
-
tableHeader: ['background', 'colspan', 'rowspan']
|
|
18
|
-
};
|
|
1
|
+
import { getDiffableAttrNames } from '../decorations/utils/diffableAttrs';
|
|
19
2
|
|
|
20
3
|
/**
|
|
21
|
-
*
|
|
22
|
-
* `
|
|
4
|
+
* Attribute-aware token encoder for `prosemirror-changeset`. The default encoder
|
|
5
|
+
* reduces a node to `node.type.name`, so an attribute-only change (e.g. a table
|
|
6
|
+
* cell recolour) tokenises identically on both sides and goes undetected. This
|
|
7
|
+
* folds the diffable attributes (from the shared `diffableAttrs` map) into the
|
|
8
|
+
* open token so such changes register.
|
|
23
9
|
*/
|
|
10
|
+
|
|
11
|
+
// Stable composite token; attr names are pre-ordered by the caller.
|
|
24
12
|
const encodeNodeWithAttrs = (node, attrNames) => {
|
|
25
13
|
var _node$attrs;
|
|
26
14
|
const attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
27
|
-
// Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
|
|
28
15
|
const parts = attrNames.map(name => {
|
|
29
16
|
var _attrs$name;
|
|
30
17
|
return `${name}=${JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null)}`;
|
|
@@ -32,16 +19,14 @@ const encodeNodeWithAttrs = (node, attrNames) => {
|
|
|
32
19
|
return `${node.type.name}|${parts.join('|')}`;
|
|
33
20
|
};
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* their allow-listed attributes into the open token. Characters and node-end
|
|
38
|
-
* tokens are left as-is, hence the `string | number` token type.
|
|
39
|
-
*/
|
|
22
|
+
// Like the library default, but node types with a `diffableAttrs` rule fold their
|
|
23
|
+
// attrs into the open token. Chars/node-end are unchanged, hence `string | number`.
|
|
40
24
|
export const attrAwareTokenEncoder = {
|
|
41
25
|
encodeCharacter: (char, _marks) => char,
|
|
42
26
|
encodeNodeStart: node => {
|
|
43
|
-
|
|
44
|
-
|
|
27
|
+
var _node$attrs2;
|
|
28
|
+
const attrNames = getDiffableAttrNames(node.type.name, (_node$attrs2 = node.attrs) !== null && _node$attrs2 !== void 0 ? _node$attrs2 : {});
|
|
29
|
+
if (attrNames && attrNames.length > 0) {
|
|
45
30
|
return encodeNodeWithAttrs(node, attrNames);
|
|
46
31
|
}
|
|
47
32
|
return node.type.name;
|
|
@@ -50,10 +35,7 @@ export const attrAwareTokenEncoder = {
|
|
|
50
35
|
compareTokens: (a, b) => a === b
|
|
51
36
|
};
|
|
52
37
|
|
|
53
|
-
|
|
54
|
-
* Mirrors the library's private `typeID` so node-end tokens match the default
|
|
55
|
-
* encoding exactly. Reimplemented here because it is not exported.
|
|
56
|
-
*/
|
|
38
|
+
// Mirrors the library's private (unexported) `typeID` so node-end tokens match.
|
|
57
39
|
function typeID(type) {
|
|
58
40
|
const cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
|
|
59
41
|
let id = cache[type.name];
|
|
@@ -2,8 +2,8 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
|
2
2
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
4
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
5
|
-
import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
6
|
-
import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
5
|
+
import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayRoundedStyle, addedCellOverlayStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
6
|
+
import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
7
7
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
8
8
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
9
9
|
const displayNoneStyle = convertToInlineCss({
|
|
@@ -172,7 +172,7 @@ export const createBlockChangedDecoration = ({
|
|
|
172
172
|
const cellOverlay = document.createElement('div');
|
|
173
173
|
const isTraditional = colorScheme === 'traditional';
|
|
174
174
|
const isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
175
|
-
const addedCellStyle = isTraditional ? traditionalAddedCellOverlayStyle : addedCellOverlayStyle;
|
|
175
|
+
const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
176
176
|
const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
177
177
|
|
|
178
178
|
// On an inverted diff, an empty cell being filled is an addition, so give it the
|
|
@@ -4,8 +4,8 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
4
4
|
import { TableMap } from '@atlaskit/editor-tables/table-map';
|
|
5
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
6
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
7
|
-
import { addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedRowStyle, deletedCellOverlayStyle } from './colorSchemes/standard';
|
|
8
|
-
import { deletedTraditionalRowStyle, deletedTraditionalCellOverlayStyle, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
7
|
+
import { addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedRowStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
8
|
+
import { deletedTraditionalRowStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
9
9
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
10
10
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
11
11
|
import { applyCellEdgeAttrs, getRowCellEdgeAttrs } from './utils/tableCellEdgeAttrs';
|
|
@@ -133,7 +133,7 @@ const createChangedRowDOM = (rowNode, cellEdgeAttrs, nodeViewSerializer, colorSc
|
|
|
133
133
|
const overlay = document.createElement('span');
|
|
134
134
|
const isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
135
135
|
const isTraditional = colorScheme === 'traditional';
|
|
136
|
-
const deletedCellStyle = isTraditional ? deletedTraditionalCellOverlayStyle : deletedCellOverlayStyle;
|
|
136
|
+
const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
137
137
|
const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
138
138
|
const overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
139
139
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for which attributes of a node type represent a
|
|
3
|
+
* meaningful change. Shared by `attrAwareTokenEncoder` (changeset detection)
|
|
4
|
+
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Node types absent from this map have no attribute-level diffing.
|
|
8
|
+
export const DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
9
|
+
tableCell: {
|
|
10
|
+
include: ['background', 'colspan', 'rowspan']
|
|
11
|
+
},
|
|
12
|
+
tableHeader: {
|
|
13
|
+
include: ['background', 'colspan', 'rowspan']
|
|
14
|
+
},
|
|
15
|
+
// Inline nodes whose identity is their attrs.
|
|
16
|
+
date: {
|
|
17
|
+
include: ['timestamp']
|
|
18
|
+
},
|
|
19
|
+
emoji: {
|
|
20
|
+
include: ['shortName', 'id', 'text']
|
|
21
|
+
},
|
|
22
|
+
mention: {
|
|
23
|
+
include: ['id', 'text']
|
|
24
|
+
},
|
|
25
|
+
status: {
|
|
26
|
+
include: ['text', 'color']
|
|
27
|
+
},
|
|
28
|
+
taskItem: {
|
|
29
|
+
include: ['state']
|
|
30
|
+
},
|
|
31
|
+
// Media: id/collection/url identify the image.
|
|
32
|
+
media: {
|
|
33
|
+
include: ['id', 'collection', 'url']
|
|
34
|
+
},
|
|
35
|
+
// Extensions: any attribute change is meaningful except localId.
|
|
36
|
+
extension: {
|
|
37
|
+
exclude: ['localId']
|
|
38
|
+
},
|
|
39
|
+
inlineExtension: {
|
|
40
|
+
exclude: ['localId']
|
|
41
|
+
},
|
|
42
|
+
bodiedExtension: {
|
|
43
|
+
exclude: ['localId']
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. False if no rule.
|
|
48
|
+
export const isDiffableAttr = (nodeTypeName, attrName) => {
|
|
49
|
+
const rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
50
|
+
if (!rule) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// The fixed include list for a node type, or `undefined` for no/exclude rule.
|
|
57
|
+
// Use where a node-independent attr list is needed (e.g. the inline node map).
|
|
58
|
+
export const getIncludedDiffableAttrs = nodeTypeName => {
|
|
59
|
+
const rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
60
|
+
return rule && 'include' in rule ? rule.include : undefined;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Like `getIncludedDiffableAttrs` but asserts the include rule exists, so a
|
|
64
|
+
// consumer relying on a fixed list fails loudly if the rule is removed or
|
|
65
|
+
// switched to an exclude rule rather than silently drifting.
|
|
66
|
+
export const getRequiredIncludedDiffableAttrs = nodeTypeName => {
|
|
67
|
+
const attrs = getIncludedDiffableAttrs(nodeTypeName);
|
|
68
|
+
if (!attrs) {
|
|
69
|
+
throw new Error(`diffableAttrs: expected an include rule for "${nodeTypeName}"`);
|
|
70
|
+
}
|
|
71
|
+
return attrs;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Concrete attr names to diff for a node instance, honouring include and exclude
|
|
76
|
+
* rules; `undefined` when the type has no rule. Exclude rules read the node's
|
|
77
|
+
* attrs and sort them, since key order isn't stable across the two diffed docs.
|
|
78
|
+
*/
|
|
79
|
+
export const getDiffableAttrNames = (nodeTypeName, attrs) => {
|
|
80
|
+
const rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
81
|
+
if (!rule) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if ('include' in rule) {
|
|
85
|
+
return rule.include;
|
|
86
|
+
}
|
|
87
|
+
return Object.keys(attrs).filter(name => !rule.exclude.includes(name)).sort();
|
|
88
|
+
};
|
|
@@ -2,25 +2,16 @@ import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
|
2
2
|
import { isExperimentEnabled } from '@atlaskit/editor-common/deprecated-platform-feature-experiments';
|
|
3
3
|
import { AttrStep } from '@atlaskit/editor-prosemirror/transform';
|
|
4
4
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
|
+
import { getRequiredIncludedDiffableAttrs, isDiffableAttr } from './diffableAttrs';
|
|
5
6
|
const filterUndefined = x => !!x;
|
|
6
7
|
|
|
7
|
-
//
|
|
8
|
-
const mediaAttrs =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const taskItemAttrs = ['state'];
|
|
15
|
-
|
|
16
|
-
// Attributes that indicate an emoji change
|
|
17
|
-
const emojiAttrs = ['shortName', 'id', 'text'];
|
|
18
|
-
|
|
19
|
-
// Attributes that indicate a mention change (who is mentioned)
|
|
20
|
-
const mentionAttrs = ['id', 'text'];
|
|
21
|
-
|
|
22
|
-
// Attributes that indicate a status change (label or colour)
|
|
23
|
-
const statusAttrs = ['text', 'color'];
|
|
8
|
+
// Attr lists sourced from the shared `diffableAttrs` map (shared with the encoder).
|
|
9
|
+
const mediaAttrs = getRequiredIncludedDiffableAttrs('media');
|
|
10
|
+
const dateAttrs = getRequiredIncludedDiffableAttrs('date');
|
|
11
|
+
const taskItemAttrs = getRequiredIncludedDiffableAttrs('taskItem');
|
|
12
|
+
const emojiAttrs = getRequiredIncludedDiffableAttrs('emoji');
|
|
13
|
+
const mentionAttrs = getRequiredIncludedDiffableAttrs('mention');
|
|
14
|
+
const statusAttrs = getRequiredIncludedDiffableAttrs('status');
|
|
24
15
|
|
|
25
16
|
// Map of node type name → the attrs that represent a meaningful content change for that node
|
|
26
17
|
const inlineNodeAttrMap = {
|
|
@@ -31,10 +22,8 @@ const inlineNodeAttrMap = {
|
|
|
31
22
|
};
|
|
32
23
|
const isInlineAttrChangeNodeName = nodeName => nodeName in inlineNodeAttrMap;
|
|
33
24
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
// Extension node type names
|
|
25
|
+
// Extension node type names. Their "any attr except localId" exclude rule lives
|
|
26
|
+
// in the shared `diffableAttrs` map and is applied via `isDiffableAttr` below.
|
|
38
27
|
const extensionNodeNames = ['extension', 'inlineExtension', 'bodiedExtension'];
|
|
39
28
|
const getStepAttrs = step => {
|
|
40
29
|
if (step instanceof AttrStep) {
|
|
@@ -95,8 +84,8 @@ export const getAttrChangeRanges = (doc, steps, originalDoc) => {
|
|
|
95
84
|
};
|
|
96
85
|
}
|
|
97
86
|
|
|
98
|
-
// extension nodes: any
|
|
99
|
-
if (nodeAtPos && extensionNodeNames.includes(nodeAtPos.type.name) && stepAttrs.some(v =>
|
|
87
|
+
// extension nodes: highlight on any diffable attr change (exclude rule in shared map)
|
|
88
|
+
if (nodeAtPos && extensionNodeNames.includes(nodeAtPos.type.name) && stepAttrs.some(v => isDiffableAttr(nodeAtPos.type.name, v))) {
|
|
100
89
|
const isInline = nodeAtPos.type.name === 'inlineExtension';
|
|
101
90
|
return {
|
|
102
91
|
fromB: step.pos,
|
|
@@ -3,8 +3,8 @@ import { trackChangesMessages } from '@atlaskit/editor-common/messages';
|
|
|
3
3
|
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
4
4
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
5
|
import { isExtendedEnabled } from '../../isExtendedEnabled';
|
|
6
|
-
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle } from '../colorSchemes/standard';
|
|
7
|
-
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
|
|
6
|
+
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
|
|
7
|
+
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from '../colorSchemes/traditional';
|
|
8
8
|
import { applyTableCellEdgeAttrs } from './tableCellEdgeAttrs';
|
|
9
9
|
const lozengeStyle = convertToInlineCss({
|
|
10
10
|
display: 'inline-flex',
|
|
@@ -168,7 +168,7 @@ const applyCellOverlayStyles = ({
|
|
|
168
168
|
element.querySelectorAll('td, th').forEach(cell => {
|
|
169
169
|
const overlay = document.createElement('span');
|
|
170
170
|
const isTraditional = colorScheme === 'traditional';
|
|
171
|
-
const deletedCellStyle = isTraditional ? deletedTraditionalCellOverlayStyle : deletedCellOverlayStyle;
|
|
171
|
+
const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
172
172
|
const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyleNew : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
173
173
|
const overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
174
174
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -1,30 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
* Attribute-aware token encoder for `prosemirror-changeset`.
|
|
3
|
-
*
|
|
4
|
-
* The library's default encoder reduces a node's open token to `node.type.name`,
|
|
5
|
-
* ignoring attributes. An attribute-only change (e.g. recolouring a table cell's
|
|
6
|
-
* `background`) therefore tokenises identically on both sides and reports no
|
|
7
|
-
* change at all.
|
|
8
|
-
*
|
|
9
|
-
* This encoder folds an allow-listed set of attributes into the open token so
|
|
10
|
-
* such changes register. Everything else encodes exactly as the default. The
|
|
11
|
-
* allow-list is deliberately narrow — folding in ephemeral attrs like `localId`
|
|
12
|
-
* would produce phantom diffs.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
var DIFFED_ATTRS_BY_NODE_TYPE = {
|
|
16
|
-
tableCell: ['background', 'colspan', 'rowspan'],
|
|
17
|
-
tableHeader: ['background', 'colspan', 'rowspan']
|
|
18
|
-
};
|
|
1
|
+
import { getDiffableAttrNames } from '../decorations/utils/diffableAttrs';
|
|
19
2
|
|
|
20
3
|
/**
|
|
21
|
-
*
|
|
22
|
-
* `
|
|
4
|
+
* Attribute-aware token encoder for `prosemirror-changeset`. The default encoder
|
|
5
|
+
* reduces a node to `node.type.name`, so an attribute-only change (e.g. a table
|
|
6
|
+
* cell recolour) tokenises identically on both sides and goes undetected. This
|
|
7
|
+
* folds the diffable attributes (from the shared `diffableAttrs` map) into the
|
|
8
|
+
* open token so such changes register.
|
|
23
9
|
*/
|
|
10
|
+
|
|
11
|
+
// Stable composite token; attr names are pre-ordered by the caller.
|
|
24
12
|
var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
|
|
25
13
|
var _node$attrs;
|
|
26
14
|
var attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
27
|
-
// Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
|
|
28
15
|
var parts = attrNames.map(function (name) {
|
|
29
16
|
var _attrs$name;
|
|
30
17
|
return "".concat(name, "=").concat(JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null));
|
|
@@ -32,18 +19,16 @@ var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
|
|
|
32
19
|
return "".concat(node.type.name, "|").concat(parts.join('|'));
|
|
33
20
|
};
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* their allow-listed attributes into the open token. Characters and node-end
|
|
38
|
-
* tokens are left as-is, hence the `string | number` token type.
|
|
39
|
-
*/
|
|
22
|
+
// Like the library default, but node types with a `diffableAttrs` rule fold their
|
|
23
|
+
// attrs into the open token. Chars/node-end are unchanged, hence `string | number`.
|
|
40
24
|
export var attrAwareTokenEncoder = {
|
|
41
25
|
encodeCharacter: function encodeCharacter(char, _marks) {
|
|
42
26
|
return char;
|
|
43
27
|
},
|
|
44
28
|
encodeNodeStart: function encodeNodeStart(node) {
|
|
45
|
-
var
|
|
46
|
-
|
|
29
|
+
var _node$attrs2;
|
|
30
|
+
var attrNames = getDiffableAttrNames(node.type.name, (_node$attrs2 = node.attrs) !== null && _node$attrs2 !== void 0 ? _node$attrs2 : {});
|
|
31
|
+
if (attrNames && attrNames.length > 0) {
|
|
47
32
|
return encodeNodeWithAttrs(node, attrNames);
|
|
48
33
|
}
|
|
49
34
|
return node.type.name;
|
|
@@ -56,10 +41,7 @@ export var attrAwareTokenEncoder = {
|
|
|
56
41
|
}
|
|
57
42
|
};
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
* Mirrors the library's private `typeID` so node-end tokens match the default
|
|
61
|
-
* encoding exactly. Reimplemented here because it is not exported.
|
|
62
|
-
*/
|
|
44
|
+
// Mirrors the library's private (unexported) `typeID` so node-end tokens match.
|
|
63
45
|
function typeID(type) {
|
|
64
46
|
var cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
|
|
65
47
|
var id = cache[type.name];
|
|
@@ -3,8 +3,8 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
|
3
3
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
4
4
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
5
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
6
|
-
import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
7
|
-
import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
6
|
+
import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayRoundedStyle, addedCellOverlayStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
7
|
+
import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
8
8
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
9
9
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
10
10
|
var displayNoneStyle = convertToInlineCss({
|
|
@@ -177,7 +177,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
177
177
|
var cellOverlay = document.createElement('div');
|
|
178
178
|
var isTraditional = colorScheme === 'traditional';
|
|
179
179
|
var isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
180
|
-
var addedCellStyle = isTraditional ? traditionalAddedCellOverlayStyle : addedCellOverlayStyle;
|
|
180
|
+
var addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
181
181
|
var deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
182
182
|
|
|
183
183
|
// On an inverted diff, an empty cell being filled is an addition, so give it the
|
|
@@ -11,8 +11,8 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
11
11
|
import { TableMap } from '@atlaskit/editor-tables/table-map';
|
|
12
12
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
13
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
14
|
-
import { addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedRowStyle, deletedCellOverlayStyle } from './colorSchemes/standard';
|
|
15
|
-
import { deletedTraditionalRowStyle, deletedTraditionalCellOverlayStyle, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
14
|
+
import { addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedRowStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
|
|
15
|
+
import { deletedTraditionalRowStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle } from './colorSchemes/traditional';
|
|
16
16
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
17
17
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
18
18
|
import { applyCellEdgeAttrs, getRowCellEdgeAttrs } from './utils/tableCellEdgeAttrs';
|
|
@@ -147,7 +147,7 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, cellEdgeAttrs, n
|
|
|
147
147
|
var overlay = document.createElement('span');
|
|
148
148
|
var isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
|
|
149
149
|
var isTraditional = colorScheme === 'traditional';
|
|
150
|
-
var deletedCellStyle = isTraditional ? deletedTraditionalCellOverlayStyle : deletedCellOverlayStyle;
|
|
150
|
+
var deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
151
151
|
var addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
152
152
|
var overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
153
153
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for which attributes of a node type represent a
|
|
3
|
+
* meaningful change. Shared by `attrAwareTokenEncoder` (changeset detection)
|
|
4
|
+
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Node types absent from this map have no attribute-level diffing.
|
|
8
|
+
export var DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
9
|
+
tableCell: {
|
|
10
|
+
include: ['background', 'colspan', 'rowspan']
|
|
11
|
+
},
|
|
12
|
+
tableHeader: {
|
|
13
|
+
include: ['background', 'colspan', 'rowspan']
|
|
14
|
+
},
|
|
15
|
+
// Inline nodes whose identity is their attrs.
|
|
16
|
+
date: {
|
|
17
|
+
include: ['timestamp']
|
|
18
|
+
},
|
|
19
|
+
emoji: {
|
|
20
|
+
include: ['shortName', 'id', 'text']
|
|
21
|
+
},
|
|
22
|
+
mention: {
|
|
23
|
+
include: ['id', 'text']
|
|
24
|
+
},
|
|
25
|
+
status: {
|
|
26
|
+
include: ['text', 'color']
|
|
27
|
+
},
|
|
28
|
+
taskItem: {
|
|
29
|
+
include: ['state']
|
|
30
|
+
},
|
|
31
|
+
// Media: id/collection/url identify the image.
|
|
32
|
+
media: {
|
|
33
|
+
include: ['id', 'collection', 'url']
|
|
34
|
+
},
|
|
35
|
+
// Extensions: any attribute change is meaningful except localId.
|
|
36
|
+
extension: {
|
|
37
|
+
exclude: ['localId']
|
|
38
|
+
},
|
|
39
|
+
inlineExtension: {
|
|
40
|
+
exclude: ['localId']
|
|
41
|
+
},
|
|
42
|
+
bodiedExtension: {
|
|
43
|
+
exclude: ['localId']
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. False if no rule.
|
|
48
|
+
export var isDiffableAttr = function isDiffableAttr(nodeTypeName, attrName) {
|
|
49
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
50
|
+
if (!rule) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// The fixed include list for a node type, or `undefined` for no/exclude rule.
|
|
57
|
+
// Use where a node-independent attr list is needed (e.g. the inline node map).
|
|
58
|
+
export var getIncludedDiffableAttrs = function getIncludedDiffableAttrs(nodeTypeName) {
|
|
59
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
60
|
+
return rule && 'include' in rule ? rule.include : undefined;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Like `getIncludedDiffableAttrs` but asserts the include rule exists, so a
|
|
64
|
+
// consumer relying on a fixed list fails loudly if the rule is removed or
|
|
65
|
+
// switched to an exclude rule rather than silently drifting.
|
|
66
|
+
export var getRequiredIncludedDiffableAttrs = function getRequiredIncludedDiffableAttrs(nodeTypeName) {
|
|
67
|
+
var attrs = getIncludedDiffableAttrs(nodeTypeName);
|
|
68
|
+
if (!attrs) {
|
|
69
|
+
throw new Error("diffableAttrs: expected an include rule for \"".concat(nodeTypeName, "\""));
|
|
70
|
+
}
|
|
71
|
+
return attrs;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Concrete attr names to diff for a node instance, honouring include and exclude
|
|
76
|
+
* rules; `undefined` when the type has no rule. Exclude rules read the node's
|
|
77
|
+
* attrs and sort them, since key order isn't stable across the two diffed docs.
|
|
78
|
+
*/
|
|
79
|
+
export var getDiffableAttrNames = function getDiffableAttrNames(nodeTypeName, attrs) {
|
|
80
|
+
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
81
|
+
if (!rule) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
if ('include' in rule) {
|
|
85
|
+
return rule.include;
|
|
86
|
+
}
|
|
87
|
+
return Object.keys(attrs).filter(function (name) {
|
|
88
|
+
return !rule.exclude.includes(name);
|
|
89
|
+
}).sort();
|
|
90
|
+
};
|
|
@@ -5,27 +5,18 @@ import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
|
|
|
5
5
|
import { isExperimentEnabled } from '@atlaskit/editor-common/deprecated-platform-feature-experiments';
|
|
6
6
|
import { AttrStep } from '@atlaskit/editor-prosemirror/transform';
|
|
7
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
|
+
import { getRequiredIncludedDiffableAttrs, isDiffableAttr } from './diffableAttrs';
|
|
8
9
|
var filterUndefined = function filterUndefined(x) {
|
|
9
10
|
return !!x;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
//
|
|
13
|
-
var mediaAttrs =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
var taskItemAttrs = ['state'];
|
|
20
|
-
|
|
21
|
-
// Attributes that indicate an emoji change
|
|
22
|
-
var emojiAttrs = ['shortName', 'id', 'text'];
|
|
23
|
-
|
|
24
|
-
// Attributes that indicate a mention change (who is mentioned)
|
|
25
|
-
var mentionAttrs = ['id', 'text'];
|
|
26
|
-
|
|
27
|
-
// Attributes that indicate a status change (label or colour)
|
|
28
|
-
var statusAttrs = ['text', 'color'];
|
|
13
|
+
// Attr lists sourced from the shared `diffableAttrs` map (shared with the encoder).
|
|
14
|
+
var mediaAttrs = getRequiredIncludedDiffableAttrs('media');
|
|
15
|
+
var dateAttrs = getRequiredIncludedDiffableAttrs('date');
|
|
16
|
+
var taskItemAttrs = getRequiredIncludedDiffableAttrs('taskItem');
|
|
17
|
+
var emojiAttrs = getRequiredIncludedDiffableAttrs('emoji');
|
|
18
|
+
var mentionAttrs = getRequiredIncludedDiffableAttrs('mention');
|
|
19
|
+
var statusAttrs = getRequiredIncludedDiffableAttrs('status');
|
|
29
20
|
|
|
30
21
|
// Map of node type name → the attrs that represent a meaningful content change for that node
|
|
31
22
|
var inlineNodeAttrMap = {
|
|
@@ -38,10 +29,8 @@ var isInlineAttrChangeNodeName = function isInlineAttrChangeNodeName(nodeName) {
|
|
|
38
29
|
return nodeName in inlineNodeAttrMap;
|
|
39
30
|
};
|
|
40
31
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Extension node type names
|
|
32
|
+
// Extension node type names. Their "any attr except localId" exclude rule lives
|
|
33
|
+
// in the shared `diffableAttrs` map and is applied via `isDiffableAttr` below.
|
|
45
34
|
var extensionNodeNames = ['extension', 'inlineExtension', 'bodiedExtension'];
|
|
46
35
|
var getStepAttrs = function getStepAttrs(step) {
|
|
47
36
|
if (step instanceof AttrStep) {
|
|
@@ -111,9 +100,9 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, steps, origin
|
|
|
111
100
|
};
|
|
112
101
|
}
|
|
113
102
|
|
|
114
|
-
// extension nodes: any
|
|
103
|
+
// extension nodes: highlight on any diffable attr change (exclude rule in shared map)
|
|
115
104
|
if (nodeAtPos && extensionNodeNames.includes(nodeAtPos.type.name) && stepAttrs.some(function (v) {
|
|
116
|
-
return
|
|
105
|
+
return isDiffableAttr(nodeAtPos.type.name, v);
|
|
117
106
|
})) {
|
|
118
107
|
var isInline = nodeAtPos.type.name === 'inlineExtension';
|
|
119
108
|
return {
|
|
@@ -4,8 +4,8 @@ import { trackChangesMessages } from '@atlaskit/editor-common/messages';
|
|
|
4
4
|
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
5
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
6
6
|
import { isExtendedEnabled } from '../../isExtendedEnabled';
|
|
7
|
-
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle } from '../colorSchemes/standard';
|
|
8
|
-
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
|
|
7
|
+
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
|
|
8
|
+
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from '../colorSchemes/traditional';
|
|
9
9
|
import { applyTableCellEdgeAttrs } from './tableCellEdgeAttrs';
|
|
10
10
|
var lozengeStyle = convertToInlineCss({
|
|
11
11
|
display: 'inline-flex',
|
|
@@ -176,7 +176,7 @@ var applyCellOverlayStyles = function applyCellOverlayStyles(_ref2) {
|
|
|
176
176
|
element.querySelectorAll('td, th').forEach(function (cell) {
|
|
177
177
|
var overlay = document.createElement('span');
|
|
178
178
|
var isTraditional = colorScheme === 'traditional';
|
|
179
|
-
var deletedCellStyle = isTraditional ? deletedTraditionalCellOverlayStyle : deletedCellOverlayStyle;
|
|
179
|
+
var deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
|
|
180
180
|
var addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyleNew : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
|
|
181
181
|
var overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
|
|
182
182
|
overlay.setAttribute('style', overlayStyle);
|
|
@@ -1,7 +1,2 @@
|
|
|
1
1
|
import type { TokenEncoder } from 'prosemirror-changeset';
|
|
2
|
-
/**
|
|
3
|
-
* Identical to the library default except that allow-listed node types encode
|
|
4
|
-
* their allow-listed attributes into the open token. Characters and node-end
|
|
5
|
-
* tokens are left as-is, hence the `string | number` token type.
|
|
6
|
-
*/
|
|
7
2
|
export declare const attrAwareTokenEncoder: TokenEncoder<string | number>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for which attributes of a node type represent a
|
|
3
|
+
* meaningful change. Shared by `attrAwareTokenEncoder` (changeset detection)
|
|
4
|
+
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
5
|
+
*/
|
|
6
|
+
export type DiffableAttrsRule = {
|
|
7
|
+
include: readonly string[];
|
|
8
|
+
} | {
|
|
9
|
+
exclude: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
export declare const DIFFABLE_ATTRS_BY_NODE_TYPE: Record<string, DiffableAttrsRule>;
|
|
12
|
+
export declare const isDiffableAttr: (nodeTypeName: string, attrName: string) => boolean;
|
|
13
|
+
export declare const getIncludedDiffableAttrs: (nodeTypeName: string) => readonly string[] | undefined;
|
|
14
|
+
export declare const getRequiredIncludedDiffableAttrs: (nodeTypeName: string) => readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Concrete attr names to diff for a node instance, honouring include and exclude
|
|
17
|
+
* rules; `undefined` when the type has no rule. Exclude rules read the node's
|
|
18
|
+
* attrs and sort them, since key order isn't stable across the two diffed docs.
|
|
19
|
+
*/
|
|
20
|
+
export declare const getDiffableAttrNames: (nodeTypeName: string, attrs: Record<string, unknown>) => readonly string[] | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.7",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
28
28
|
"@atlaskit/editor-tables": "^3.0.0",
|
|
29
29
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
30
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
30
|
+
"@atlaskit/tmp-editor-statsig": "^149.0.0",
|
|
31
31
|
"@atlaskit/tokens": "^16.7.0",
|
|
32
32
|
"@babel/runtime": "^7.0.0",
|
|
33
33
|
"@compiled/react": "^1.0.2",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@atlaskit/button": "^25.0.0",
|
|
41
41
|
"@atlaskit/css": "^1.0.0",
|
|
42
42
|
"@atlaskit/dropdown-menu": "^18.0.0",
|
|
43
|
-
"@atlaskit/editor-core": "^224.
|
|
43
|
+
"@atlaskit/editor-core": "^224.1.0",
|
|
44
44
|
"@atlaskit/editor-json-transformer": "^9.4.0",
|
|
45
45
|
"@atlaskit/form": "^17.0.0",
|
|
46
46
|
"@atlaskit/primitives": "^22.2.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"react-intl": "^7.0.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@atlaskit/editor-common": "^119.
|
|
56
|
+
"@atlaskit/editor-common": "^119.7.0",
|
|
57
57
|
"react": "^18.2.0 || ^19.2.0"
|
|
58
58
|
},
|
|
59
59
|
"techstack": {
|