Skip to content

Commit cc39949

Browse files
[REF] runbot: extract diff display to own component
Also modernize code of the diff match patch use.
1 parent 9097aa4 commit cc39949

File tree

4 files changed

+102
-62
lines changed

4 files changed

+102
-62
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Component, onWillRender } from '@odoo/owl';
2+
3+
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
4+
5+
6+
export class DiffDisplay extends Component {
7+
static template = 'runbot.DiffDisplay';
8+
static props = {
9+
fromValue: { type: String },
10+
toValue: { type: String },
11+
lineFilter: { type: Function },
12+
}
13+
static defaultProps = {
14+
lineFilter: (line) => line.type !== 'kept',
15+
}
16+
17+
setup() {
18+
onWillRender(() => {
19+
this.lines = this.makeLines(this.props.fromValue, this.props.toValue);
20+
});
21+
}
22+
23+
makeLines(oldValue, newValue) {
24+
const diff = this.makeDiff(oldValue, newValue);
25+
const lines = this.prepareForRendering(diff);
26+
return lines;
27+
}
28+
29+
makeDiff(text1, text2) {
30+
const dmp = new diff_match_patch();
31+
const a = dmp.diff_linesToChars_(text1, text2);
32+
const lineText1 = a.chars1;
33+
const lineText2 = a.chars2;
34+
const lineArray = a.lineArray;
35+
const diffs = dmp.diff_main(lineText1, lineText2, false);
36+
dmp.diff_charsToLines_(diffs, lineArray);
37+
dmp.diff_cleanupSemantic(diffs);
38+
return diffs;
39+
}
40+
41+
prepareForRendering(diffs) {
42+
let preLineCounter = 0;
43+
let postLineCounter = 0;
44+
return diffs.reduce((lines, {0: diff_type, 1: data}) => {
45+
data.split('\n').forEach(line => {
46+
line = line
47+
.replace(/&/g, '&')
48+
.replace(/</g, '&lt;')
49+
.replace(/>/g, '&gt;');
50+
let type, colOne, colTwo;
51+
switch (diff_type) {
52+
case 0: //kept
53+
type = 'kept'
54+
colOne = ''
55+
colTwo = postLineCounter;
56+
preLineCounter++; postLineCounter++;
57+
break;
58+
case -1: //removed
59+
type = 'removed';
60+
colOne = preLineCounter;
61+
colTwo = '-';
62+
preLineCounter++;
63+
break;
64+
case 1: //added
65+
type = 'added';
66+
colOne = '+';
67+
colTwo = postLineCounter;
68+
postLineCounter++;
69+
break;
70+
default:
71+
console.warn('Unknown diff_type', diff_type)
72+
return;
73+
}
74+
lines.push({type, colOne, colTwo, line});
75+
})
76+
return lines
77+
}, []);
78+
}
79+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<templates>
3+
<t t-name="runbot.DiffDisplay">
4+
<div class="code_diff">
5+
<table>
6+
<tr t-foreach="lines" t-as="line" t-key="line_index" t-if="props.lineFilter(line)">
7+
<td class="col_number" t-out="line.colOne"/>
8+
<td class="col_number" t-out="line.colTwo"/>
9+
<td class="code" t-att-class="line.type" t-out="line.line"/>
10+
</tr>
11+
</table>
12+
</div>
13+
</t>
14+
</templates>

runbot/static/src/js/fields/tracking_value.js

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
import { patch } from "@web/core/utils/patch";
33
import { Message } from "@mail/core/common/message";
44
import { diff_match_patch } from "@runbot/libs/diff_match_patch/diff_match_patch";
5+
import { DiffDisplay } from './diff_display';
6+
7+
patch(Message, {
8+
components: {...Message.components, DiffDisplay},
9+
});
510

611
patch(Message.prototype, {
712
setup() {
@@ -13,9 +18,6 @@ patch(Message.prototype, {
1318
const newValue = trackingValue.newValue.value;
1419
return ((oldValue && typeof oldValue=== 'string' && oldValue.includes('\n')) && (newValue && typeof oldValue=== 'string' && newValue.includes('\n')))
1520
},
16-
formatTracking(trackingType, trackingValue) {
17-
return super.formatTracking(trackingType, trackingValue)
18-
},
1921
toggleKept() {
2022
this.kept = !this.kept;
2123
},
@@ -29,52 +31,4 @@ patch(Message.prototype, {
2931
navigator.clipboard.writeText(trackingValue.newValue.value);
3032
};
3133
},
32-
lines(trackingValue) {
33-
const oldValue = trackingValue.oldValue.value;
34-
const newValue = trackingValue.newValue.value;
35-
const diff = this.makeDiff(oldValue, newValue);
36-
const lines = this.prepareForRendering(diff);
37-
return lines;
38-
},
39-
makeDiff(text1, text2) {
40-
var dmp = new diff_match_patch();
41-
var a = dmp.diff_linesToChars_(text1, text2);
42-
var lineText1 = a.chars1;
43-
var lineText2 = a.chars2;
44-
var lineArray = a.lineArray;
45-
var diffs = dmp.diff_main(lineText1, lineText2, false);
46-
dmp.diff_charsToLines_(diffs, lineArray);
47-
dmp.diff_cleanupSemantic(diffs);
48-
return diffs;
49-
},
50-
prepareForRendering(diffs) {
51-
var lines = [];
52-
var pre_line_counter = 0
53-
var post_line_counter = 0
54-
for (var x = 0; x < diffs.length; x++) {
55-
var diff_type = diffs[x][0];
56-
var data = diffs[x][1];
57-
var data_lines = data.split('\n');
58-
for (var line_index in data_lines) {
59-
var line = data_lines[line_index];
60-
line = line.replace(/&/g, '&amp;');
61-
line = line.replace(/</g, '&lt;');
62-
line = line.replace(/>/g, '&gt;');
63-
//text = text.replace(/\n/g, '<br>');
64-
//text = text.replace(/ /g, '&nbsp&nbsp');
65-
if (diff_type == -1) {
66-
lines.push({type:'removed', pre_line_counter: pre_line_counter, post_line_counter: '-', line: line})
67-
pre_line_counter += 1
68-
} else if (diff_type == 0) {
69-
lines.push({type:'kept', pre_line_counter: '', post_line_counter: post_line_counter, line: line})
70-
pre_line_counter += 1
71-
post_line_counter +=1
72-
} else if (diff_type == 1) {
73-
lines.push({type:'added', pre_line_counter: '+', post_line_counter: post_line_counter, line: line})
74-
post_line_counter +=1
75-
}
76-
}
77-
}
78-
return lines;
79-
},
8034
});

runbot/static/src/js/fields/tracking_value.xml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,10 @@
1010
<button class="btn btn-sm btn-outline-primary" t-on-click="copyNewToClipboard(trackingValue)">Copy new value to clipboard</button>
1111
</div>
1212
<div class="o-mail-Message-trackingField ms-1 fst-italic text-muted">(<t t-out="trackingValue.changedField"/>)</div>
13-
<div class="code_diff">
14-
<table>
15-
<t t-foreach="lines(trackingValue)" t-as="line" t-key="line_index">
16-
<tr t-if="kept or line.type!=='kept'">
17-
<td class="col_number" t-out="line.pre_line_counter"/>
18-
<td class="col_number" t-out="line.post_line_counter"/>
19-
<td class="code" t-att-class="line.type" t-out="line.line"/>
20-
</tr>
21-
</t>
22-
</table>
23-
</div>
13+
<DiffDisplay
14+
fromValue="trackingValue.oldValue.value" toValue="trackingValue.newValue.value"
15+
lineFilter="kept ? () => true : undefined"
16+
/>
2417
</t>
2518
<t t-else="">
2619
<span class="o-mail-Message-trackingOld me-1 px-1 text-muted fw-bold" t-out="formatTrackingOrNone(trackingValue.fieldType, trackingValue.oldValue)"/>

0 commit comments

Comments
 (0)