The class LGPL license:
// Author: Michael Schøler, 2008
// LGPL license, use as you like, don't hold me responsible for success or failure though
Array.prototype.compareTo = function(compareAry) {
if (this.length === compareAry.length) {
var i;
for (i = 0; i < compareAry.length; i+=1) {
if (Object.isArray(this[i]) === true) {
if (this[i].compareTo(compareAry[i]) === false) {
return false;
}
continue;
}
else if (this[i] !== compareAry[i]) {
return false;
}
}
return true;
}
return false;
};
var jsonDataHandler = {
diff: function(j1, j2) {
if (typeof this.diffing === "undefined" || this.diffing === 0) {
this.diffCyclicCheck = [];
this.diffing = 0;
}
var diffRes = {};
this.diffing += 1;
if (typeof j1 === "undefined") {
j1 = {};
}
if (typeof j2 === "undefined") {
j2 = {};
}
if (typeof this.diffCyclicCheck === "undefined") {
this.diffCyclicCheck = [];
}
var key, bDiff;
for (key in j2) if (j2.hasOwnProperty(key)) {
bDiff = false;
if (typeof j1[key] === "undefined" || typeof j1[key] != typeof j2[key]) {
bDiff = true;
}
else if (j1[key] !== j2[key]) {
if (typeof j2[key] === "object") {
if (this.diffCyclicCheck.indexOf(j2[key]) >= 0) {
break;
}
else if (Object.isArray(j2[key])) {
if (j1[key].length !== j2[key].length || j1[key] !== j2[key]) {
if (j2[key].compareTo(j1[key]) === false) {
bDiff = true;
}
}
}
else if (typeof j1[key] === "object") {
var dR = this.diff(j1[key], j2[key]);
if (Object.keys(dR).length > 0) {
diffRes[key] = dR;
}
}
else {
bDiff = true;
}
this.diffCyclicCheck.push(j2[key]);
}
else if (j1[key] !== j2[key]) {
bDiff = true;
}
}
if (bDiff) {
diffRes[key] = j2[key];
}
}
for (key in j1) if (j1.hasOwnProperty(key)) {
bDiff = false;
if (typeof j2[key] === "undefined") {
diffRes[key] = j1[key];
}
}
this.diffing -= 1;
return diffRes;
}
};