mirror of
https://github.com/samsonjs/json-diff.git
synced 2026-03-25 09:25:48 +00:00
started seperating html/css/library components making ready for nodejs
This commit is contained in:
parent
fa5d621ea6
commit
0ef44f6158
9 changed files with 281 additions and 52 deletions
9
bin/jsond
Normal file
9
bin/jsond
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var sys = require("sys"),
|
||||||
|
fs = require("fs"),
|
||||||
|
argv = require('optimist').argv,
|
||||||
|
colors = require("colors"),
|
||||||
|
jsond = require("../js/lib/jsond");
|
||||||
|
|
||||||
|
// To-Do: seperate rendering to provision for nodejs output using colors etc.
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
body {
|
body {
|
||||||
background-color: lightblue;
|
color: #333;
|
||||||
|
|
||||||
|
background: #eeeeee; /* old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #eeeeee 0%, #cccccc 100%); /* firefox */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#cccccc)); /* webkit */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* ie */
|
||||||
|
|
||||||
|
font-family:Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#results li > span, #results ul > span {
|
#results li > span, #results ul > span {
|
||||||
|
|
@ -18,11 +25,11 @@ body {
|
||||||
margin-left: -15px;
|
margin-left: -15px;
|
||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
background: url(open.png) no-repeat 2px 5px;
|
background: url(../img/open.png) no-repeat 2px 5px;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
#results ul[closed="yes"] {
|
#results ul[closed="yes"] {
|
||||||
background: url(closed.png) no-repeat 2px 5px;
|
background: url(../img/closed.png) no-repeat 2px 5px;
|
||||||
}
|
}
|
||||||
#results ul[closed="yes"] > * {
|
#results ul[closed="yes"] > * {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -53,15 +60,67 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
.contentbox {
|
.contentbox {
|
||||||
border: 1px dashed black;
|
|
||||||
background-color: white;
|
-moz-box-shadow: 2px 2px 3px #666;
|
||||||
|
-webkit-box-shadow: 2px 2px 3px #666;
|
||||||
|
box-shadow: 2px 2px 3px #666;
|
||||||
|
|
||||||
|
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
background: #eeeeee; /* old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #eeeeee 0%, #cccccc 100%); /* firefox */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eeeeee), color-stop(100%,#cccccc)); /* webkit */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#cccccc',GradientType=0 ); /* ie */
|
||||||
|
|
||||||
|
border: 1px solid #666;
|
||||||
|
|
||||||
|
color: #666;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
input[type=button] {
|
||||||
|
cursor:pointer;
|
||||||
|
height:35px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding:0 -8px;
|
||||||
|
|
||||||
|
background: #7d7e7d; /* old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #7d7e7d 0%, #0e0e0e 100%); /* firefox */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7d7e7d), color-stop(100%,#0e0e0e)); /* webkit */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7d7e7d', endColorstr='#0e0e0e',GradientType=0 ); /* ie */
|
||||||
|
|
||||||
|
color: #eee;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
border:#666 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
border: 1px solid #666;
|
||||||
|
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
background: #EDEDED; /* old browsers */
|
||||||
|
background: -moz-linear-gradient(top, #EDEDED 0%, #f6f6f6 47%, #FFFFFF 100%); /* firefox */
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#EDEDED), color-stop(47%,#f6f6f6), color-stop(100%,#FFFFFF)); /* webkit */
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EDEDED', endColorstr='#FFFFFF',GradientType=0 ); /* ie */
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0px;;
|
margin: 0px;
|
||||||
|
font-size: 35px;
|
||||||
|
color: #666;
|
||||||
|
text-shadow: #515151 1px 1px 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#results {
|
#results {
|
||||||
|
|
|
||||||
BIN
img/bg.jpg
Normal file
BIN
img/bg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
img/closed.png
Normal file
BIN
img/closed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
BIN
img/open.png
Normal file
BIN
img/open.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
34
index.html
34
index.html
|
|
@ -4,14 +4,8 @@
|
||||||
<meta charset=utf8>
|
<meta charset=utf8>
|
||||||
<link rel="stylesheet" href="css/json-diff.css" type="text/css" media="screen" title="no title" charset="utf-8">
|
<link rel="stylesheet" href="css/json-diff.css" type="text/css" media="screen" title="no title" charset="utf-8">
|
||||||
</head>
|
</head>
|
||||||
<body onload="init();">
|
<body>
|
||||||
<p align="center" style="margin: 2em;">Courtesy of <a href="http://tlrobinson.net/projects/javascript-fun/jsondiff/">tlrobinson</a>.
|
<h1>json-diff</h1>
|
||||||
<br>
|
|
||||||
This version differs in that it supports <code>null</code> values,<br>
|
|
||||||
downplays the significance of changed properties with the key <code>key</code>,<br>
|
|
||||||
and provides links to jump from one change to the next.</p>
|
|
||||||
|
|
||||||
<h2>JSON Diff</h2>
|
|
||||||
<div class="contentbox" id="instructions">
|
<div class="contentbox" id="instructions">
|
||||||
<ul>
|
<ul>
|
||||||
<li>Paste some JSON in each of the text fields. Click "Compare" to see the diff.</li>
|
<li>Paste some JSON in each of the text fields. Click "Compare" to see the diff.</li>
|
||||||
|
|
@ -26,31 +20,17 @@
|
||||||
</textarea>
|
</textarea>
|
||||||
<textarea id="jsonB">
|
<textarea id="jsonB">
|
||||||
</textarea>
|
</textarea>
|
||||||
<input type="button" value="Compare" id="compare" onclick="startCompare();" />
|
<input type="button" value="Compare" id="compare" />
|
||||||
<input type="button" value="Swap" id="swap" onclick="swapBoxes();"/>
|
<input type="button" value="Swap" id="swap" />
|
||||||
<input type="button" value="Clear" id="clear" onclick="clearBoxes();"/>
|
<input type="button" value="Clear" id="clear" />
|
||||||
</div>
|
</div>
|
||||||
<p align=center id=first style=display:none><a href=#change-0>first change</a></p>
|
<p align=center id=first style=display:none><a href=#change-0>first change</a></p>
|
||||||
<div class="contentbox" id="results">
|
<div class="contentbox" id="results">
|
||||||
</div>
|
</div>
|
||||||
<div class="contentbox" id="issues">
|
|
||||||
<h3>About</h3>
|
|
||||||
<p>JSON Diff is a simple way to visualize and compare <a href="http://json.org">JSON</a>.</p>
|
|
||||||
<h3>Known Issues</h3>
|
|
||||||
<ul>
|
|
||||||
<li>Diff algorithm not very intelligent when dealing with arrays</li>
|
|
||||||
<li>Probably doesn't work in IE</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<p>
|
|
||||||
© 2006-2010 Thomas Robinson. <a rel="license" href="http://creativecommons.org/licenses/by-nc/3.0/us/">Some rights reserved</a>. </p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="js/lib/json-diff.js" type="text/javascript" charset="utf-8"></script>
|
<script src="js/lib/jsond.js?v=1" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="js/app.js" type="text/javascript" charset="utf-8"></script>
|
<script src="js/app.js?v=1" type="text/javascript" charset="utf-8"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
64
js/app.js
64
js/app.js
|
|
@ -55,30 +55,58 @@ if(!window.console){
|
||||||
|
|
||||||
Init: function() {
|
Init: function() {
|
||||||
|
|
||||||
console.log('>>> Init()');
|
var self = this;
|
||||||
|
|
||||||
document.addEventListener("click", this.clickHandler, false);
|
|
||||||
|
|
||||||
jsonBoxA = document.getElementById("jsonA");
|
|
||||||
jsonBoxB = document.getElementById("jsonB");
|
|
||||||
|
|
||||||
jsonDiff.feedback = this.markChanged;
|
|
||||||
|
|
||||||
this.populteSamples();
|
window.onload = function() {
|
||||||
this.startCompare();
|
|
||||||
}
|
console.log('>>> Init()');
|
||||||
|
|
||||||
populteSamples: function() {
|
document.addEventListener("click", self.clickHandler, false);
|
||||||
|
|
||||||
|
jsonBoxA = document.getElementById("jsonA");
|
||||||
|
jsonBoxB = document.getElementById("jsonB");
|
||||||
|
|
||||||
|
function populateValues(a, b) {
|
||||||
|
jsonBoxA.value = JSON.stringify(a);
|
||||||
|
jsonBoxB.value = JSON.stringify(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateResults(results) {
|
||||||
|
console.log(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("swap").addEventListener("click", function() {
|
||||||
|
jsond.swap(populateValues);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
document.getElementById("clear").addEventListener("click", function() {
|
||||||
|
jsond.clear(populateValues);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
document.getElementById("compare").addEventListener("click", function() {
|
||||||
|
jsond.compare(JSON.parse(jsonBoxA.value), JSON.parse(jsonBoxB.value), "root", populateResults);
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
jsond.feedback = self.markChanged;
|
||||||
|
|
||||||
|
self.assignSamples();
|
||||||
|
self.startCompare();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
assignSamples: function() {
|
||||||
|
|
||||||
console.log('>>> populateSamples()');
|
console.log('>>> populateSamples()');
|
||||||
|
|
||||||
jsonBoxA.value = JSON.stringify(samples.a);
|
jsonBoxA.value = JSON.stringify(jsond.a = samples.a);
|
||||||
jsonBoxB.value = JSON.stringify(samples.b);
|
jsonBoxB.value = JSON.stringify(jsond.b = samples.b);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
startCompare: function () {
|
startCompare: function () {
|
||||||
|
|
||||||
console.log('>>> startCompare()');
|
console.log('>>> startCompare()');
|
||||||
var objA, objB;
|
var objA, objB;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
@ -101,7 +129,7 @@ if(!window.console){
|
||||||
while (results.firstChild)
|
while (results.firstChild)
|
||||||
results.removeChild(results.firstChild);
|
results.removeChild(results.firstChild);
|
||||||
|
|
||||||
jsonDiff.compareTree(objA, objB, "root", results);
|
jsond.compare(objA, objB, "root", results);
|
||||||
},
|
},
|
||||||
|
|
||||||
markChanged: function(node) {
|
markChanged: function(node) {
|
||||||
|
|
@ -113,7 +141,7 @@ if(!window.console){
|
||||||
n += 1;
|
n += 1;
|
||||||
var nextNode = document.createElement('a');
|
var nextNode = document.createElement('a');
|
||||||
nextNode.setAttribute('href', '#change-' + n);
|
nextNode.setAttribute('href', '#change-' + n);
|
||||||
nextNode.appendChild(document.createTextNode('↓ next change ↓'))
|
nextNode.appendChild(document.createTextNode('↓ next change ↓'));
|
||||||
node.appendChild(nextNode);
|
node.appendChild(nextNode);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
130
js/lib/jsond.js
Normal file
130
js/lib/jsond.js
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
|
||||||
|
var jsond = (typeof exports !== "undefined" ? exports : window).jsond = (function(){
|
||||||
|
|
||||||
|
function isArray(value) {
|
||||||
|
return value && typeof value === "object" && value.constructor === Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
function typeofReal(value) {
|
||||||
|
return isArray(value) ? "array": value === null ? 'null' : typeof value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getType(value) {
|
||||||
|
(typeA === "object" || typeA === "array") ? "": String(a) + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
version: "0.0.1",
|
||||||
|
|
||||||
|
a: [], // first structure
|
||||||
|
b: [], // second structure
|
||||||
|
|
||||||
|
feedback: function() {
|
||||||
|
},
|
||||||
|
|
||||||
|
swap: function(fn) {
|
||||||
|
console.log('>>> swapBoxes()');
|
||||||
|
this.a = [this.b, this.b = this.a][0];
|
||||||
|
fn(this.a, this.b);
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function(fn) {
|
||||||
|
console.log('>>> clearValues()');
|
||||||
|
this.a = this.b = {};
|
||||||
|
fn(this.a, this.b);
|
||||||
|
},
|
||||||
|
|
||||||
|
compare: function(a, b, name, fn) {
|
||||||
|
|
||||||
|
// To-Do: a and/or b should accept a uri or a json structure.
|
||||||
|
// To-Do: this DOM manipulation should be seperated into logic and rendering so that it works with nodejs.
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var typeA = typeofReal(a);
|
||||||
|
var typeB = typeofReal(b);
|
||||||
|
|
||||||
|
console.log('>>> compare(a=(', typeA, ')', a,
|
||||||
|
', b=(', typeB, ')', b,
|
||||||
|
', name=(', typeof name, ')', name,
|
||||||
|
', results=(', typeof results, ')', results, ')');
|
||||||
|
|
||||||
|
var typeSpanA = document.createElement("span");
|
||||||
|
typeSpanA.appendChild(document.createTextNode("(" + typeA + ")"))
|
||||||
|
typeSpanA.setAttribute("class", "typeName");
|
||||||
|
|
||||||
|
var typeSpanB = document.createElement("span");
|
||||||
|
typeSpanB.appendChild(document.createTextNode("(" + typeB + ")"))
|
||||||
|
typeSpanB.setAttribute("class", "typeName");
|
||||||
|
|
||||||
|
var aString = (typeA === "object" || typeA === "array") ? "": String(a) + " ";
|
||||||
|
var bString = (typeB === "object" || typeB === "array") ? "": String(b) + " ";
|
||||||
|
|
||||||
|
var leafNode = document.createElement("span");
|
||||||
|
leafNode.appendChild(document.createTextNode(name));
|
||||||
|
if (a === undefined)
|
||||||
|
{
|
||||||
|
leafNode.setAttribute("class", "added");
|
||||||
|
leafNode.appendChild(document.createTextNode(": " + bString));
|
||||||
|
leafNode.appendChild(typeSpanB);
|
||||||
|
self.feedback(leafNode);
|
||||||
|
}
|
||||||
|
else if (b === undefined)
|
||||||
|
{
|
||||||
|
leafNode.setAttribute("class", "removed");
|
||||||
|
leafNode.appendChild(document.createTextNode(": " + aString));
|
||||||
|
leafNode.appendChild(typeSpanA);
|
||||||
|
self.feedback(leafNode);
|
||||||
|
}
|
||||||
|
else if (typeA !== typeB || (typeA !== "object" && typeA !== "array" && a !== b))
|
||||||
|
{
|
||||||
|
leafNode.setAttribute("class", "changed");
|
||||||
|
leafNode.appendChild(document.createTextNode(": " + aString));
|
||||||
|
leafNode.appendChild(typeSpanA);
|
||||||
|
leafNode.appendChild(document.createTextNode(" => " + bString));
|
||||||
|
leafNode.appendChild(typeSpanB);
|
||||||
|
|
||||||
|
if (name === 'key') leafNode.setAttribute('class', 'changed key');
|
||||||
|
else self.feedback(leafNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leafNode.appendChild(document.createTextNode(": " + aString));
|
||||||
|
leafNode.appendChild(typeSpanA);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeA === "object" || typeA === "array" || typeB === "object" || typeB === "array")
|
||||||
|
{
|
||||||
|
var keys = [];
|
||||||
|
for (var i in a) keys.push(i);
|
||||||
|
for (var i in b) keys.push(i);
|
||||||
|
keys.sort();
|
||||||
|
|
||||||
|
var listNode = document.createElement("ul");
|
||||||
|
listNode.appendChild(leafNode);
|
||||||
|
|
||||||
|
for (var i = 0; i < keys.length; i++)
|
||||||
|
{
|
||||||
|
if (keys[i] === keys[i - 1])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var li = document.createElement("li");
|
||||||
|
listNode.appendChild(li);
|
||||||
|
|
||||||
|
self.compare(a && a[keys[i]], b && b[keys[i]], keys[i], li);
|
||||||
|
}
|
||||||
|
|
||||||
|
results.appendChild(listNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
results.appendChild(leafNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
23
package.json
Normal file
23
package.json
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"name": "jsond",
|
||||||
|
"description": "compare json with a web interface/CLI or API",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"author": "hij1nx <http://githib.com/hij1nx>",
|
||||||
|
"contributors": [
|
||||||
|
{ "name": "hij1nx", "email": "hi1jnx.dev@gmail.com" },
|
||||||
|
{ "name": "Tom Robinson", "email": "tlr@gmail.com" },
|
||||||
|
{ "name": "Sami Samhuri", "email": "samisamhuri@gmail.com" }
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/samsonjs/json-diff"
|
||||||
|
},
|
||||||
|
"keywords": ["cli", "json", "diff", "tools"],
|
||||||
|
"dependencies": {
|
||||||
|
"optimist": ">= 0.0.6",
|
||||||
|
"colors": ">= 0.3.0"
|
||||||
|
},
|
||||||
|
"bin": { "forever": "./bin/jsond" },
|
||||||
|
"main": "./lib/jsond",
|
||||||
|
"engines": { "node": ">= 0.2.0" }
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue