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 {
|
||||
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 {
|
||||
|
|
@ -18,11 +25,11 @@ body {
|
|||
margin-left: -15px;
|
||||
padding-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;
|
||||
}
|
||||
#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"] > * {
|
||||
display: none;
|
||||
|
|
@ -53,15 +60,67 @@ textarea {
|
|||
}
|
||||
|
||||
.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;
|
||||
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;
|
||||
margin: 0px;;
|
||||
margin: 0px;
|
||||
font-size: 35px;
|
||||
color: #666;
|
||||
text-shadow: #515151 1px 1px 1px;
|
||||
}
|
||||
|
||||
#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>
|
||||
<link rel="stylesheet" href="css/json-diff.css" type="text/css" media="screen" title="no title" charset="utf-8">
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<p align="center" style="margin: 2em;">Courtesy of <a href="http://tlrobinson.net/projects/javascript-fun/jsondiff/">tlrobinson</a>.
|
||||
<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>
|
||||
<body>
|
||||
<h1>json-diff</h1>
|
||||
<div class="contentbox" id="instructions">
|
||||
<ul>
|
||||
<li>Paste some JSON in each of the text fields. Click "Compare" to see the diff.</li>
|
||||
|
|
@ -26,31 +20,17 @@
|
|||
</textarea>
|
||||
<textarea id="jsonB">
|
||||
</textarea>
|
||||
<input type="button" value="Compare" id="compare" onclick="startCompare();" />
|
||||
<input type="button" value="Swap" id="swap" onclick="swapBoxes();"/>
|
||||
<input type="button" value="Clear" id="clear" onclick="clearBoxes();"/>
|
||||
<input type="button" value="Compare" id="compare" />
|
||||
<input type="button" value="Swap" id="swap" />
|
||||
<input type="button" value="Clear" id="clear" />
|
||||
</div>
|
||||
<p align=center id=first style=display:none><a href=#change-0>first change</a></p>
|
||||
<div class="contentbox" id="results">
|
||||
</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/app.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?v=1" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
64
js/app.js
64
js/app.js
|
|
@ -55,30 +55,58 @@ if(!window.console){
|
|||
|
||||
Init: function() {
|
||||
|
||||
console.log('>>> Init()');
|
||||
|
||||
document.addEventListener("click", this.clickHandler, false);
|
||||
|
||||
jsonBoxA = document.getElementById("jsonA");
|
||||
jsonBoxB = document.getElementById("jsonB");
|
||||
|
||||
jsonDiff.feedback = this.markChanged;
|
||||
var self = this;
|
||||
|
||||
this.populteSamples();
|
||||
this.startCompare();
|
||||
}
|
||||
|
||||
populteSamples: function() {
|
||||
window.onload = function() {
|
||||
|
||||
console.log('>>> Init()');
|
||||
|
||||
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()');
|
||||
|
||||
jsonBoxA.value = JSON.stringify(samples.a);
|
||||
jsonBoxB.value = JSON.stringify(samples.b);
|
||||
jsonBoxA.value = JSON.stringify(jsond.a = samples.a);
|
||||
jsonBoxB.value = JSON.stringify(jsond.b = samples.b);
|
||||
|
||||
},
|
||||
|
||||
startCompare: function () {
|
||||
|
||||
|
||||
console.log('>>> startCompare()');
|
||||
var objA, objB;
|
||||
n = 0;
|
||||
|
|
@ -101,7 +129,7 @@ if(!window.console){
|
|||
while (results.firstChild)
|
||||
results.removeChild(results.firstChild);
|
||||
|
||||
jsonDiff.compareTree(objA, objB, "root", results);
|
||||
jsond.compare(objA, objB, "root", results);
|
||||
},
|
||||
|
||||
markChanged: function(node) {
|
||||
|
|
@ -113,7 +141,7 @@ if(!window.console){
|
|||
n += 1;
|
||||
var nextNode = document.createElement('a');
|
||||
nextNode.setAttribute('href', '#change-' + n);
|
||||
nextNode.appendChild(document.createTextNode('↓ next change ↓'))
|
||||
nextNode.appendChild(document.createTextNode('↓ next change ↓'));
|
||||
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