@matrixreq/htmldiff 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +147 -0
- package/htmldiff-cli.js +125 -0
- package/js/htmldiff.d.ts +17 -0
- package/js/htmldiff.js +1005 -0
- package/package.json +60 -0
- package/sample/after.html +18 -0
- package/sample/after.png +0 -0
- package/sample/before.html +18 -0
- package/sample/before.png +0 -0
- package/test/calculate_operations.spec.js +278 -0
- package/test/config.js +2 -0
- package/test/diff.spec.js +210 -0
- package/test/edge_cases.spec.js +31 -0
- package/test/find_matching_blocks.spec.js +168 -0
- package/test/from_port_source.spec.js +30 -0
- package/test/html_to_tokens.spec.js +128 -0
- package/test/mocha.opts +3 -0
- package/test/module.spec.js +11 -0
- package/test/pain_games.spec.js +18 -0
- package/test/render_operations.spec.js +177 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2012 The Network Inc. and contributors
|
|
4
|
+
Copyright (c) 2022 idesis GmbH, Max-Keith-Straße 66 (E 11), D-45136 Essen, https://www.idesis.de
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
the Software without restriction, including without limitation the rights to
|
|
9
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
10
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
11
|
+
so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# htmldiff.js
|
|
2
|
+
|
|
3
|
+
Diff and markup HTML with `<ins>` and `<del>` tags.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Origin
|
|
7
|
+
|
|
8
|
+
Quote from the original source of this fork:
|
|
9
|
+
|
|
10
|
+
*`htmldiff.js` is a JavaScript port of [https://github.com/myobie/htmldiff](https://github.com/myobie/htmldiff) by
|
|
11
|
+
[Keanu Lee](http://keanulee.com) at [Inkling](https://www.inkling.com/).*
|
|
12
|
+
|
|
13
|
+
**htmldiff.js** is based on [this fork](https://github.com/inkling/htmldiff.js) and adds a few things:
|
|
14
|
+
|
|
15
|
+
- Diffing of video, math, widget, iframe, img and svg tags.
|
|
16
|
+
- Ability to set atomic tags via the API.
|
|
17
|
+
- A command line interface.
|
|
18
|
+
- TypeScript support.
|
|
19
|
+
- Better documentation.
|
|
20
|
+
|
|
21
|
+
See also *Credits* below.
|
|
22
|
+
|
|
23
|
+
## Description
|
|
24
|
+
|
|
25
|
+
htmldiff takes two HTML snippets or files and marks the differences between them with
|
|
26
|
+
`<ins>` and `<del>` tags. The diffing understands HTML so it doesn't do a pure text diff,
|
|
27
|
+
instead it will insert the appropriate tags for changed/added/deleted text nodes, single
|
|
28
|
+
tags or tag hierarchies.
|
|
29
|
+
|
|
30
|
+
The module can be used as module in Node.js, with RequireJS, or even just as a script tag.
|
|
31
|
+
|
|
32
|
+
## API
|
|
33
|
+
|
|
34
|
+
The module exports a single default function:
|
|
35
|
+
|
|
36
|
+
JavaScript:
|
|
37
|
+
|
|
38
|
+
````javascript
|
|
39
|
+
diff(before, after, className, dataPrefix, atomicTags);
|
|
40
|
+
````
|
|
41
|
+
|
|
42
|
+
TypeScript:
|
|
43
|
+
|
|
44
|
+
````javascript
|
|
45
|
+
function diff(before: string, after: string, className?: string | null, dataPrefix?: string | null, atomicTags?: string | null): string;
|
|
46
|
+
````
|
|
47
|
+
|
|
48
|
+
### Parameters
|
|
49
|
+
|
|
50
|
+
- `before` (string) is the original HTML text.
|
|
51
|
+
- `after` (string) is the HTML text after the changes have been applied.
|
|
52
|
+
|
|
53
|
+
The return value is a string with the diff result, marked by `<ins>` and `del` tags. The
|
|
54
|
+
function has three optional parameters. If an empty string or `null` is used for any
|
|
55
|
+
of these three parameters it will be ignored:
|
|
56
|
+
|
|
57
|
+
- `className` (string) className will be added as a class attribute on every inserted
|
|
58
|
+
`<ins>` and `<del>` tag.
|
|
59
|
+
- `dataPrefix` (string) The data prefix to use for data attributes. The so called *operation
|
|
60
|
+
index data attribute* will be named `data-${dataPrefix-}operation-index`. If not used,
|
|
61
|
+
the default attribute name `data-operation-index` will be added on every inserted
|
|
62
|
+
`<ins>` and `<del>` tag. The value of this attribute is an auto incremented counter.
|
|
63
|
+
- `atomicTags` (string) Comma separated list of tag names. The list has to be in the form
|
|
64
|
+
`tag1,tag2,...` e. g. `head,script,style`. An atomic tag is one whose child nodes should
|
|
65
|
+
not be compared - the entire tag should be treated as one token. This is useful for tags
|
|
66
|
+
where it does not make sense to insert `<ins>` and `<del>` tags. If not used, the default
|
|
67
|
+
list will be used:
|
|
68
|
+
`iframe,object,math,svg,script,video,head,style`.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Example
|
|
72
|
+
|
|
73
|
+
JavaScript:
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
diff = require('node-htmldiff');
|
|
77
|
+
|
|
78
|
+
console.log(diff('<p>This is some text</p>', '<p>That is some more text</p>', 'myClass'));
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
TypeScript:
|
|
82
|
+
|
|
83
|
+
```javascript
|
|
84
|
+
import diff = require("node-htmldiff");
|
|
85
|
+
|
|
86
|
+
console.log(diff("<p>This is some text</p>", "<p>That is some more text</p>", "myClass"));
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Please note that `diff` is only an arbitrary name; since the module exports only one default
|
|
90
|
+
function you can use whatever name you like, e. g., `diffHTML`.
|
|
91
|
+
|
|
92
|
+
Result:
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<p><del data-operation-index="1" class="myClass">This</del><ins data-operation-index="1" class="myClass">That</ins> is some<ins data-operation-index="3" class="myClass"> more</ins> text.</p>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
## Command line interface
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
htmldiff beforeFile afterFile diffedFile [-c className] [-p dataPrefix] [-t atomicTags]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Parameters:
|
|
106
|
+
|
|
107
|
+
- `beforeFile` An HTML input file in its original form.
|
|
108
|
+
|
|
109
|
+
- `afterFile` An HTML input file, based on `beforeFile` but with changes.
|
|
110
|
+
|
|
111
|
+
- `diffedFile` Name of the diffed HTML output file. All differences between
|
|
112
|
+
`beforeFile` and `afterFile` will be surrounded with `<ins>` and `<del>`
|
|
113
|
+
tags. If diffedFile is `-` (minus) the result will be written with
|
|
114
|
+
`console.log()` to stdout.
|
|
115
|
+
|
|
116
|
+
Options:
|
|
117
|
+
|
|
118
|
+
`-c className`, `-p dataPrefix` and `-t atomicTags` are all optional. For a
|
|
119
|
+
description please see API documentation above.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Development
|
|
123
|
+
|
|
124
|
+
After cloning the repository run `npm i` or `npm install` to install the necessary
|
|
125
|
+
dependencies. A run of `npm run make` creates the JavaScript output file.
|
|
126
|
+
`npm run lint` checks the TypeScript sources with TSLint. `npm test` runs all the
|
|
127
|
+
tests from the `test` directory. `npm run testsample` diffs the HTML sample files
|
|
128
|
+
from the directory `sample` and logs the result to the console.
|
|
129
|
+
|
|
130
|
+
The command line interface of htmldiff is developed in TypeScript so you have to run
|
|
131
|
+
`npm run make` once to create the JavaScript output file.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## Credits
|
|
135
|
+
|
|
136
|
+
This module wouldn't have been possible without code from the following projects/persons:
|
|
137
|
+
|
|
138
|
+
- Original project: [The Network Inc.](http://www.tninetwork.com), [Github](https://github.com/tnwinc/htmldiff.js)
|
|
139
|
+
- Massive improvements of the original code: [Inkling](https://www.inkling.com), [Github](https://github.com/inkling/htmldiff.js)
|
|
140
|
+
- Support of more tags: Ian White, [Github](https://github.com/ian97531)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT © [idesis GmbH](https://www.idesis.de), Max-Keith-Straße 66 (E 11), D-45136 Essen
|
|
146
|
+
|
|
147
|
+
See the `LICENSE` file for details.
|
package/htmldiff-cli.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const htmldiff_1 = __importDefault(require("./js/htmldiff"));
|
|
10
|
+
const argc = process.argv.length;
|
|
11
|
+
const cli = (0, path_1.parse)(__filename).name;
|
|
12
|
+
let className = null;
|
|
13
|
+
let dataPrefix = null;
|
|
14
|
+
let atomicTags = null;
|
|
15
|
+
function printUsage() {
|
|
16
|
+
const usage = `${cli} v0.9.4
|
|
17
|
+
|
|
18
|
+
Usage: ${cli} beforeFile afterFile diffedFile [Options]
|
|
19
|
+
|
|
20
|
+
beforeFile:
|
|
21
|
+
An HTML input file in its original form.
|
|
22
|
+
|
|
23
|
+
afterFile:
|
|
24
|
+
An HTML input file, based on beforeFile but with changes.
|
|
25
|
+
|
|
26
|
+
diffedFile:
|
|
27
|
+
Name of the diffed HTML output file. All differences between beforeFile
|
|
28
|
+
and afterFile will be surrounded with <ins> and <del> tags. If diffedFile
|
|
29
|
+
is - (minus) the result will be written with console.log() to stdout.
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
|
|
33
|
+
-c className (optional):
|
|
34
|
+
className will be added as a class attribute on every <ins> and <del> tag.
|
|
35
|
+
|
|
36
|
+
-p dataPrefix (optional):
|
|
37
|
+
The data prefix to use for data attributes. The operation index data
|
|
38
|
+
attribute will be named "data-$\{dataPrefix-}operation-index". If not
|
|
39
|
+
used, the default attribute name "data-operation-index" will be added
|
|
40
|
+
on every <ins> and <del> tag. The value of this attribute is an auto
|
|
41
|
+
incremented counter.
|
|
42
|
+
|
|
43
|
+
-t atomicTags (optional):
|
|
44
|
+
Comma separated list of tag names. The list has to be in the form
|
|
45
|
+
"tag1,tag2,..." e. g. "head,script,style". An atomic tag is one whose
|
|
46
|
+
child nodes should not be compared - the entire tag should be treated
|
|
47
|
+
as one token. This is useful for tags where it does not make sense to
|
|
48
|
+
insert <ins> and <del> tags. If not used, this default list will be used:
|
|
49
|
+
"iframe,object,math,svg,script,video,head,style".`;
|
|
50
|
+
console.log(usage);
|
|
51
|
+
}
|
|
52
|
+
function readFileContent(fileName) {
|
|
53
|
+
try {
|
|
54
|
+
const result = (0, fs_1.readFileSync)((0, path_1.resolve)(fileName), "utf-8");
|
|
55
|
+
if (result === "") {
|
|
56
|
+
console.error(`File "${fileName}" is empty.`);
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
console.error(`Couldn't read file "${fileName}"\n${error}`);
|
|
62
|
+
return "";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function resolveSwitch(name, value) {
|
|
66
|
+
switch (name) {
|
|
67
|
+
case "-c":
|
|
68
|
+
if (className) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
className = value;
|
|
72
|
+
return true;
|
|
73
|
+
case "-p":
|
|
74
|
+
if (dataPrefix) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
dataPrefix = value;
|
|
78
|
+
return true;
|
|
79
|
+
case "-t":
|
|
80
|
+
if (atomicTags) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
atomicTags = value;
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
const validArgc = [5, 7, 9, 11];
|
|
89
|
+
if (validArgc.indexOf(argc) === -1) {
|
|
90
|
+
printUsage();
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
if (argc > 6) {
|
|
94
|
+
if (!resolveSwitch(process.argv[5], process.argv[6])) {
|
|
95
|
+
printUsage();
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (argc > 8) {
|
|
100
|
+
if (!resolveSwitch(process.argv[7], process.argv[8])) {
|
|
101
|
+
printUsage();
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (argc > 10) {
|
|
106
|
+
if (!resolveSwitch(process.argv[9], process.argv[10])) {
|
|
107
|
+
printUsage();
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const beforeFile = readFileContent(process.argv[2]);
|
|
112
|
+
if (!beforeFile) {
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
const afterFile = readFileContent(process.argv[3]);
|
|
116
|
+
if (!afterFile) {
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
const diffedResult = (0, htmldiff_1.default)(beforeFile, afterFile, className, dataPrefix, atomicTags);
|
|
120
|
+
if (process.argv[4] === "-") {
|
|
121
|
+
console.log(diffedResult);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
(0, fs_1.writeFileSync)((0, path_1.resolve)(process.argv[4]), diffedResult);
|
|
125
|
+
}
|
package/js/htmldiff.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares two pieces of HTML content and returns the combined content with differences
|
|
3
|
+
* wrapped in <ins> and <del> tags.
|
|
4
|
+
* @param before The HTML content before the changes.
|
|
5
|
+
* @param after The HTML content after the changes.
|
|
6
|
+
* @param className (Optional) The class attribute to include in `<ins>` and `<del>` tags.
|
|
7
|
+
* @param dataPrefix (Optional) The data prefix to use for data attributes. The operation index data
|
|
8
|
+
* attribute will be named `data-${dataPrefix-}operation-index`.
|
|
9
|
+
* @param atomicTags (Optional) Comma separated list of tag names. The list has to be in the form
|
|
10
|
+
* `tag1,tag2,...` e. g. `head,script,style`. An atomic tag is one whose child nodes should not be
|
|
11
|
+
* compared - the entire tag should be treated as one token. This is useful for tags where it does
|
|
12
|
+
* not make sense to insert `<ins>` and `<del>` tags. If not used, the default list
|
|
13
|
+
* `iframe,object,math,svg,script,video,head,style` will be used.
|
|
14
|
+
* @return The combined HTML content with differences wrapped in `<ins>` and `<del>` tags.
|
|
15
|
+
*/
|
|
16
|
+
declare function diff(before: string, after: string, className?: string | null, dataPrefix?: string | null, atomicTags?: string | null): string;
|
|
17
|
+
export = diff;
|