@pronto-tools-and-more/diff-process 11.0.0 → 11.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/src/parts/AddHash/AddHash.js +22 -0
- package/src/parts/AddHashes/AddHashes.js +7 -0
- package/src/parts/Diff/Diff.js +32 -1
- package/src/parts/GetChangeAncestor/GetChangeAncestor.js +45 -0
- package/src/parts/GetChangedView/GetChangedView.js +0 -0
- package/src/parts/GetChangedViews/GetChangedViews.js +22 -0
- package/src/parts/GetChanges/GetChanges.js +27 -0
- package/src/parts/PidKey/PidKey.js +1 -0
package/package.json
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
import * as Hash from "../Hash/Hash.js";
|
2
|
+
|
3
|
+
export const addHash = (view) => {
|
4
|
+
const { content, ...rest } = view;
|
5
|
+
if (Array.isArray(content)) {
|
6
|
+
let subtreeHashes = "";
|
7
|
+
for (const item of content) {
|
8
|
+
if (typeof item === "object") {
|
9
|
+
addHash(item);
|
10
|
+
subtreeHashes += item.subtreeHash;
|
11
|
+
subtreeHashes += item.attributeHash;
|
12
|
+
} else if (typeof content === "string") {
|
13
|
+
subtreeHashes += Hash.hash(content);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
view.subtreeHash = Hash.hash(subtreeHashes);
|
17
|
+
} else if (typeof content === "string") {
|
18
|
+
view.subtreeHash = Hash.hash(content);
|
19
|
+
}
|
20
|
+
view.attributeHash = Hash.hash(JSON.stringify(rest));
|
21
|
+
return view;
|
22
|
+
};
|
package/src/parts/Diff/Diff.js
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
import * as AddHashes from "../AddHashes/AddHashes.js";
|
2
|
+
import * as GetChangedViews from "../GetChangedViews/GetChangedViews.js";
|
3
|
+
import * as GetChanges from "../GetChanges/GetChanges.js";
|
4
|
+
|
5
|
+
// TODO walk all nodes
|
6
|
+
// return one of four changes
|
7
|
+
// 1. full update
|
8
|
+
// 2. classname update
|
9
|
+
// 3. text update
|
10
|
+
// 4. node update
|
11
|
+
|
1
12
|
export const diff = (oldViews, newViews) => {
|
2
|
-
|
13
|
+
if (!oldViews) {
|
14
|
+
return [
|
15
|
+
{
|
16
|
+
type: "full-update",
|
17
|
+
},
|
18
|
+
];
|
19
|
+
}
|
20
|
+
if (oldViews.length !== newViews.length) {
|
21
|
+
return [
|
22
|
+
{
|
23
|
+
type: "full-update",
|
24
|
+
},
|
25
|
+
];
|
26
|
+
}
|
27
|
+
|
28
|
+
AddHashes.addHashes(oldViews);
|
29
|
+
AddHashes.addHashes(newViews);
|
30
|
+
|
31
|
+
const changed = GetChangedViews.getChangedViews(oldViews, newViews);
|
32
|
+
const changes = GetChanges.getChanges(changed);
|
33
|
+
return changes;
|
3
34
|
};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
export const getChangeAncestor = (oldView, newView) => {
|
2
|
+
const oldContent = oldView.content;
|
3
|
+
const newContent = newView.content;
|
4
|
+
|
5
|
+
// if (oldContent === undefined || newContent === undefined) {
|
6
|
+
// console.log({ oldView, newView });
|
7
|
+
// }
|
8
|
+
|
9
|
+
const oldContentLength = oldContent.length;
|
10
|
+
const newContentLength = newContent.length;
|
11
|
+
if (oldContentLength !== newContentLength) {
|
12
|
+
return {
|
13
|
+
type: "length-change",
|
14
|
+
oldView,
|
15
|
+
newView,
|
16
|
+
};
|
17
|
+
}
|
18
|
+
|
19
|
+
for (let i = 0; i < oldContentLength; i++) {
|
20
|
+
const oldItem = oldContent[i];
|
21
|
+
const newItem = newContent[i];
|
22
|
+
if (oldItem.subtreeHash !== newItem.subtreeHash) {
|
23
|
+
const childChanges = getChangeAncestor(oldItem, newItem);
|
24
|
+
return childChanges;
|
25
|
+
}
|
26
|
+
if (oldItem.attributeHash !== newItem.attributeHash) {
|
27
|
+
return {
|
28
|
+
type: "attribute-hash",
|
29
|
+
oldView,
|
30
|
+
newView,
|
31
|
+
};
|
32
|
+
}
|
33
|
+
}
|
34
|
+
for (let i = 0; i < oldContentLength; i++) {
|
35
|
+
const oldItem = oldContent[i];
|
36
|
+
const newItem = newContent[i];
|
37
|
+
const childChanges = getChangeAncestor(oldItem, newItem);
|
38
|
+
if (childChanges.type !== "equal") {
|
39
|
+
return childChanges;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
return {
|
43
|
+
type: "equal",
|
44
|
+
};
|
45
|
+
};
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
const isEqual = (oldView, newView) => {
|
2
|
+
return (
|
3
|
+
oldView.attributeHash === newView.attributeHash &&
|
4
|
+
oldView.subtreeHash === newView.subtreeHash
|
5
|
+
);
|
6
|
+
};
|
7
|
+
|
8
|
+
export const getChangedViews = (oldViews, newViews) => {
|
9
|
+
const length = oldViews.length;
|
10
|
+
const changed = [];
|
11
|
+
for (let i = 0; i < length; i++) {
|
12
|
+
const oldView = oldViews[i];
|
13
|
+
const newView = newViews[i];
|
14
|
+
if (!isEqual(oldView, newView)) {
|
15
|
+
changed.push({
|
16
|
+
oldView,
|
17
|
+
newView,
|
18
|
+
});
|
19
|
+
}
|
20
|
+
}
|
21
|
+
return changed;
|
22
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import * as GetChangeAncestor from "../GetChangeAncestor/GetChangeAncestor.js";
|
2
|
+
import * as PidKey from "../PidKey/PidKey.js";
|
3
|
+
|
4
|
+
export const getChanges = (changed) => {
|
5
|
+
const changes = [];
|
6
|
+
for (const item of changed) {
|
7
|
+
const { oldView, newView } = item;
|
8
|
+
const ancestor = GetChangeAncestor.getChangeAncestor(oldView, newView);
|
9
|
+
// TODO at this point, figure out type of update
|
10
|
+
// 1. text change
|
11
|
+
// 2. attribute change
|
12
|
+
// 3. full node change
|
13
|
+
if (
|
14
|
+
ancestor &&
|
15
|
+
ancestor.type === "length-change" &&
|
16
|
+
typeof ancestor.oldView.content === "string" &&
|
17
|
+
typeof ancestor.newView.content === "string"
|
18
|
+
) {
|
19
|
+
changes.push({
|
20
|
+
type: "text-change",
|
21
|
+
ref: ancestor.newView.attributes[PidKey.pidKey],
|
22
|
+
newText: ancestor.newView.content,
|
23
|
+
});
|
24
|
+
}
|
25
|
+
}
|
26
|
+
return changes;
|
27
|
+
};
|
@@ -0,0 +1 @@
|
|
1
|
+
export const pidKey = "data-prid";
|