Bug 11876 [Follow-up] Add a diff view to staged MARC Records
[koha.git] / koha-tmpl / intranet-tmpl / lib / jsdiff / jsdiff.js
1 /*
2  * Javascript Diff Algorithm
3  *  By John Resig (http://ejohn.org/)
4  *  Modified by Chu Alan "sprite"
5  *
6  * Released under the MIT license.
7  *
8  * More Info:
9  *  http://ejohn.org/projects/javascript-diff-algorithm/
10  */
11
12 function escape(s) {
13     var n = s;
14     n = n.replace(/&/g, "&");
15     n = n.replace(/</g, "&lt;");
16     n = n.replace(/>/g, "&gt;");
17     n = n.replace(/"/g, "&quot;");
18
19     return n;
20 }
21
22 function diffString( o, n ) {
23   o = o.replace(/\s+$/, '');
24   n = n.replace(/\s+$/, '');
25
26   var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/) );
27   var str = "";
28
29   var oSpace = o.match(/\s+/g);
30   if (oSpace == null) {
31     oSpace = ["\n"];
32   } else {
33     oSpace.push("\n");
34   }
35   var nSpace = n.match(/\s+/g);
36   if (nSpace == null) {
37     nSpace = ["\n"];
38   } else {
39     nSpace.push("\n");
40   }
41
42   if (out.n.length == 0) {
43       for (var i = 0; i < out.o.length; i++) {
44         str += '<del>' + escape(out.o[i]) + oSpace[i] + "</del>";
45       }
46   } else {
47     if (out.n[0].text == null) {
48       for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
49         str += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>";
50       }
51     }
52
53     for ( var i = 0; i < out.n.length; i++ ) {
54       if (out.n[i].text == null) {
55         str += '<ins>' + escape(out.n[i]) + nSpace[i] + "</ins>";
56       } else {
57         var pre = "";
58
59         for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
60           pre += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>";
61         }
62         str += " " + out.n[i].text + nSpace[i] + pre;
63       }
64     }
65   }
66
67   return str;
68 }
69
70 function randomColor() {
71     return "rgb(" + (Math.random() * 100) + "%, " +
72                     (Math.random() * 100) + "%, " +
73                     (Math.random() * 100) + "%)";
74 }
75 function diffString2( o, n ) {
76   o = o.replace(/\s+$/, '');
77   n = n.replace(/\s+$/, '');
78
79   var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/) );
80
81   var oSpace = o.match(/\s+/g);
82   if (oSpace == null) {
83     oSpace = ["\n"];
84   } else {
85     oSpace.push("\n");
86   }
87   var nSpace = n.match(/\s+/g);
88   if (nSpace == null) {
89     nSpace = ["\n"];
90   } else {
91     nSpace.push("\n");
92   }
93
94   var os = "";
95   var colors = new Array();
96   for (var i = 0; i < out.o.length; i++) {
97       colors[i] = randomColor();
98
99       if (out.o[i].text != null) {
100           os += '<span style="background-color: ' +colors[i]+ '">' +
101                 escape(out.o[i].text) + oSpace[i] + "</span>";
102       } else {
103           os += "<del>" + escape(out.o[i]) + oSpace[i] + "</del>";
104       }
105   }
106
107   var ns = "";
108   for (var i = 0; i < out.n.length; i++) {
109       if (out.n[i].text != null) {
110           ns += '<span style="background-color: ' +colors[out.n[i].row]+ '">' +
111                 escape(out.n[i].text) + nSpace[i] + "</span>";
112       } else {
113           ns += "<ins>" + escape(out.n[i]) + nSpace[i] + "</ins>";
114       }
115   }
116
117   return { o : os , n : ns };
118 }
119
120 function diff( o, n ) {
121   var ns = new Object();
122   var os = new Object();
123
124   for ( var i = 0; i < n.length; i++ ) {
125     if ( ns[ n[i] ] == null )
126       ns[ n[i] ] = { rows: new Array(), o: null };
127     ns[ n[i] ].rows.push( i );
128   }
129
130   for ( var i = 0; i < o.length; i++ ) {
131     if ( os[ o[i] ] == null )
132       os[ o[i] ] = { rows: new Array(), n: null };
133     os[ o[i] ].rows.push( i );
134   }
135
136   for ( var i in ns ) {
137     if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) {
138       n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] };
139       o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] };
140     }
141   }
142
143   for ( var i = 0; i < n.length - 1; i++ ) {
144     if ( n[i].text != null && n[i+1].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
145          n[i+1] == o[ n[i].row + 1 ] ) {
146       n[i+1] = { text: n[i+1], row: n[i].row + 1 };
147       o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 };
148     }
149   }
150
151   for ( var i = n.length - 1; i > 0; i-- ) {
152     if ( n[i].text != null && n[i-1].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
153          n[i-1] == o[ n[i].row - 1 ] ) {
154       n[i-1] = { text: n[i-1], row: n[i].row - 1 };
155       o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 };
156     }
157   }
158
159   return { o: o, n: n };
160 }