diff dom
by lid0
HTML
<!-- Sample of diff where existing elements got changes -->
<div class="container">
<div id="a" class='view'>
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta</h1>
<p>what is going on</p>
<p>bbbb</p>
</div>
<div id="b" class='view'>
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta2</h1>
<p>what is going on</p>
<p>bbabb</p>
</div>
</div>
<div class="container">
<div id="aa" class='view'>
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta</h1>
<p>what is going on</p>
<p>bbbb</p>
</div>
<div id="bb" class='view'>
<p>aaa</p>
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta</h1>
<h1>this is not sparta</h1>
<p>what is going on</p>
<p>ccccc</p>
<p>bbbb</p>
<p>ccccc</p>
<p>ddddddd</p>
</div>
</div>
<!-- Sample of diff with new lines
<div id="a">
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta</h1>
<p>what is going on</p>
<p>bbbb</p>
</div>
<div id="b">
<p>aaa</p>
<p>hellob</p>
<p>aaa</p>
<h1>this is sparta</h1>
<h1>this is not sparta</h1>
<p>what is going on</p>
<p>ccccc</p>
<p>bbbb</p>
<p>ccccc</p>
</div>
-->
CSS
.view{
border:1px solid #cfcfcf;
display:inline-block;
padding:5px;
vertical-align:top;
}
.container{
border-bottom:2px dashed black;
margin-bottom:15px;
display:block;
clear:both;
}
.diff {
border:1px dashed green;
background:#D8FFC5;
}
JavaScript
/**
A prototype code to detect difference between two similar DOM containers.
This is usful for an editor with a live preview, and the detection of the
element that was changes to bring it into view.
Ideally the diff should be performed with a small increment of changes between.
view A and view B
**/
a1 = $("#a");
b1 = $("#b");
a2 = $("#aa");
b2 = $("#bb");
function inner_diff(a,b){
console.log("inner_diff", a, b);
if (a.html() === b.html()){
return true;
} else{
return false;
}
}
console.log("equal by innerHTML:", inner_diff(a1,b1)? "yes" : "no");
function find_diff(a,b){
var same_root_children = (a.length === b.length);
console.log( a.length, b.length );
var ai = 0, bi =0;
while( (ai < a.length || bi < b.length) && (ai<a.length) && (bi<b.length) ){
if ($(a[ai]).html() == $(b[bi]).html()){
console.log("match at", ai, bi);
} else {
console.log("diff at", ai, bi, $(b[bi]).html() );
$(b[bi]).addClass("diff");
if (same_root_children) {
//if we have the same number of children
//the change is on a specific line
//once we detect the different line
// we increment bot ai and bi pointers.
//in this case we can also perform a deeper
//diff if there are multiple childrens,
//to identify the sub element it occured at.
} else{
ai--; //prevent increment
}
}
//detect new lines, when view b has more "lines" at the end
if (ai==a.length-1 && bi < b.length){
while(bi < b.length-1){ //mark the rest of the element as "new"
bi++;
$(b[bi]).addClass("diff");
console.log("possible more new lines", ai,bi,b[bi]);
}
}
ai++;
...