@atlaskit/editor-plugin-show-diff 0.1.2 → 0.1.4
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 +14 -0
- package/dist/cjs/pm-plugins/NodeViewSerializer.js +101 -0
- package/dist/cjs/pm-plugins/decorations.js +98 -14
- package/dist/cjs/pm-plugins/main.js +31 -7
- package/dist/es2019/pm-plugins/NodeViewSerializer.js +82 -0
- package/dist/es2019/pm-plugins/decorations.js +94 -14
- package/dist/es2019/pm-plugins/main.js +31 -7
- package/dist/esm/pm-plugins/NodeViewSerializer.js +94 -0
- package/dist/esm/pm-plugins/decorations.js +98 -14
- package/dist/esm/pm-plugins/main.js +31 -7
- package/dist/types/pm-plugins/NodeViewSerializer.d.ts +62 -0
- package/dist/types/pm-plugins/decorations.d.ts +5 -1
- package/dist/types-ts4.5/pm-plugins/NodeViewSerializer.d.ts +62 -0
- package/dist/types-ts4.5/pm-plugins/decorations.d.ts +5 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 0.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`1fc9ea612c6ef`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/1fc9ea612c6ef) -
|
|
8
|
+
[EDITOR-1358] Fix nit + minor local bug
|
|
9
|
+
|
|
10
|
+
## 0.1.3
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [`8700ce859da07`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/8700ce859da07) -
|
|
15
|
+
[EDITOR-1249] Added inline node support for show diff
|
|
16
|
+
|
|
3
17
|
## 0.1.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.NodeViewSerializer = void 0;
|
|
8
|
+
exports.isEditorViewWithNodeViews = isEditorViewWithNodeViews;
|
|
9
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
11
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
12
|
+
/**
|
|
13
|
+
* Utilities for working with ProseMirror node views and DOM serialization within the
|
|
14
|
+
* Show Diff editor plugin.
|
|
15
|
+
*
|
|
16
|
+
* This module centralizes:
|
|
17
|
+
* - Access to the editor's `nodeViews` registry (when available on `EditorView`)
|
|
18
|
+
* - Safe attempts to instantiate a node view for a given node, with a blocklist to
|
|
19
|
+
* avoid node types that are known to be problematic in this context (e.g. tables)
|
|
20
|
+
* - Schema-driven serialization of nodes and fragments to DOM via `DOMSerializer`
|
|
21
|
+
*
|
|
22
|
+
* The Show Diff decorations leverage this to either render nodes using their
|
|
23
|
+
* corresponding node view implementation, or fall back to DOM serialization.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Narrowed `EditorView` that exposes the internal `nodeViews` registry.
|
|
28
|
+
* Many editor instances provide this, but it's not part of the base type.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Type guard to detect whether an `EditorView` exposes a `nodeViews` map.
|
|
33
|
+
*/
|
|
34
|
+
function isEditorViewWithNodeViews(view) {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
return view.nodeViews !== undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Encapsulates DOM serialization and node view access/creation.
|
|
41
|
+
*
|
|
42
|
+
* Responsible for:
|
|
43
|
+
* - Creating a `DOMSerializer` from the provided schema
|
|
44
|
+
* - Reading `nodeViews` from an `EditorView` (if present) or using an explicit mapping
|
|
45
|
+
* - Preventing node view creation for blocklisted node types
|
|
46
|
+
*/
|
|
47
|
+
var NodeViewSerializer = exports.NodeViewSerializer = /*#__PURE__*/function () {
|
|
48
|
+
function NodeViewSerializer(params) {
|
|
49
|
+
var _ref, _params$nodeViews, _this$editorView, _params$blocklist;
|
|
50
|
+
(0, _classCallCheck2.default)(this, NodeViewSerializer);
|
|
51
|
+
this.serializer = _model.DOMSerializer.fromSchema(params.schema);
|
|
52
|
+
if (params.editorView && isEditorViewWithNodeViews(params.editorView)) {
|
|
53
|
+
this.editorView = params.editorView;
|
|
54
|
+
}
|
|
55
|
+
this.nodeViews = (_ref = (_params$nodeViews = params.nodeViews) !== null && _params$nodeViews !== void 0 ? _params$nodeViews : (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.nodeViews) !== null && _ref !== void 0 ? _ref : {};
|
|
56
|
+
this.nodeViewBlocklist = new Set((_params$blocklist = params.blocklist) !== null && _params$blocklist !== void 0 ? _params$blocklist : ['tableRow', 'table', 'paragraph']);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Attempts to create a node view for the given node.
|
|
61
|
+
*
|
|
62
|
+
* Returns `null` when there is no `EditorView`, no constructor for the node type,
|
|
63
|
+
* or the node type is blocklisted. Otherwise returns the constructed node view instance.
|
|
64
|
+
*/
|
|
65
|
+
return (0, _createClass2.default)(NodeViewSerializer, [{
|
|
66
|
+
key: "tryCreateNodeView",
|
|
67
|
+
value: function tryCreateNodeView(targetNode) {
|
|
68
|
+
if (!this.editorView) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
var constructor = this.nodeViews[targetNode.type.name];
|
|
72
|
+
if (!constructor) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (this.nodeViewBlocklist.has(targetNode.type.name)) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return constructor(targetNode, this.editorView, function () {
|
|
79
|
+
return 0;
|
|
80
|
+
}, [], {});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Serializes a node to a DOM `Node` using the schema's `DOMSerializer`.
|
|
85
|
+
*/
|
|
86
|
+
}, {
|
|
87
|
+
key: "serializeNode",
|
|
88
|
+
value: function serializeNode(node) {
|
|
89
|
+
return this.serializer.serializeNode(node);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Serializes a fragment to a `DocumentFragment` using the schema's `DOMSerializer`.
|
|
94
|
+
*/
|
|
95
|
+
}, {
|
|
96
|
+
key: "serializeFragment",
|
|
97
|
+
value: function serializeFragment(fragment) {
|
|
98
|
+
return this.serializer.serializeFragment(fragment);
|
|
99
|
+
}
|
|
100
|
+
}]);
|
|
101
|
+
}();
|
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createInlineChangedDecoration = exports.createDeletedContentDecoration = void 0;
|
|
7
7
|
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
8
|
-
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
9
8
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
9
|
+
var _NodeViewSerializer = require("./NodeViewSerializer");
|
|
10
10
|
var style = (0, _lazyNodeView.convertToInlineCss)({
|
|
11
11
|
background: "var(--ds-background-accent-purple-subtlest, #F3F0FF)",
|
|
12
12
|
textDecoration: 'underline',
|
|
@@ -14,7 +14,6 @@ var style = (0, _lazyNodeView.convertToInlineCss)({
|
|
|
14
14
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
15
15
|
textDecorationColor: "var(--ds-border-accent-purple, #8270DB)"
|
|
16
16
|
});
|
|
17
|
-
|
|
18
17
|
/**
|
|
19
18
|
* Inline decoration used for insertions as the content already exists in the document
|
|
20
19
|
*
|
|
@@ -29,7 +28,18 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
|
|
|
29
28
|
};
|
|
30
29
|
var deletedContentStyle = (0, _lazyNodeView.convertToInlineCss)({
|
|
31
30
|
color: "var(--ds-text-accent-gray, #44546F)",
|
|
32
|
-
textDecoration: 'line-through'
|
|
31
|
+
textDecoration: 'line-through',
|
|
32
|
+
position: 'relative',
|
|
33
|
+
opacity: 0.6
|
|
34
|
+
});
|
|
35
|
+
var deletedContentStyleUnbounded = (0, _lazyNodeView.convertToInlineCss)({
|
|
36
|
+
position: 'absolute',
|
|
37
|
+
top: '50%',
|
|
38
|
+
width: '100%',
|
|
39
|
+
display: 'inline-block',
|
|
40
|
+
borderTop: "1px solid ".concat("var(--ds-text-accent-gray, #44546F)"),
|
|
41
|
+
pointerEvents: 'none',
|
|
42
|
+
zIndex: 1
|
|
33
43
|
});
|
|
34
44
|
|
|
35
45
|
/**
|
|
@@ -43,7 +53,9 @@ var deletedContentStyle = (0, _lazyNodeView.convertToInlineCss)({
|
|
|
43
53
|
var createDeletedContentDecoration = exports.createDeletedContentDecoration = function createDeletedContentDecoration(_ref) {
|
|
44
54
|
var change = _ref.change,
|
|
45
55
|
doc = _ref.doc,
|
|
46
|
-
tr = _ref.tr
|
|
56
|
+
tr = _ref.tr,
|
|
57
|
+
editorView = _ref.editorView,
|
|
58
|
+
nodeViews = _ref.nodeViews;
|
|
47
59
|
var dom = document.createElement('span');
|
|
48
60
|
dom.setAttribute('style', deletedContentStyle);
|
|
49
61
|
|
|
@@ -53,22 +65,94 @@ var createDeletedContentDecoration = exports.createDeletedContentDecoration = fu
|
|
|
53
65
|
* or sliced End depth is and match only the content and not with the entire node.
|
|
54
66
|
*/
|
|
55
67
|
var slice = doc.slice(change.fromA, change.toA);
|
|
68
|
+
var nodeViewSerializer = new _NodeViewSerializer.NodeViewSerializer({
|
|
69
|
+
schema: tr.doc.type.schema,
|
|
70
|
+
editorView: editorView,
|
|
71
|
+
nodeViews: nodeViews
|
|
72
|
+
});
|
|
56
73
|
slice.content.forEach(function (node) {
|
|
57
|
-
|
|
74
|
+
// Create a wrapper for each node with strikethrough
|
|
75
|
+
var createWrapperWithStrikethrough = function createWrapperWithStrikethrough() {
|
|
76
|
+
var wrapper = document.createElement('span');
|
|
77
|
+
wrapper.style.position = 'relative';
|
|
78
|
+
wrapper.style.width = 'fit-content';
|
|
79
|
+
var strikethrough = document.createElement('span');
|
|
80
|
+
strikethrough.setAttribute('style', deletedContentStyleUnbounded);
|
|
81
|
+
wrapper.append(strikethrough);
|
|
82
|
+
return wrapper;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Helper function to handle multiple child nodes
|
|
86
|
+
var handleMultipleChildNodes = function handleMultipleChildNodes(node) {
|
|
87
|
+
if (node.content.childCount > 1 && node.type.inlineContent) {
|
|
88
|
+
node.content.forEach(function (childNode) {
|
|
89
|
+
var childNodeView = nodeViewSerializer.tryCreateNodeView(childNode);
|
|
90
|
+
if (childNodeView) {
|
|
91
|
+
var lineBreak = document.createElement('br');
|
|
92
|
+
targetNode = node;
|
|
93
|
+
dom.append(lineBreak);
|
|
94
|
+
var wrapper = createWrapperWithStrikethrough();
|
|
95
|
+
wrapper.append(childNodeView.dom);
|
|
96
|
+
dom.append(wrapper);
|
|
97
|
+
} else {
|
|
98
|
+
// Fallback to serializing the individual child node
|
|
99
|
+
var serializedChild = nodeViewSerializer.serializeNode(childNode);
|
|
100
|
+
dom.append(serializedChild);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return true; // Indicates we handled multiple children
|
|
104
|
+
}
|
|
105
|
+
return false; // Indicates single child, continue with normal logic
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// Determine which node to use and how to serialize
|
|
58
109
|
var isFirst = slice.content.firstChild === node;
|
|
59
110
|
var isLast = slice.content.lastChild === node;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
111
|
+
var hasInlineContent = node.content.childCount > 0 && node.type.inlineContent === true;
|
|
112
|
+
var targetNode;
|
|
113
|
+
var fallbackSerialization;
|
|
114
|
+
if ((isFirst || isLast && slice.content.childCount > 2) && hasInlineContent) {
|
|
115
|
+
if (handleMultipleChildNodes(node)) {
|
|
116
|
+
return;
|
|
65
117
|
}
|
|
118
|
+
targetNode = node.content.content[0];
|
|
119
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
120
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
121
|
+
};
|
|
66
122
|
} else if (isLast && slice.content.childCount === 2) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
123
|
+
if (handleMultipleChildNodes(node)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
targetNode = node;
|
|
127
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
128
|
+
if (node.type.name === 'text') {
|
|
129
|
+
return document.createTextNode(node.text || '');
|
|
130
|
+
}
|
|
131
|
+
if (node.type.name === 'paragraph') {
|
|
132
|
+
var lineBreak = document.createElement('br');
|
|
133
|
+
dom.append(lineBreak);
|
|
134
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
135
|
+
}
|
|
136
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
137
|
+
};
|
|
138
|
+
} else {
|
|
139
|
+
if (handleMultipleChildNodes(node)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
targetNode = node.content.content[0] || node;
|
|
143
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
144
|
+
return nodeViewSerializer.serializeNode(node);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Try to create node view, fallback to serialization
|
|
149
|
+
var nodeView = nodeViewSerializer.tryCreateNodeView(targetNode);
|
|
150
|
+
if (nodeView) {
|
|
151
|
+
var wrapper = createWrapperWithStrikethrough();
|
|
152
|
+
wrapper.append(nodeView.dom);
|
|
153
|
+
dom.append(wrapper);
|
|
70
154
|
} else {
|
|
71
|
-
dom.append(
|
|
155
|
+
dom.append(fallbackSerialization());
|
|
72
156
|
}
|
|
73
157
|
});
|
|
74
158
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
@@ -21,7 +21,9 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
|
|
|
21
21
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } // eslint-disable-next-line @atlassian/tangerine/import/entry-points
|
|
22
22
|
var calculateDecorations = function calculateDecorations(_ref) {
|
|
23
23
|
var state = _ref.state,
|
|
24
|
-
pluginState = _ref.pluginState
|
|
24
|
+
pluginState = _ref.pluginState,
|
|
25
|
+
editorView = _ref.editorView,
|
|
26
|
+
nodeViews = _ref.nodeViews;
|
|
25
27
|
var originalDoc = pluginState.originalDoc,
|
|
26
28
|
steps = pluginState.steps;
|
|
27
29
|
if (!originalDoc || !pluginState.isDisplayingChanges) {
|
|
@@ -59,7 +61,9 @@ var calculateDecorations = function calculateDecorations(_ref) {
|
|
|
59
61
|
decorations.push((0, _decorations.createDeletedContentDecoration)({
|
|
60
62
|
change: change,
|
|
61
63
|
doc: originalDoc,
|
|
62
|
-
tr: tr
|
|
64
|
+
tr: tr,
|
|
65
|
+
editorView: editorView,
|
|
66
|
+
nodeViews: nodeViews
|
|
63
67
|
}));
|
|
64
68
|
}
|
|
65
69
|
});
|
|
@@ -70,16 +74,23 @@ var calculateDecorations = function calculateDecorations(_ref) {
|
|
|
70
74
|
};
|
|
71
75
|
var showDiffPluginKey = exports.showDiffPluginKey = new _state.PluginKey('showDiffPlugin');
|
|
72
76
|
var createPlugin = exports.createPlugin = function createPlugin(config) {
|
|
77
|
+
var editorView;
|
|
78
|
+
var setEditorView = function setEditorView(newEditorView) {
|
|
79
|
+
editorView = newEditorView;
|
|
80
|
+
};
|
|
73
81
|
return new _safePlugin.SafePlugin({
|
|
74
82
|
key: showDiffPluginKey,
|
|
75
83
|
state: {
|
|
76
84
|
init: function init(_, state) {
|
|
77
|
-
var _config$steps, _config$steps2;
|
|
85
|
+
var _config$steps, _config$steps2, _editorView;
|
|
78
86
|
var schema = state.schema;
|
|
79
87
|
var isDisplayingChanges = ((_config$steps = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps !== void 0 ? _config$steps : []).length > 0;
|
|
80
88
|
var steps = ((_config$steps2 = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps2 !== void 0 ? _config$steps2 : []).map(function (step) {
|
|
81
89
|
return _transform.Step.fromJSON(schema, step);
|
|
82
90
|
});
|
|
91
|
+
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
|
+
var nodeViews = ((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.nodeViews) || {};
|
|
83
94
|
return {
|
|
84
95
|
steps: steps,
|
|
85
96
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? (0, _processRawValue.processRawValue)(state.schema, config.originalDoc) : undefined,
|
|
@@ -89,24 +100,33 @@ var createPlugin = exports.createPlugin = function createPlugin(config) {
|
|
|
89
100
|
steps: steps,
|
|
90
101
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? (0, _processRawValue.processRawValue)(state.schema, config.originalDoc) : undefined,
|
|
91
102
|
isDisplayingChanges: isDisplayingChanges
|
|
92
|
-
}
|
|
103
|
+
},
|
|
104
|
+
editorView: editorView,
|
|
105
|
+
nodeViews: nodeViews
|
|
93
106
|
}),
|
|
94
107
|
isDisplayingChanges: isDisplayingChanges
|
|
95
108
|
};
|
|
96
109
|
},
|
|
97
110
|
apply: function apply(tr, currentPluginState, oldState, newState) {
|
|
111
|
+
var _editorView2;
|
|
98
112
|
var meta = tr.getMeta(showDiffPluginKey);
|
|
99
113
|
var newPluginState = currentPluginState;
|
|
114
|
+
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
116
|
+
var nodeViews = ((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.nodeViews) || {};
|
|
100
117
|
if (meta) {
|
|
101
118
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
119
|
+
var _meta$steps, _meta$originalDoc;
|
|
102
120
|
// Calculate and store decorations in state
|
|
103
121
|
var decorations = calculateDecorations({
|
|
104
122
|
state: newState,
|
|
105
123
|
pluginState: {
|
|
106
|
-
steps: meta.steps,
|
|
107
|
-
originalDoc: meta.originalDoc,
|
|
124
|
+
steps: (_meta$steps = meta.steps) !== null && _meta$steps !== void 0 ? _meta$steps : currentPluginState.steps,
|
|
125
|
+
originalDoc: (_meta$originalDoc = meta.originalDoc) !== null && _meta$originalDoc !== void 0 ? _meta$originalDoc : currentPluginState.originalDoc,
|
|
108
126
|
isDisplayingChanges: true
|
|
109
|
-
}
|
|
127
|
+
},
|
|
128
|
+
editorView: editorView,
|
|
129
|
+
nodeViews: nodeViews
|
|
110
130
|
});
|
|
111
131
|
newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
|
|
112
132
|
decorations: decorations,
|
|
@@ -126,6 +146,10 @@ var createPlugin = exports.createPlugin = function createPlugin(config) {
|
|
|
126
146
|
});
|
|
127
147
|
}
|
|
128
148
|
},
|
|
149
|
+
view: function view(editorView) {
|
|
150
|
+
setEditorView(editorView);
|
|
151
|
+
return {};
|
|
152
|
+
},
|
|
129
153
|
props: {
|
|
130
154
|
decorations: function decorations(state) {
|
|
131
155
|
var pluginState = showDiffPluginKey.getState(state);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Utilities for working with ProseMirror node views and DOM serialization within the
|
|
5
|
+
* Show Diff editor plugin.
|
|
6
|
+
*
|
|
7
|
+
* This module centralizes:
|
|
8
|
+
* - Access to the editor's `nodeViews` registry (when available on `EditorView`)
|
|
9
|
+
* - Safe attempts to instantiate a node view for a given node, with a blocklist to
|
|
10
|
+
* avoid node types that are known to be problematic in this context (e.g. tables)
|
|
11
|
+
* - Schema-driven serialization of nodes and fragments to DOM via `DOMSerializer`
|
|
12
|
+
*
|
|
13
|
+
* The Show Diff decorations leverage this to either render nodes using their
|
|
14
|
+
* corresponding node view implementation, or fall back to DOM serialization.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Narrowed `EditorView` that exposes the internal `nodeViews` registry.
|
|
19
|
+
* Many editor instances provide this, but it's not part of the base type.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Type guard to detect whether an `EditorView` exposes a `nodeViews` map.
|
|
24
|
+
*/
|
|
25
|
+
export function isEditorViewWithNodeViews(view) {
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
return view.nodeViews !== undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Encapsulates DOM serialization and node view access/creation.
|
|
32
|
+
*
|
|
33
|
+
* Responsible for:
|
|
34
|
+
* - Creating a `DOMSerializer` from the provided schema
|
|
35
|
+
* - Reading `nodeViews` from an `EditorView` (if present) or using an explicit mapping
|
|
36
|
+
* - Preventing node view creation for blocklisted node types
|
|
37
|
+
*/
|
|
38
|
+
export class NodeViewSerializer {
|
|
39
|
+
constructor(params) {
|
|
40
|
+
var _ref, _params$nodeViews, _this$editorView, _params$blocklist;
|
|
41
|
+
this.serializer = DOMSerializer.fromSchema(params.schema);
|
|
42
|
+
if (params.editorView && isEditorViewWithNodeViews(params.editorView)) {
|
|
43
|
+
this.editorView = params.editorView;
|
|
44
|
+
}
|
|
45
|
+
this.nodeViews = (_ref = (_params$nodeViews = params.nodeViews) !== null && _params$nodeViews !== void 0 ? _params$nodeViews : (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.nodeViews) !== null && _ref !== void 0 ? _ref : {};
|
|
46
|
+
this.nodeViewBlocklist = new Set((_params$blocklist = params.blocklist) !== null && _params$blocklist !== void 0 ? _params$blocklist : ['tableRow', 'table', 'paragraph']);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Attempts to create a node view for the given node.
|
|
51
|
+
*
|
|
52
|
+
* Returns `null` when there is no `EditorView`, no constructor for the node type,
|
|
53
|
+
* or the node type is blocklisted. Otherwise returns the constructed node view instance.
|
|
54
|
+
*/
|
|
55
|
+
tryCreateNodeView(targetNode) {
|
|
56
|
+
if (!this.editorView) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const constructor = this.nodeViews[targetNode.type.name];
|
|
60
|
+
if (!constructor) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (this.nodeViewBlocklist.has(targetNode.type.name)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return constructor(targetNode, this.editorView, () => 0, [], {});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Serializes a node to a DOM `Node` using the schema's `DOMSerializer`.
|
|
71
|
+
*/
|
|
72
|
+
serializeNode(node) {
|
|
73
|
+
return this.serializer.serializeNode(node);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Serializes a fragment to a `DocumentFragment` using the schema's `DOMSerializer`.
|
|
78
|
+
*/
|
|
79
|
+
serializeFragment(fragment) {
|
|
80
|
+
return this.serializer.serializeFragment(fragment);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
|
-
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
3
2
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
4
4
|
const style = convertToInlineCss({
|
|
5
5
|
background: "var(--ds-background-accent-purple-subtlest, #F3F0FF)",
|
|
6
6
|
textDecoration: 'underline',
|
|
@@ -8,7 +8,6 @@ const style = convertToInlineCss({
|
|
|
8
8
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
9
9
|
textDecorationColor: "var(--ds-border-accent-purple, #8270DB)"
|
|
10
10
|
});
|
|
11
|
-
|
|
12
11
|
/**
|
|
13
12
|
* Inline decoration used for insertions as the content already exists in the document
|
|
14
13
|
*
|
|
@@ -21,7 +20,18 @@ export const createInlineChangedDecoration = change => Decoration.inline(change.
|
|
|
21
20
|
}, {});
|
|
22
21
|
const deletedContentStyle = convertToInlineCss({
|
|
23
22
|
color: "var(--ds-text-accent-gray, #44546F)",
|
|
24
|
-
textDecoration: 'line-through'
|
|
23
|
+
textDecoration: 'line-through',
|
|
24
|
+
position: 'relative',
|
|
25
|
+
opacity: 0.6
|
|
26
|
+
});
|
|
27
|
+
const deletedContentStyleUnbounded = convertToInlineCss({
|
|
28
|
+
position: 'absolute',
|
|
29
|
+
top: '50%',
|
|
30
|
+
width: '100%',
|
|
31
|
+
display: 'inline-block',
|
|
32
|
+
borderTop: `1px solid ${"var(--ds-text-accent-gray, #44546F)"}`,
|
|
33
|
+
pointerEvents: 'none',
|
|
34
|
+
zIndex: 1
|
|
25
35
|
});
|
|
26
36
|
|
|
27
37
|
/**
|
|
@@ -35,7 +45,9 @@ const deletedContentStyle = convertToInlineCss({
|
|
|
35
45
|
export const createDeletedContentDecoration = ({
|
|
36
46
|
change,
|
|
37
47
|
doc,
|
|
38
|
-
tr
|
|
48
|
+
tr,
|
|
49
|
+
editorView,
|
|
50
|
+
nodeViews
|
|
39
51
|
}) => {
|
|
40
52
|
const dom = document.createElement('span');
|
|
41
53
|
dom.setAttribute('style', deletedContentStyle);
|
|
@@ -46,22 +58,90 @@ export const createDeletedContentDecoration = ({
|
|
|
46
58
|
* or sliced End depth is and match only the content and not with the entire node.
|
|
47
59
|
*/
|
|
48
60
|
const slice = doc.slice(change.fromA, change.toA);
|
|
61
|
+
const nodeViewSerializer = new NodeViewSerializer({
|
|
62
|
+
schema: tr.doc.type.schema,
|
|
63
|
+
editorView,
|
|
64
|
+
nodeViews
|
|
65
|
+
});
|
|
49
66
|
slice.content.forEach(node => {
|
|
50
|
-
|
|
67
|
+
// Create a wrapper for each node with strikethrough
|
|
68
|
+
const createWrapperWithStrikethrough = () => {
|
|
69
|
+
const wrapper = document.createElement('span');
|
|
70
|
+
wrapper.style.position = 'relative';
|
|
71
|
+
wrapper.style.width = 'fit-content';
|
|
72
|
+
const strikethrough = document.createElement('span');
|
|
73
|
+
strikethrough.setAttribute('style', deletedContentStyleUnbounded);
|
|
74
|
+
wrapper.append(strikethrough);
|
|
75
|
+
return wrapper;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Helper function to handle multiple child nodes
|
|
79
|
+
const handleMultipleChildNodes = node => {
|
|
80
|
+
if (node.content.childCount > 1 && node.type.inlineContent) {
|
|
81
|
+
node.content.forEach(childNode => {
|
|
82
|
+
const childNodeView = nodeViewSerializer.tryCreateNodeView(childNode);
|
|
83
|
+
if (childNodeView) {
|
|
84
|
+
const lineBreak = document.createElement('br');
|
|
85
|
+
targetNode = node;
|
|
86
|
+
dom.append(lineBreak);
|
|
87
|
+
const wrapper = createWrapperWithStrikethrough();
|
|
88
|
+
wrapper.append(childNodeView.dom);
|
|
89
|
+
dom.append(wrapper);
|
|
90
|
+
} else {
|
|
91
|
+
// Fallback to serializing the individual child node
|
|
92
|
+
const serializedChild = nodeViewSerializer.serializeNode(childNode);
|
|
93
|
+
dom.append(serializedChild);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return true; // Indicates we handled multiple children
|
|
97
|
+
}
|
|
98
|
+
return false; // Indicates single child, continue with normal logic
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Determine which node to use and how to serialize
|
|
51
102
|
const isFirst = slice.content.firstChild === node;
|
|
52
103
|
const isLast = slice.content.lastChild === node;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
104
|
+
const hasInlineContent = node.content.childCount > 0 && node.type.inlineContent === true;
|
|
105
|
+
let targetNode;
|
|
106
|
+
let fallbackSerialization;
|
|
107
|
+
if ((isFirst || isLast && slice.content.childCount > 2) && hasInlineContent) {
|
|
108
|
+
if (handleMultipleChildNodes(node)) {
|
|
109
|
+
return;
|
|
58
110
|
}
|
|
111
|
+
targetNode = node.content.content[0];
|
|
112
|
+
fallbackSerialization = () => nodeViewSerializer.serializeFragment(node.content);
|
|
59
113
|
} else if (isLast && slice.content.childCount === 2) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
114
|
+
if (handleMultipleChildNodes(node)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
targetNode = node;
|
|
118
|
+
fallbackSerialization = () => {
|
|
119
|
+
if (node.type.name === 'text') {
|
|
120
|
+
return document.createTextNode(node.text || '');
|
|
121
|
+
}
|
|
122
|
+
if (node.type.name === 'paragraph') {
|
|
123
|
+
const lineBreak = document.createElement('br');
|
|
124
|
+
dom.append(lineBreak);
|
|
125
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
126
|
+
}
|
|
127
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
128
|
+
};
|
|
129
|
+
} else {
|
|
130
|
+
if (handleMultipleChildNodes(node)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
targetNode = node.content.content[0] || node;
|
|
134
|
+
fallbackSerialization = () => nodeViewSerializer.serializeNode(node);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Try to create node view, fallback to serialization
|
|
138
|
+
const nodeView = nodeViewSerializer.tryCreateNodeView(targetNode);
|
|
139
|
+
if (nodeView) {
|
|
140
|
+
const wrapper = createWrapperWithStrikethrough();
|
|
141
|
+
wrapper.append(nodeView.dom);
|
|
142
|
+
dom.append(wrapper);
|
|
63
143
|
} else {
|
|
64
|
-
dom.append(
|
|
144
|
+
dom.append(fallbackSerialization());
|
|
65
145
|
}
|
|
66
146
|
});
|
|
67
147
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
@@ -9,7 +9,9 @@ import { createInlineChangedDecoration, createDeletedContentDecoration } from '.
|
|
|
9
9
|
import { getMarkChangeRanges } from './markDecorations';
|
|
10
10
|
const calculateDecorations = ({
|
|
11
11
|
state,
|
|
12
|
-
pluginState
|
|
12
|
+
pluginState,
|
|
13
|
+
editorView,
|
|
14
|
+
nodeViews
|
|
13
15
|
}) => {
|
|
14
16
|
const {
|
|
15
17
|
originalDoc,
|
|
@@ -43,7 +45,9 @@ const calculateDecorations = ({
|
|
|
43
45
|
decorations.push(createDeletedContentDecoration({
|
|
44
46
|
change,
|
|
45
47
|
doc: originalDoc,
|
|
46
|
-
tr
|
|
48
|
+
tr,
|
|
49
|
+
editorView,
|
|
50
|
+
nodeViews
|
|
47
51
|
}));
|
|
48
52
|
}
|
|
49
53
|
});
|
|
@@ -54,14 +58,21 @@ const calculateDecorations = ({
|
|
|
54
58
|
};
|
|
55
59
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
56
60
|
export const createPlugin = config => {
|
|
61
|
+
let editorView;
|
|
62
|
+
const setEditorView = newEditorView => {
|
|
63
|
+
editorView = newEditorView;
|
|
64
|
+
};
|
|
57
65
|
return new SafePlugin({
|
|
58
66
|
key: showDiffPluginKey,
|
|
59
67
|
state: {
|
|
60
68
|
init(_, state) {
|
|
61
|
-
var _config$steps, _config$steps2;
|
|
69
|
+
var _config$steps, _config$steps2, _editorView;
|
|
62
70
|
const schema = state.schema;
|
|
63
71
|
const isDisplayingChanges = ((_config$steps = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps !== void 0 ? _config$steps : []).length > 0;
|
|
64
72
|
const steps = ((_config$steps2 = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps2 !== void 0 ? _config$steps2 : []).map(step => ProseMirrorStep.fromJSON(schema, step));
|
|
73
|
+
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
+
const nodeViews = ((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.nodeViews) || {};
|
|
65
76
|
return {
|
|
66
77
|
steps,
|
|
67
78
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? processRawValue(state.schema, config.originalDoc) : undefined,
|
|
@@ -71,24 +82,33 @@ export const createPlugin = config => {
|
|
|
71
82
|
steps,
|
|
72
83
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? processRawValue(state.schema, config.originalDoc) : undefined,
|
|
73
84
|
isDisplayingChanges
|
|
74
|
-
}
|
|
85
|
+
},
|
|
86
|
+
editorView,
|
|
87
|
+
nodeViews
|
|
75
88
|
}),
|
|
76
89
|
isDisplayingChanges
|
|
77
90
|
};
|
|
78
91
|
},
|
|
79
92
|
apply: (tr, currentPluginState, oldState, newState) => {
|
|
93
|
+
var _editorView2;
|
|
80
94
|
const meta = tr.getMeta(showDiffPluginKey);
|
|
81
95
|
let newPluginState = currentPluginState;
|
|
96
|
+
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
const nodeViews = ((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.nodeViews) || {};
|
|
82
99
|
if (meta) {
|
|
83
100
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
101
|
+
var _meta$steps, _meta$originalDoc;
|
|
84
102
|
// Calculate and store decorations in state
|
|
85
103
|
const decorations = calculateDecorations({
|
|
86
104
|
state: newState,
|
|
87
105
|
pluginState: {
|
|
88
|
-
steps: meta.steps,
|
|
89
|
-
originalDoc: meta.originalDoc,
|
|
106
|
+
steps: (_meta$steps = meta.steps) !== null && _meta$steps !== void 0 ? _meta$steps : currentPluginState.steps,
|
|
107
|
+
originalDoc: (_meta$originalDoc = meta.originalDoc) !== null && _meta$originalDoc !== void 0 ? _meta$originalDoc : currentPluginState.originalDoc,
|
|
90
108
|
isDisplayingChanges: true
|
|
91
|
-
}
|
|
109
|
+
},
|
|
110
|
+
editorView,
|
|
111
|
+
nodeViews: nodeViews
|
|
92
112
|
});
|
|
93
113
|
newPluginState = {
|
|
94
114
|
...currentPluginState,
|
|
@@ -116,6 +136,10 @@ export const createPlugin = config => {
|
|
|
116
136
|
};
|
|
117
137
|
}
|
|
118
138
|
},
|
|
139
|
+
view(editorView) {
|
|
140
|
+
setEditorView(editorView);
|
|
141
|
+
return {};
|
|
142
|
+
},
|
|
119
143
|
props: {
|
|
120
144
|
decorations: state => {
|
|
121
145
|
const pluginState = showDiffPluginKey.getState(state);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Utilities for working with ProseMirror node views and DOM serialization within the
|
|
7
|
+
* Show Diff editor plugin.
|
|
8
|
+
*
|
|
9
|
+
* This module centralizes:
|
|
10
|
+
* - Access to the editor's `nodeViews` registry (when available on `EditorView`)
|
|
11
|
+
* - Safe attempts to instantiate a node view for a given node, with a blocklist to
|
|
12
|
+
* avoid node types that are known to be problematic in this context (e.g. tables)
|
|
13
|
+
* - Schema-driven serialization of nodes and fragments to DOM via `DOMSerializer`
|
|
14
|
+
*
|
|
15
|
+
* The Show Diff decorations leverage this to either render nodes using their
|
|
16
|
+
* corresponding node view implementation, or fall back to DOM serialization.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Narrowed `EditorView` that exposes the internal `nodeViews` registry.
|
|
21
|
+
* Many editor instances provide this, but it's not part of the base type.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type guard to detect whether an `EditorView` exposes a `nodeViews` map.
|
|
26
|
+
*/
|
|
27
|
+
export function isEditorViewWithNodeViews(view) {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
return view.nodeViews !== undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Encapsulates DOM serialization and node view access/creation.
|
|
34
|
+
*
|
|
35
|
+
* Responsible for:
|
|
36
|
+
* - Creating a `DOMSerializer` from the provided schema
|
|
37
|
+
* - Reading `nodeViews` from an `EditorView` (if present) or using an explicit mapping
|
|
38
|
+
* - Preventing node view creation for blocklisted node types
|
|
39
|
+
*/
|
|
40
|
+
export var NodeViewSerializer = /*#__PURE__*/function () {
|
|
41
|
+
function NodeViewSerializer(params) {
|
|
42
|
+
var _ref, _params$nodeViews, _this$editorView, _params$blocklist;
|
|
43
|
+
_classCallCheck(this, NodeViewSerializer);
|
|
44
|
+
this.serializer = DOMSerializer.fromSchema(params.schema);
|
|
45
|
+
if (params.editorView && isEditorViewWithNodeViews(params.editorView)) {
|
|
46
|
+
this.editorView = params.editorView;
|
|
47
|
+
}
|
|
48
|
+
this.nodeViews = (_ref = (_params$nodeViews = params.nodeViews) !== null && _params$nodeViews !== void 0 ? _params$nodeViews : (_this$editorView = this.editorView) === null || _this$editorView === void 0 ? void 0 : _this$editorView.nodeViews) !== null && _ref !== void 0 ? _ref : {};
|
|
49
|
+
this.nodeViewBlocklist = new Set((_params$blocklist = params.blocklist) !== null && _params$blocklist !== void 0 ? _params$blocklist : ['tableRow', 'table', 'paragraph']);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Attempts to create a node view for the given node.
|
|
54
|
+
*
|
|
55
|
+
* Returns `null` when there is no `EditorView`, no constructor for the node type,
|
|
56
|
+
* or the node type is blocklisted. Otherwise returns the constructed node view instance.
|
|
57
|
+
*/
|
|
58
|
+
return _createClass(NodeViewSerializer, [{
|
|
59
|
+
key: "tryCreateNodeView",
|
|
60
|
+
value: function tryCreateNodeView(targetNode) {
|
|
61
|
+
if (!this.editorView) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
var constructor = this.nodeViews[targetNode.type.name];
|
|
65
|
+
if (!constructor) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
if (this.nodeViewBlocklist.has(targetNode.type.name)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return constructor(targetNode, this.editorView, function () {
|
|
72
|
+
return 0;
|
|
73
|
+
}, [], {});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Serializes a node to a DOM `Node` using the schema's `DOMSerializer`.
|
|
78
|
+
*/
|
|
79
|
+
}, {
|
|
80
|
+
key: "serializeNode",
|
|
81
|
+
value: function serializeNode(node) {
|
|
82
|
+
return this.serializer.serializeNode(node);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Serializes a fragment to a `DocumentFragment` using the schema's `DOMSerializer`.
|
|
87
|
+
*/
|
|
88
|
+
}, {
|
|
89
|
+
key: "serializeFragment",
|
|
90
|
+
value: function serializeFragment(fragment) {
|
|
91
|
+
return this.serializer.serializeFragment(fragment);
|
|
92
|
+
}
|
|
93
|
+
}]);
|
|
94
|
+
}();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
|
-
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
3
2
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
4
4
|
var style = convertToInlineCss({
|
|
5
5
|
background: "var(--ds-background-accent-purple-subtlest, #F3F0FF)",
|
|
6
6
|
textDecoration: 'underline',
|
|
@@ -8,7 +8,6 @@ var style = convertToInlineCss({
|
|
|
8
8
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
9
9
|
textDecorationColor: "var(--ds-border-accent-purple, #8270DB)"
|
|
10
10
|
});
|
|
11
|
-
|
|
12
11
|
/**
|
|
13
12
|
* Inline decoration used for insertions as the content already exists in the document
|
|
14
13
|
*
|
|
@@ -23,7 +22,18 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
23
22
|
};
|
|
24
23
|
var deletedContentStyle = convertToInlineCss({
|
|
25
24
|
color: "var(--ds-text-accent-gray, #44546F)",
|
|
26
|
-
textDecoration: 'line-through'
|
|
25
|
+
textDecoration: 'line-through',
|
|
26
|
+
position: 'relative',
|
|
27
|
+
opacity: 0.6
|
|
28
|
+
});
|
|
29
|
+
var deletedContentStyleUnbounded = convertToInlineCss({
|
|
30
|
+
position: 'absolute',
|
|
31
|
+
top: '50%',
|
|
32
|
+
width: '100%',
|
|
33
|
+
display: 'inline-block',
|
|
34
|
+
borderTop: "1px solid ".concat("var(--ds-text-accent-gray, #44546F)"),
|
|
35
|
+
pointerEvents: 'none',
|
|
36
|
+
zIndex: 1
|
|
27
37
|
});
|
|
28
38
|
|
|
29
39
|
/**
|
|
@@ -37,7 +47,9 @@ var deletedContentStyle = convertToInlineCss({
|
|
|
37
47
|
export var createDeletedContentDecoration = function createDeletedContentDecoration(_ref) {
|
|
38
48
|
var change = _ref.change,
|
|
39
49
|
doc = _ref.doc,
|
|
40
|
-
tr = _ref.tr
|
|
50
|
+
tr = _ref.tr,
|
|
51
|
+
editorView = _ref.editorView,
|
|
52
|
+
nodeViews = _ref.nodeViews;
|
|
41
53
|
var dom = document.createElement('span');
|
|
42
54
|
dom.setAttribute('style', deletedContentStyle);
|
|
43
55
|
|
|
@@ -47,22 +59,94 @@ export var createDeletedContentDecoration = function createDeletedContentDecorat
|
|
|
47
59
|
* or sliced End depth is and match only the content and not with the entire node.
|
|
48
60
|
*/
|
|
49
61
|
var slice = doc.slice(change.fromA, change.toA);
|
|
62
|
+
var nodeViewSerializer = new NodeViewSerializer({
|
|
63
|
+
schema: tr.doc.type.schema,
|
|
64
|
+
editorView: editorView,
|
|
65
|
+
nodeViews: nodeViews
|
|
66
|
+
});
|
|
50
67
|
slice.content.forEach(function (node) {
|
|
51
|
-
|
|
68
|
+
// Create a wrapper for each node with strikethrough
|
|
69
|
+
var createWrapperWithStrikethrough = function createWrapperWithStrikethrough() {
|
|
70
|
+
var wrapper = document.createElement('span');
|
|
71
|
+
wrapper.style.position = 'relative';
|
|
72
|
+
wrapper.style.width = 'fit-content';
|
|
73
|
+
var strikethrough = document.createElement('span');
|
|
74
|
+
strikethrough.setAttribute('style', deletedContentStyleUnbounded);
|
|
75
|
+
wrapper.append(strikethrough);
|
|
76
|
+
return wrapper;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Helper function to handle multiple child nodes
|
|
80
|
+
var handleMultipleChildNodes = function handleMultipleChildNodes(node) {
|
|
81
|
+
if (node.content.childCount > 1 && node.type.inlineContent) {
|
|
82
|
+
node.content.forEach(function (childNode) {
|
|
83
|
+
var childNodeView = nodeViewSerializer.tryCreateNodeView(childNode);
|
|
84
|
+
if (childNodeView) {
|
|
85
|
+
var lineBreak = document.createElement('br');
|
|
86
|
+
targetNode = node;
|
|
87
|
+
dom.append(lineBreak);
|
|
88
|
+
var wrapper = createWrapperWithStrikethrough();
|
|
89
|
+
wrapper.append(childNodeView.dom);
|
|
90
|
+
dom.append(wrapper);
|
|
91
|
+
} else {
|
|
92
|
+
// Fallback to serializing the individual child node
|
|
93
|
+
var serializedChild = nodeViewSerializer.serializeNode(childNode);
|
|
94
|
+
dom.append(serializedChild);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return true; // Indicates we handled multiple children
|
|
98
|
+
}
|
|
99
|
+
return false; // Indicates single child, continue with normal logic
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Determine which node to use and how to serialize
|
|
52
103
|
var isFirst = slice.content.firstChild === node;
|
|
53
104
|
var isLast = slice.content.lastChild === node;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
105
|
+
var hasInlineContent = node.content.childCount > 0 && node.type.inlineContent === true;
|
|
106
|
+
var targetNode;
|
|
107
|
+
var fallbackSerialization;
|
|
108
|
+
if ((isFirst || isLast && slice.content.childCount > 2) && hasInlineContent) {
|
|
109
|
+
if (handleMultipleChildNodes(node)) {
|
|
110
|
+
return;
|
|
59
111
|
}
|
|
112
|
+
targetNode = node.content.content[0];
|
|
113
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
114
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
115
|
+
};
|
|
60
116
|
} else if (isLast && slice.content.childCount === 2) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
117
|
+
if (handleMultipleChildNodes(node)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
targetNode = node;
|
|
121
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
122
|
+
if (node.type.name === 'text') {
|
|
123
|
+
return document.createTextNode(node.text || '');
|
|
124
|
+
}
|
|
125
|
+
if (node.type.name === 'paragraph') {
|
|
126
|
+
var lineBreak = document.createElement('br');
|
|
127
|
+
dom.append(lineBreak);
|
|
128
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
129
|
+
}
|
|
130
|
+
return nodeViewSerializer.serializeFragment(node.content);
|
|
131
|
+
};
|
|
132
|
+
} else {
|
|
133
|
+
if (handleMultipleChildNodes(node)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
targetNode = node.content.content[0] || node;
|
|
137
|
+
fallbackSerialization = function fallbackSerialization() {
|
|
138
|
+
return nodeViewSerializer.serializeNode(node);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Try to create node view, fallback to serialization
|
|
143
|
+
var nodeView = nodeViewSerializer.tryCreateNodeView(targetNode);
|
|
144
|
+
if (nodeView) {
|
|
145
|
+
var wrapper = createWrapperWithStrikethrough();
|
|
146
|
+
wrapper.append(nodeView.dom);
|
|
147
|
+
dom.append(wrapper);
|
|
64
148
|
} else {
|
|
65
|
-
dom.append(
|
|
149
|
+
dom.append(fallbackSerialization());
|
|
66
150
|
}
|
|
67
151
|
});
|
|
68
152
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
@@ -15,7 +15,9 @@ import { createInlineChangedDecoration, createDeletedContentDecoration } from '.
|
|
|
15
15
|
import { getMarkChangeRanges } from './markDecorations';
|
|
16
16
|
var calculateDecorations = function calculateDecorations(_ref) {
|
|
17
17
|
var state = _ref.state,
|
|
18
|
-
pluginState = _ref.pluginState
|
|
18
|
+
pluginState = _ref.pluginState,
|
|
19
|
+
editorView = _ref.editorView,
|
|
20
|
+
nodeViews = _ref.nodeViews;
|
|
19
21
|
var originalDoc = pluginState.originalDoc,
|
|
20
22
|
steps = pluginState.steps;
|
|
21
23
|
if (!originalDoc || !pluginState.isDisplayingChanges) {
|
|
@@ -53,7 +55,9 @@ var calculateDecorations = function calculateDecorations(_ref) {
|
|
|
53
55
|
decorations.push(createDeletedContentDecoration({
|
|
54
56
|
change: change,
|
|
55
57
|
doc: originalDoc,
|
|
56
|
-
tr: tr
|
|
58
|
+
tr: tr,
|
|
59
|
+
editorView: editorView,
|
|
60
|
+
nodeViews: nodeViews
|
|
57
61
|
}));
|
|
58
62
|
}
|
|
59
63
|
});
|
|
@@ -64,16 +68,23 @@ var calculateDecorations = function calculateDecorations(_ref) {
|
|
|
64
68
|
};
|
|
65
69
|
export var showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
66
70
|
export var createPlugin = function createPlugin(config) {
|
|
71
|
+
var editorView;
|
|
72
|
+
var setEditorView = function setEditorView(newEditorView) {
|
|
73
|
+
editorView = newEditorView;
|
|
74
|
+
};
|
|
67
75
|
return new SafePlugin({
|
|
68
76
|
key: showDiffPluginKey,
|
|
69
77
|
state: {
|
|
70
78
|
init: function init(_, state) {
|
|
71
|
-
var _config$steps, _config$steps2;
|
|
79
|
+
var _config$steps, _config$steps2, _editorView;
|
|
72
80
|
var schema = state.schema;
|
|
73
81
|
var isDisplayingChanges = ((_config$steps = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps !== void 0 ? _config$steps : []).length > 0;
|
|
74
82
|
var steps = ((_config$steps2 = config === null || config === void 0 ? void 0 : config.steps) !== null && _config$steps2 !== void 0 ? _config$steps2 : []).map(function (step) {
|
|
75
83
|
return ProseMirrorStep.fromJSON(schema, step);
|
|
76
84
|
});
|
|
85
|
+
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
87
|
+
var nodeViews = ((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.nodeViews) || {};
|
|
77
88
|
return {
|
|
78
89
|
steps: steps,
|
|
79
90
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? processRawValue(state.schema, config.originalDoc) : undefined,
|
|
@@ -83,24 +94,33 @@ export var createPlugin = function createPlugin(config) {
|
|
|
83
94
|
steps: steps,
|
|
84
95
|
originalDoc: config !== null && config !== void 0 && config.originalDoc ? processRawValue(state.schema, config.originalDoc) : undefined,
|
|
85
96
|
isDisplayingChanges: isDisplayingChanges
|
|
86
|
-
}
|
|
97
|
+
},
|
|
98
|
+
editorView: editorView,
|
|
99
|
+
nodeViews: nodeViews
|
|
87
100
|
}),
|
|
88
101
|
isDisplayingChanges: isDisplayingChanges
|
|
89
102
|
};
|
|
90
103
|
},
|
|
91
104
|
apply: function apply(tr, currentPluginState, oldState, newState) {
|
|
105
|
+
var _editorView2;
|
|
92
106
|
var meta = tr.getMeta(showDiffPluginKey);
|
|
93
107
|
var newPluginState = currentPluginState;
|
|
108
|
+
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
var nodeViews = ((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.nodeViews) || {};
|
|
94
111
|
if (meta) {
|
|
95
112
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
113
|
+
var _meta$steps, _meta$originalDoc;
|
|
96
114
|
// Calculate and store decorations in state
|
|
97
115
|
var decorations = calculateDecorations({
|
|
98
116
|
state: newState,
|
|
99
117
|
pluginState: {
|
|
100
|
-
steps: meta.steps,
|
|
101
|
-
originalDoc: meta.originalDoc,
|
|
118
|
+
steps: (_meta$steps = meta.steps) !== null && _meta$steps !== void 0 ? _meta$steps : currentPluginState.steps,
|
|
119
|
+
originalDoc: (_meta$originalDoc = meta.originalDoc) !== null && _meta$originalDoc !== void 0 ? _meta$originalDoc : currentPluginState.originalDoc,
|
|
102
120
|
isDisplayingChanges: true
|
|
103
|
-
}
|
|
121
|
+
},
|
|
122
|
+
editorView: editorView,
|
|
123
|
+
nodeViews: nodeViews
|
|
104
124
|
});
|
|
105
125
|
newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
|
|
106
126
|
decorations: decorations,
|
|
@@ -120,6 +140,10 @@ export var createPlugin = function createPlugin(config) {
|
|
|
120
140
|
});
|
|
121
141
|
}
|
|
122
142
|
},
|
|
143
|
+
view: function view(editorView) {
|
|
144
|
+
setEditorView(editorView);
|
|
145
|
+
return {};
|
|
146
|
+
},
|
|
123
147
|
props: {
|
|
124
148
|
decorations: function decorations(state) {
|
|
125
149
|
var pluginState = showDiffPluginKey.getState(state);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
|
+
import type { Schema, Node as PMNode, Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
+
/**
|
|
5
|
+
* Utilities for working with ProseMirror node views and DOM serialization within the
|
|
6
|
+
* Show Diff editor plugin.
|
|
7
|
+
*
|
|
8
|
+
* This module centralizes:
|
|
9
|
+
* - Access to the editor's `nodeViews` registry (when available on `EditorView`)
|
|
10
|
+
* - Safe attempts to instantiate a node view for a given node, with a blocklist to
|
|
11
|
+
* avoid node types that are known to be problematic in this context (e.g. tables)
|
|
12
|
+
* - Schema-driven serialization of nodes and fragments to DOM via `DOMSerializer`
|
|
13
|
+
*
|
|
14
|
+
* The Show Diff decorations leverage this to either render nodes using their
|
|
15
|
+
* corresponding node view implementation, or fall back to DOM serialization.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Narrowed `EditorView` that exposes the internal `nodeViews` registry.
|
|
19
|
+
* Many editor instances provide this, but it's not part of the base type.
|
|
20
|
+
*/
|
|
21
|
+
export interface EditorViewWithNodeViews extends EditorView {
|
|
22
|
+
nodeViews: Record<string, NodeViewConstructor>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Type guard to detect whether an `EditorView` exposes a `nodeViews` map.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isEditorViewWithNodeViews(view: EditorView): view is EditorViewWithNodeViews;
|
|
28
|
+
/**
|
|
29
|
+
* Encapsulates DOM serialization and node view access/creation.
|
|
30
|
+
*
|
|
31
|
+
* Responsible for:
|
|
32
|
+
* - Creating a `DOMSerializer` from the provided schema
|
|
33
|
+
* - Reading `nodeViews` from an `EditorView` (if present) or using an explicit mapping
|
|
34
|
+
* - Preventing node view creation for blocklisted node types
|
|
35
|
+
*/
|
|
36
|
+
export declare class NodeViewSerializer {
|
|
37
|
+
private serializer;
|
|
38
|
+
private editorView?;
|
|
39
|
+
private nodeViews;
|
|
40
|
+
private nodeViewBlocklist;
|
|
41
|
+
constructor(params: {
|
|
42
|
+
schema: Schema;
|
|
43
|
+
editorView?: EditorView;
|
|
44
|
+
nodeViews?: Record<string, NodeViewConstructor>;
|
|
45
|
+
blocklist?: string[];
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Attempts to create a node view for the given node.
|
|
49
|
+
*
|
|
50
|
+
* Returns `null` when there is no `EditorView`, no constructor for the node type,
|
|
51
|
+
* or the node type is blocklisted. Otherwise returns the constructed node view instance.
|
|
52
|
+
*/
|
|
53
|
+
tryCreateNodeView(targetNode: PMNode): import("prosemirror-view").NodeView | null;
|
|
54
|
+
/**
|
|
55
|
+
* Serializes a node to a DOM `Node` using the schema's `DOMSerializer`.
|
|
56
|
+
*/
|
|
57
|
+
serializeNode(node: PMNode): Node;
|
|
58
|
+
/**
|
|
59
|
+
* Serializes a fragment to a `DocumentFragment` using the schema's `DOMSerializer`.
|
|
60
|
+
*/
|
|
61
|
+
serializeFragment(fragment: Fragment): DocumentFragment | HTMLElement;
|
|
62
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Change } from 'prosemirror-changeset';
|
|
2
|
+
import { type NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
3
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
7
|
/**
|
|
6
8
|
* Inline decoration used for insertions as the content already exists in the document
|
|
@@ -16,6 +18,8 @@ interface DeletedContentDecorationProps {
|
|
|
16
18
|
change: Change;
|
|
17
19
|
doc: PMNode;
|
|
18
20
|
tr: Transaction;
|
|
21
|
+
nodeViews: Record<string, NodeViewConstructor>;
|
|
22
|
+
editorView?: EditorView;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Creates a widget to represent the deleted content in the editor
|
|
@@ -25,5 +29,5 @@ interface DeletedContentDecorationProps {
|
|
|
25
29
|
* @param props.tr The relevant transaction this decoration is being created against
|
|
26
30
|
* @returns Prosemirror widget decoration
|
|
27
31
|
*/
|
|
28
|
-
export declare const createDeletedContentDecoration: ({ change, doc, tr, }: DeletedContentDecorationProps) => Decoration;
|
|
32
|
+
export declare const createDeletedContentDecoration: ({ change, doc, tr, editorView, nodeViews, }: DeletedContentDecorationProps) => Decoration;
|
|
29
33
|
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
|
+
import type { Schema, Node as PMNode, Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
|
+
/**
|
|
5
|
+
* Utilities for working with ProseMirror node views and DOM serialization within the
|
|
6
|
+
* Show Diff editor plugin.
|
|
7
|
+
*
|
|
8
|
+
* This module centralizes:
|
|
9
|
+
* - Access to the editor's `nodeViews` registry (when available on `EditorView`)
|
|
10
|
+
* - Safe attempts to instantiate a node view for a given node, with a blocklist to
|
|
11
|
+
* avoid node types that are known to be problematic in this context (e.g. tables)
|
|
12
|
+
* - Schema-driven serialization of nodes and fragments to DOM via `DOMSerializer`
|
|
13
|
+
*
|
|
14
|
+
* The Show Diff decorations leverage this to either render nodes using their
|
|
15
|
+
* corresponding node view implementation, or fall back to DOM serialization.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Narrowed `EditorView` that exposes the internal `nodeViews` registry.
|
|
19
|
+
* Many editor instances provide this, but it's not part of the base type.
|
|
20
|
+
*/
|
|
21
|
+
export interface EditorViewWithNodeViews extends EditorView {
|
|
22
|
+
nodeViews: Record<string, NodeViewConstructor>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Type guard to detect whether an `EditorView` exposes a `nodeViews` map.
|
|
26
|
+
*/
|
|
27
|
+
export declare function isEditorViewWithNodeViews(view: EditorView): view is EditorViewWithNodeViews;
|
|
28
|
+
/**
|
|
29
|
+
* Encapsulates DOM serialization and node view access/creation.
|
|
30
|
+
*
|
|
31
|
+
* Responsible for:
|
|
32
|
+
* - Creating a `DOMSerializer` from the provided schema
|
|
33
|
+
* - Reading `nodeViews` from an `EditorView` (if present) or using an explicit mapping
|
|
34
|
+
* - Preventing node view creation for blocklisted node types
|
|
35
|
+
*/
|
|
36
|
+
export declare class NodeViewSerializer {
|
|
37
|
+
private serializer;
|
|
38
|
+
private editorView?;
|
|
39
|
+
private nodeViews;
|
|
40
|
+
private nodeViewBlocklist;
|
|
41
|
+
constructor(params: {
|
|
42
|
+
schema: Schema;
|
|
43
|
+
editorView?: EditorView;
|
|
44
|
+
nodeViews?: Record<string, NodeViewConstructor>;
|
|
45
|
+
blocklist?: string[];
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Attempts to create a node view for the given node.
|
|
49
|
+
*
|
|
50
|
+
* Returns `null` when there is no `EditorView`, no constructor for the node type,
|
|
51
|
+
* or the node type is blocklisted. Otherwise returns the constructed node view instance.
|
|
52
|
+
*/
|
|
53
|
+
tryCreateNodeView(targetNode: PMNode): import("prosemirror-view").NodeView | null;
|
|
54
|
+
/**
|
|
55
|
+
* Serializes a node to a DOM `Node` using the schema's `DOMSerializer`.
|
|
56
|
+
*/
|
|
57
|
+
serializeNode(node: PMNode): Node;
|
|
58
|
+
/**
|
|
59
|
+
* Serializes a fragment to a `DocumentFragment` using the schema's `DOMSerializer`.
|
|
60
|
+
*/
|
|
61
|
+
serializeFragment(fragment: Fragment): DocumentFragment | HTMLElement;
|
|
62
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Change } from 'prosemirror-changeset';
|
|
2
|
+
import { type NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
3
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
4
|
import type { Transaction } from '@atlaskit/editor-prosemirror/state';
|
|
5
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
4
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
7
|
/**
|
|
6
8
|
* Inline decoration used for insertions as the content already exists in the document
|
|
@@ -16,6 +18,8 @@ interface DeletedContentDecorationProps {
|
|
|
16
18
|
change: Change;
|
|
17
19
|
doc: PMNode;
|
|
18
20
|
tr: Transaction;
|
|
21
|
+
nodeViews: Record<string, NodeViewConstructor>;
|
|
22
|
+
editorView?: EditorView;
|
|
19
23
|
}
|
|
20
24
|
/**
|
|
21
25
|
* Creates a widget to represent the deleted content in the editor
|
|
@@ -25,5 +29,5 @@ interface DeletedContentDecorationProps {
|
|
|
25
29
|
* @param props.tr The relevant transaction this decoration is being created against
|
|
26
30
|
* @returns Prosemirror widget decoration
|
|
27
31
|
*/
|
|
28
|
-
export declare const createDeletedContentDecoration: ({ change, doc, tr, }: DeletedContentDecorationProps) => Decoration;
|
|
32
|
+
export declare const createDeletedContentDecoration: ({ change, doc, tr, editorView, nodeViews, }: DeletedContentDecorationProps) => Decoration;
|
|
29
33
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"prosemirror-changeset": "^2.2.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@atlaskit/editor-common": "^107.
|
|
40
|
+
"@atlaskit/editor-common": "^107.26.0",
|
|
41
41
|
"react": "^18.2.0"
|
|
42
42
|
},
|
|
43
43
|
"techstack": {
|