@samemichaeltadele/tiptap-compare 0.0.1

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/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # TiptapCompare
2
+
3
+ A Tiptap extension that provides real-time visual comparison between two versions of content in your editor. This plugin helps you track changes by highlighting additions, modifications, and deletions with different colors and styles.
4
+
5
+ ## Features
6
+
7
+ - Visual diff highlighting for tiptap editor changes changes
8
+ - Support for different types of blocks (text, paragraphs, images)
9
+ - Color-coded changes:
10
+ - Green background for added content
11
+ - Red background with strikethrough for removed content
12
+ - Yellow background for modified content
13
+ - Real-time comparison updates
14
+ - Support for nested content structures
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @samemichaeltadele/tiptap-compare
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```typescript
25
+ import { ComparePlugin } from 'tiptap-compare'
26
+ import { Editor } from '@tiptap/core'
27
+
28
+ const editor = new Editor({
29
+ extensions: [
30
+ // ... other extensions
31
+ ComparePlugin.configure({
32
+ comparisonContent: ""
33
+ })
34
+ ]
35
+ })
36
+
37
+ // Update comparison content
38
+ editor.commands.setComparisonContent(newContent)
39
+ ```
40
+ New content should be json format like you would get in by using the getJSON() comand on an editor
41
+
42
+ ## Configuration
43
+
44
+ The plugin accepts the following options:
45
+
46
+ - `comparisonContent`: The content to compare against (default: empty string), should be the content with which it should be compared in json format.
47
+
48
+
49
+ ## Styling
50
+
51
+ The plugin uses the following CSS classes for styling:
52
+
53
+ - `diff-added`: Applied to added content (green background)
54
+ - `diff-removed`: Applied to removed content (red background with strikethrough)
55
+ - `diff-modified`: Applied to modified content (yellow background)
56
+
57
+ ## License
58
+
59
+ MIT
60
+
61
+ ## Author
62
+
63
+ SameC137 <samemichael1415@gmail.com>
@@ -0,0 +1,156 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('@tiptap/core');
6
+ var prosemirrorState = require('prosemirror-state');
7
+ var prosemirrorView = require('prosemirror-view');
8
+ var diff = require('diff');
9
+
10
+ const pluginKey = new prosemirrorState.PluginKey("comparePlugin");
11
+ const ComparePlugin = core.Extension.create({
12
+ name: "compare",
13
+ addOptions() {
14
+ return {
15
+ comparisonContent: ""
16
+ };
17
+ },
18
+ addCommands() {
19
+ return {
20
+ setComparisonContent: (content) => ({ state, dispatch }) => {
21
+ const tr = state.tr.setMeta(pluginKey, {
22
+ comparisonContent: content,
23
+ });
24
+ if (dispatch)
25
+ dispatch(tr);
26
+ return true;
27
+ },
28
+ };
29
+ },
30
+ addProseMirrorPlugins() {
31
+ return [
32
+ new prosemirrorState.Plugin({
33
+ key: pluginKey,
34
+ state: {
35
+ init: (_, { doc }) => {
36
+ return {
37
+ comparisonContent: this.options.comparisonContent,
38
+ options: this.options,
39
+ };
40
+ },
41
+ apply(tr, pluginState, _, newState) {
42
+ const meta = tr.getMeta(pluginKey);
43
+ if (meta && meta.comparisonContent !== undefined) {
44
+ return Object.assign(Object.assign({}, pluginState), { comparisonContent: meta.comparisonContent });
45
+ }
46
+ return pluginState;
47
+ },
48
+ },
49
+ props: {
50
+ decorations(state) {
51
+ var _a, _b, _c;
52
+ const pluginState = pluginKey.getState(state);
53
+ if (!pluginState)
54
+ return null;
55
+ const { comparisonContent } = pluginState;
56
+ if (!comparisonContent)
57
+ return null;
58
+ if (!comparisonContent.content)
59
+ return null;
60
+ if (!comparisonContent.content[0].content)
61
+ return null;
62
+ const decos = [];
63
+ const oldContent = comparisonContent;
64
+ const newContent = state.doc.toJSON();
65
+ const oldNodes = oldContent.content;
66
+ const newNodes = newContent.content;
67
+ let pos = 0;
68
+ for (let i = 0; i < Math.max(oldNodes === null || oldNodes === void 0 ? void 0 : oldNodes.length, newNodes === null || newNodes === void 0 ? void 0 : newNodes.length); i++) {
69
+ const oldNode = oldNodes[i];
70
+ const newNode = newNodes[i];
71
+ if (!oldNode) {
72
+ // Node added
73
+ const nodeSize = ((_a = state.doc.nodeAt(pos)) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0;
74
+ decos.push(prosemirrorView.Decoration.node(pos, pos + nodeSize, {
75
+ class: "diff-added bg-[#e6ffec] text-green-500",
76
+ }));
77
+ pos += nodeSize;
78
+ }
79
+ else if (!newNode) {
80
+ // Node removed
81
+ decos.push(prosemirrorView.Decoration.widget(pos, createRemovedNode(oldNode)));
82
+ }
83
+ else if (oldNode.type !== newNode.type) {
84
+ // Node type changed
85
+ const nodeSize = ((_b = state.doc.nodeAt(pos)) === null || _b === void 0 ? void 0 : _b.nodeSize) || 0;
86
+ decos.push(prosemirrorView.Decoration.node(pos, pos + nodeSize, {
87
+ class: "diff-modified bg-[#ffefc6] text-red-500",
88
+ }));
89
+ pos += nodeSize;
90
+ }
91
+ else {
92
+ // Compare node content
93
+ const oldText = nodeToText(oldNode);
94
+ const newText = nodeToText(newNode);
95
+ const diff$1 = diff.diffChars(oldText, newText);
96
+ let nodePos = pos + 1; // +1 to skip the node start tag
97
+ diff$1.forEach((part) => {
98
+ const length = part.value.length;
99
+ if (part.added) {
100
+ decos.push(prosemirrorView.Decoration.inline(nodePos, nodePos + length, {
101
+ class: "diff-added bg-[#e6ffec] text-green-500",
102
+ }));
103
+ nodePos += length;
104
+ }
105
+ else if (part.removed) {
106
+ decos.push(prosemirrorView.Decoration.widget(nodePos, createRemovedSpan(part.value)));
107
+ }
108
+ else {
109
+ nodePos += length;
110
+ }
111
+ });
112
+ pos += ((_c = state.doc.nodeAt(pos)) === null || _c === void 0 ? void 0 : _c.nodeSize) || 0;
113
+ }
114
+ }
115
+ return prosemirrorView.DecorationSet.create(state.doc, decos);
116
+ },
117
+ },
118
+ }),
119
+ ];
120
+ },
121
+ });
122
+ function nodeToText(node) {
123
+ var _a;
124
+ if (node.type === "text") {
125
+ return node.text || "";
126
+ }
127
+ else if (node.type === "paragraph") {
128
+ if (!node.content)
129
+ return " \n";
130
+ return ((_a = node.content) === null || _a === void 0 ? void 0 : _a.map(nodeToText).join("")) + "\n";
131
+ }
132
+ else if (node.type === "image") {
133
+ return `[Image: ${node.attrs.alt || "No alt text"} (${node.attrs.src})]\n`;
134
+ }
135
+ else if (node.content) {
136
+ return node.content.map(nodeToText).join("");
137
+ }
138
+ return "";
139
+ }
140
+ function createRemovedSpan(text) {
141
+ const span = document.createElement("span");
142
+ span.className = "diff-removed bg-[#ffebe9] line-through text-red-500";
143
+ span.textContent = text;
144
+ return span;
145
+ }
146
+ function createRemovedNode(node) {
147
+ const div = document.createElement("div");
148
+ div.className =
149
+ "diff-removed-node bg-[#ffebe9] line-through px-0 py-0.5 text-red-500";
150
+ div.textContent = nodeToText(node);
151
+ return div;
152
+ }
153
+
154
+ exports.ComparePlugin = ComparePlugin;
155
+ exports.default = ComparePlugin;
156
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,14 @@
1
+ import { Extension } from "@tiptap/core";
2
+ interface ComparePluginOptions {
3
+ comparisonContent: any;
4
+ }
5
+ declare module "@tiptap/core" {
6
+ interface Commands<ReturnType> {
7
+ compare: {
8
+ setComparisonContent: (content: any) => ReturnType;
9
+ };
10
+ }
11
+ }
12
+ declare const ComparePlugin: Extension<ComparePluginOptions, any>;
13
+ export { ComparePlugin };
14
+ export default ComparePlugin;
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { PluginKey, Plugin } from 'prosemirror-state';
3
+ import { Decoration, DecorationSet } from 'prosemirror-view';
4
+ import { diffChars } from 'diff';
5
+
6
+ const pluginKey = new PluginKey("comparePlugin");
7
+ const ComparePlugin = Extension.create({
8
+ name: "compare",
9
+ addOptions() {
10
+ return {
11
+ comparisonContent: ""
12
+ };
13
+ },
14
+ addCommands() {
15
+ return {
16
+ setComparisonContent: (content) => ({ state, dispatch }) => {
17
+ const tr = state.tr.setMeta(pluginKey, {
18
+ comparisonContent: content,
19
+ });
20
+ if (dispatch)
21
+ dispatch(tr);
22
+ return true;
23
+ },
24
+ };
25
+ },
26
+ addProseMirrorPlugins() {
27
+ return [
28
+ new Plugin({
29
+ key: pluginKey,
30
+ state: {
31
+ init: (_, { doc }) => {
32
+ return {
33
+ comparisonContent: this.options.comparisonContent,
34
+ options: this.options,
35
+ };
36
+ },
37
+ apply(tr, pluginState, _, newState) {
38
+ const meta = tr.getMeta(pluginKey);
39
+ if (meta && meta.comparisonContent !== undefined) {
40
+ return Object.assign(Object.assign({}, pluginState), { comparisonContent: meta.comparisonContent });
41
+ }
42
+ return pluginState;
43
+ },
44
+ },
45
+ props: {
46
+ decorations(state) {
47
+ var _a, _b, _c;
48
+ const pluginState = pluginKey.getState(state);
49
+ if (!pluginState)
50
+ return null;
51
+ const { comparisonContent } = pluginState;
52
+ if (!comparisonContent)
53
+ return null;
54
+ if (!comparisonContent.content)
55
+ return null;
56
+ if (!comparisonContent.content[0].content)
57
+ return null;
58
+ const decos = [];
59
+ const oldContent = comparisonContent;
60
+ const newContent = state.doc.toJSON();
61
+ const oldNodes = oldContent.content;
62
+ const newNodes = newContent.content;
63
+ let pos = 0;
64
+ for (let i = 0; i < Math.max(oldNodes === null || oldNodes === void 0 ? void 0 : oldNodes.length, newNodes === null || newNodes === void 0 ? void 0 : newNodes.length); i++) {
65
+ const oldNode = oldNodes[i];
66
+ const newNode = newNodes[i];
67
+ if (!oldNode) {
68
+ // Node added
69
+ const nodeSize = ((_a = state.doc.nodeAt(pos)) === null || _a === void 0 ? void 0 : _a.nodeSize) || 0;
70
+ decos.push(Decoration.node(pos, pos + nodeSize, {
71
+ class: "diff-added bg-[#e6ffec] text-green-500",
72
+ }));
73
+ pos += nodeSize;
74
+ }
75
+ else if (!newNode) {
76
+ // Node removed
77
+ decos.push(Decoration.widget(pos, createRemovedNode(oldNode)));
78
+ }
79
+ else if (oldNode.type !== newNode.type) {
80
+ // Node type changed
81
+ const nodeSize = ((_b = state.doc.nodeAt(pos)) === null || _b === void 0 ? void 0 : _b.nodeSize) || 0;
82
+ decos.push(Decoration.node(pos, pos + nodeSize, {
83
+ class: "diff-modified bg-[#ffefc6] text-red-500",
84
+ }));
85
+ pos += nodeSize;
86
+ }
87
+ else {
88
+ // Compare node content
89
+ const oldText = nodeToText(oldNode);
90
+ const newText = nodeToText(newNode);
91
+ const diff = diffChars(oldText, newText);
92
+ let nodePos = pos + 1; // +1 to skip the node start tag
93
+ diff.forEach((part) => {
94
+ const length = part.value.length;
95
+ if (part.added) {
96
+ decos.push(Decoration.inline(nodePos, nodePos + length, {
97
+ class: "diff-added bg-[#e6ffec] text-green-500",
98
+ }));
99
+ nodePos += length;
100
+ }
101
+ else if (part.removed) {
102
+ decos.push(Decoration.widget(nodePos, createRemovedSpan(part.value)));
103
+ }
104
+ else {
105
+ nodePos += length;
106
+ }
107
+ });
108
+ pos += ((_c = state.doc.nodeAt(pos)) === null || _c === void 0 ? void 0 : _c.nodeSize) || 0;
109
+ }
110
+ }
111
+ return DecorationSet.create(state.doc, decos);
112
+ },
113
+ },
114
+ }),
115
+ ];
116
+ },
117
+ });
118
+ function nodeToText(node) {
119
+ var _a;
120
+ if (node.type === "text") {
121
+ return node.text || "";
122
+ }
123
+ else if (node.type === "paragraph") {
124
+ if (!node.content)
125
+ return " \n";
126
+ return ((_a = node.content) === null || _a === void 0 ? void 0 : _a.map(nodeToText).join("")) + "\n";
127
+ }
128
+ else if (node.type === "image") {
129
+ return `[Image: ${node.attrs.alt || "No alt text"} (${node.attrs.src})]\n`;
130
+ }
131
+ else if (node.content) {
132
+ return node.content.map(nodeToText).join("");
133
+ }
134
+ return "";
135
+ }
136
+ function createRemovedSpan(text) {
137
+ const span = document.createElement("span");
138
+ span.className = "diff-removed bg-[#ffebe9] line-through text-red-500";
139
+ span.textContent = text;
140
+ return span;
141
+ }
142
+ function createRemovedNode(node) {
143
+ const div = document.createElement("div");
144
+ div.className =
145
+ "diff-removed-node bg-[#ffebe9] line-through px-0 py-0.5 text-red-500";
146
+ div.textContent = nodeToText(node);
147
+ return div;
148
+ }
149
+
150
+ export { ComparePlugin, ComparePlugin as default };
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@samemichaeltadele/tiptap-compare",
3
+ "version": "0.0.1",
4
+ "description": "Tip Tap diff compare extension ",
5
+ "keywords": ["tiptap", "compare", "diff", "highlight", "highlighting", "diffing", "diff-highlighting", "diff-highlighting-tiptap", "tiptap-compare", "tiptap-diff", "tiptap-highlight", "tiptap-highlighting", "tiptap-diff-highlighting", "tiptap-diff-highlighting-tiptap"],
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/SameC137/tiptap-compare.git"
9
+ },
10
+ "author": "SameC137 <samemichael1415@gmail.com>",
11
+ "license": "MIT",
12
+ "main": "dist/index.cjs.js",
13
+ "module": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "scripts": {
16
+ "clean": "rm -r -Force dist",
17
+ "build": "rollup -c",
18
+ "dev": " rollup -c -w"
19
+ },
20
+ "devDependencies": {
21
+ "@rollup/plugin-babel": "^6.0.3",
22
+ "@rollup/plugin-commonjs": "^24.0.1",
23
+ "@tiptap/core": "^2.0.0-beta.220",
24
+ "@tiptap/pm": "^2.0.0-beta.220",
25
+ "rollup": "^3.17.3",
26
+ "rollup-plugin-auto-external": "^2.0.0",
27
+ "rollup-plugin-sourcemaps": "^0.6.3",
28
+ "rollup-plugin-typescript2": "^0.34.1",
29
+ "typescript": "^4.9.5"
30
+ },
31
+ "peerDependencies": {
32
+ "@tiptap/core": "^2.0.0-beta.220",
33
+ "@tiptap/pm": "^2.0.0-beta.220"
34
+ },
35
+ "dependencies": {
36
+ "diff": "^7.0.0"
37
+ }
38
+ }
@@ -0,0 +1,34 @@
1
+ // rollup.config.js
2
+
3
+ const autoExternal = require("rollup-plugin-auto-external");
4
+ const sourcemaps = require("rollup-plugin-sourcemaps");
5
+ const commonjs = require("@rollup/plugin-commonjs");
6
+ const babel = require("@rollup/plugin-babel");
7
+ const typescript = require("rollup-plugin-typescript2");
8
+
9
+ const config = {
10
+ input: "src/index.ts",
11
+ output: [
12
+ {
13
+ file: "dist/index.cjs.js",
14
+ format: "cjs",
15
+ exports: "named",
16
+ sourcemap: true,
17
+ },
18
+ {
19
+ file: "dist/index.js",
20
+ format: "esm",
21
+ exports: "named",
22
+ sourcemap: true,
23
+ },
24
+ ],
25
+ plugins: [
26
+ autoExternal({ packagePath: "./package.json" }),
27
+ sourcemaps(),
28
+ babel(),
29
+ commonjs(),
30
+ typescript(),
31
+ ],
32
+ };
33
+
34
+ module.exports = config;
package/src/index.ts ADDED
@@ -0,0 +1,182 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "prosemirror-state";
3
+ import { Decoration, DecorationSet } from "prosemirror-view";
4
+ import { diffChars } from "diff";
5
+
6
+ interface ComparePluginOptions {
7
+ comparisonContent: any;
8
+ }
9
+
10
+ declare module "@tiptap/core" {
11
+ interface Commands<ReturnType> {
12
+ compare: {
13
+ setComparisonContent: (content: any) => ReturnType;
14
+ };
15
+ }
16
+ }
17
+
18
+ const pluginKey = new PluginKey("comparePlugin");
19
+
20
+ const ComparePlugin = Extension.create<ComparePluginOptions>({
21
+ name: "compare",
22
+
23
+ addOptions() {
24
+ return {
25
+ comparisonContent: ""
26
+ };
27
+ },
28
+
29
+ addCommands() {
30
+ return {
31
+ setComparisonContent:
32
+ (content: string) =>
33
+ ({ state, dispatch }) => {
34
+ const tr = state.tr.setMeta(pluginKey, {
35
+ comparisonContent: content,
36
+ });
37
+
38
+ if (dispatch) dispatch(tr);
39
+ return true;
40
+ },
41
+ };
42
+ },
43
+
44
+ addProseMirrorPlugins() {
45
+ return [
46
+ new Plugin({
47
+ key: pluginKey,
48
+ state: {
49
+ init: (_, { doc }) => {
50
+ return {
51
+ comparisonContent: this.options.comparisonContent,
52
+ options: this.options,
53
+ };
54
+ },
55
+ apply(tr, pluginState, _, newState) {
56
+ const meta = tr.getMeta(pluginKey);
57
+ if (meta && meta.comparisonContent !== undefined) {
58
+ return {
59
+ ...pluginState,
60
+ comparisonContent: meta.comparisonContent,
61
+ };
62
+ }
63
+ return pluginState;
64
+ },
65
+ },
66
+ props: {
67
+ decorations(state) {
68
+ const pluginState = pluginKey.getState(state);
69
+ if (!pluginState) return null;
70
+
71
+ const { comparisonContent } = pluginState;
72
+ if (!comparisonContent) return null;
73
+ if (!comparisonContent.content) return null;
74
+ if (!comparisonContent.content[0].content) return null;
75
+
76
+ const decos: Decoration[] = [];
77
+ const oldContent = comparisonContent;
78
+ const newContent = state.doc.toJSON();
79
+
80
+ const oldNodes = oldContent.content;
81
+ const newNodes = newContent.content;
82
+
83
+ let pos = 0;
84
+
85
+ for (
86
+ let i = 0;
87
+ i < Math.max(oldNodes?.length, newNodes?.length);
88
+ i++
89
+ ) {
90
+ const oldNode = oldNodes[i];
91
+ const newNode = newNodes[i];
92
+
93
+ if (!oldNode) {
94
+ // Node added
95
+ const nodeSize = state.doc.nodeAt(pos)?.nodeSize || 0;
96
+ decos.push(
97
+ Decoration.node(pos, pos + nodeSize, {
98
+ class: "diff-added bg-[#e6ffec] text-green-500",
99
+ })
100
+ );
101
+ pos += nodeSize;
102
+ } else if (!newNode) {
103
+ // Node removed
104
+ decos.push(Decoration.widget(pos, createRemovedNode(oldNode)));
105
+ } else if (oldNode.type !== newNode.type) {
106
+ // Node type changed
107
+ const nodeSize = state.doc.nodeAt(pos)?.nodeSize || 0;
108
+ decos.push(
109
+ Decoration.node(pos, pos + nodeSize, {
110
+ class: "diff-modified bg-[#ffefc6] text-red-500",
111
+ })
112
+ );
113
+ pos += nodeSize;
114
+ } else {
115
+ // Compare node content
116
+ const oldText = nodeToText(oldNode);
117
+ const newText = nodeToText(newNode);
118
+
119
+ const diff = diffChars(oldText, newText);
120
+ let nodePos = pos + 1; // +1 to skip the node start tag
121
+
122
+ diff.forEach((part) => {
123
+ const length = part.value.length;
124
+ if (part.added) {
125
+ decos.push(
126
+ Decoration.inline(nodePos, nodePos + length, {
127
+ class: "diff-added bg-[#e6ffec] text-green-500",
128
+ })
129
+ );
130
+ nodePos += length;
131
+ } else if (part.removed) {
132
+ decos.push(
133
+ Decoration.widget(nodePos, createRemovedSpan(part.value))
134
+ );
135
+ } else {
136
+ nodePos += length;
137
+ }
138
+ });
139
+
140
+ pos += state.doc.nodeAt(pos)?.nodeSize || 0;
141
+ }
142
+ }
143
+
144
+ return DecorationSet.create(state.doc, decos);
145
+ },
146
+ },
147
+ }),
148
+ ];
149
+ },
150
+ });
151
+
152
+ function nodeToText(node: any): string {
153
+ if (node.type === "text") {
154
+ return node.text || "";
155
+ } else if (node.type === "paragraph") {
156
+ if (!node.content) return " \n";
157
+ return node.content?.map(nodeToText).join("") + "\n";
158
+ } else if (node.type === "image") {
159
+ return `[Image: ${node.attrs.alt || "No alt text"} (${node.attrs.src})]\n`;
160
+ } else if (node.content) {
161
+ return node.content.map(nodeToText).join("");
162
+ }
163
+ return "";
164
+ }
165
+
166
+ function createRemovedSpan(text: string) {
167
+ const span = document.createElement("span");
168
+ span.className = "diff-removed bg-[#ffebe9] line-through text-red-500";
169
+ span.textContent = text;
170
+ return span;
171
+ }
172
+
173
+ function createRemovedNode(node: any) {
174
+ const div = document.createElement("div");
175
+ div.className =
176
+ "diff-removed-node bg-[#ffebe9] line-through px-0 py-0.5 text-red-500";
177
+ div.textContent = nodeToText(node);
178
+ return div;
179
+ }
180
+ export { ComparePlugin };
181
+
182
+ export default ComparePlugin;
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2015",
4
+ "module": "ES2015",
5
+ "lib": ["es2015", "dom"],
6
+ "moduleResolution": "node",
7
+ "declaration": true,
8
+ "noEmit": true,
9
+ "rootDir": "./src",
10
+ }
11
+ }