Skip to content

Commit 9a76b55

Browse files
himanshukelaHimanshu Kapoor
authored and
Himanshu Kapoor
committed
Reame written + automation done
1 parent f35b6c3 commit 9a76b55

9 files changed

+158
-32
lines changed

.remove_spaces.py.swp

12 KB
Binary file not shown.

README.md

+56-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,56 @@
1-
Readme
1+
---------------------------DOM Comparator-------------------------------
2+
3+
## Synopsis
4+
DOM-comparator is a JavaScript library that observes changes to the DOM(Document Object Model) which are just lightweight JavaScript objects.
5+
It tells how the document is different now from how it was, in a very fast manner.
6+
So given two nodes as input say nodeA(original) and nodeB(Modified), this API shows the minimal number of steps required to transform nodeA
7+
to nodeB. The steps are given in nice Jquery format(human readable).
8+
9+
Supported Operations :
10+
1. insertNode
11+
2. deleteNode
12+
3. rearrange
13+
4. textChange
14+
5. css
15+
6. removeCss
16+
7. attr
17+
8. removeAtrr
18+
19+
20+
## Motivation
21+
* Naive approach for DOM-Comparision is to replace new node directly with the old one, but this makes the dynamic content in old dom to become static.
22+
* Considering DOM as a tree, tranforming a tree to another is a complex problem and takes O(n^4) computations. This library implements algorithm which have complexity of O(n^2) in worst case, with some assumptions:
23+
1. The elements in a DOM are not too similar and can be assigned as unique keys.
24+
2. DOM size is not too big (<=1000 elements).
25+
In practice, these assumptions are very negligible for almost all practical use cases.
26+
27+
## Installation
28+
* To install all the dependencies run "npm install"
29+
* Then run "bower install" for 'jasmine', 'jquery' and 'underscore' library dependencies.
30+
* Install grunt which is a Javascript Task Runner
31+
"npm install -g grunt-cli"
32+
33+
## To run Tests
34+
35+
* For testing Jasmine is used which is behavior-driven development framework for testing JavaScript code.
36+
* Tests are written in test/unit folder. Each file in DOM/src have different test cases files and final cases can be seen in dom-comparator.spec.js file .
37+
* For running tests, run "grunt ; testem server" (from home folder... (DOM/))
38+
* To see the final outputs open "http://localhost:7357/" in browser, open console and see final_results array.
39+
40+
## Example
41+
To see example, run the testem server and go to the url mentioned above. Put nodeA in first textarea and nodB in second and press compare button. The result will be seen in the third textarea box in the Jquery format.
42+
43+
44+
45+
## API Reference
46+
47+
Depending on the size of the project, if it is small and simple enough the reference docs can be added to the README. For medium size to larger projects it is important to at least provide a link to where the API reference docs live.
48+
49+
50+
## Contributors
51+
52+
Let people know how they can dive into the project, include important links to things like issue trackers, irc, twitter accounts if applicable.
53+
54+
## License
55+
56+
A short snippet describing the license (MIT, Apache, etc.)

remove_spaces.py

+8-16
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,15 @@
77
88
99
10-
11-
<ul>
12-
13-
14-
<li>2</li>
15-
16-
<li>Jai ho</li>
17-
<li>4</li>
18-
19-
<li>5</li>
20-
21-
<li>HImanshu</li>
10+
<div style="display: block;">
11+
<ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;">
12+
<li><a href="/about">Our Team</a></li>
13+
<li><a href="/careers">Careers</a></li>
14+
<li><a href="/labs">Labs</a></li>
15+
<li class="trigger-contact"><a href="/contact" class="">Contact Us</a></li>
2216
</ul>
23-
<li>1</li>
24-
25-
26-
17+
<div class="clear" style="color: red;">CHANGED TEXT</div>
18+
</div>
2719
2820
2921

src/.dom-comparator.js.swp

44 KB
Binary file not shown.

src/dom-comparator.js

+65-3
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,74 @@ VWO.DOMComparator = function (params) {
2727
// Wrapping method changed ... since matching with the end "div " gives choas ...
2828
// See test case 41 as reference ....
2929

30+
31+
var outA = stripNodes($(this.elA).outerHTML()) ;
32+
var outB = stripNodes($(this.elB).outerHTML()) ;
33+
3034
this.nodeA = VWO.DOMNodePool.create({
31-
el: $("<him id='DOMComparisonResult'>" + $(this.elA).outerHTML() + "</him>").get(0)
35+
el: $("<him id='DOMComparisonResult'>" + outA + "</him>").get(0)
3236
});
3337
this.nodeB = VWO.DOMNodePool.create({
34-
el: $("<him id='DOMComparisonResult'>" + $(this.elB).outerHTML() + "</him>").get(0)
38+
el: $("<him id='DOMComparisonResult'>" + outB + "</him>").get(0)
3539
});
36-
this.elAClone = $("<him id='DOMComparisonResult'>" + $(this.elA).outerHTML() + "</him>").get(0) ;
40+
this.elAClone = $("<him id='DOMComparisonResult'>" + outA + "</him>").get(0) ;
3741
};
3842

43+
function stripNodes(node)
44+
{
45+
var ans = node.replace(/(\r\n|\n|\r)/gm,"");
46+
var out = '', l = ans.length, i = 0 ;
47+
while(i < l)
48+
{
49+
if(ans[i] == '"')
50+
{
51+
out += ans[i];
52+
while(1)
53+
{
54+
i = i + 1 ;
55+
if(ans[i] == '"')
56+
{
57+
out += ans[i] ;
58+
break ;
59+
}
60+
if((i+1) < l && ans[i+1] == "'")
61+
{
62+
out += ans[i] ;
63+
out += '\\' ;
64+
continue ;
65+
}
66+
if(ans[i] == ' ')
67+
{
68+
if(ans[i+1].isAlpha)
69+
{
70+
out += ans[i] ;
71+
continue ;
72+
}
73+
else
74+
continue ;
75+
}
76+
77+
out += ans[i] ;
78+
}
79+
}
80+
81+
else
82+
{
83+
if((i+1) < l && ans[i+1] == "'")
84+
{
85+
out += ans[i] ;
86+
out += '\\' ;
87+
}
88+
else
89+
out += ans[i] ;
90+
}
91+
i = i + 1 ;
92+
}
93+
94+
return out ;
95+
};
96+
97+
3998
VWO.DOMComparator.create = function (params) {
4099
return new VWO.DOMComparator(params);
41100
};
@@ -60,6 +119,8 @@ VWO.DOMComparator.prototype = {
60119
* the second tree, additional properties 'matchScore' and
61120
* 'matchDifference' are also set.
62121
*/
122+
123+
63124
analyzeMatches: function () {
64125
var matches = VWO.DOMMatchFinder.create({
65126
nodeA: this.nodeA,
@@ -451,6 +512,7 @@ VWO.DOMComparator.prototype = {
451512
// a text node could also be removed
452513
selectorPath: null,
453514
content: {
515+
html: node.outerHTML(),
454516
parentSelectorPath: parentSelectorPath,
455517
indexInParent: indexInParent,
456518
existsInDOM: false

test/.test-index.html.swp

20 KB
Binary file not shown.

test/test-index.html

+20-4
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,33 @@
4848
$(".compare").click(function() {
4949
VWO.DOMNodePool.clear();
5050

51+
/*
5152
window.dom1 = VWO.DOMNodePool.create({
5253
el: $($('.txt1').val()).get(null)
5354
});
5455
window.dom2 = VWO.DOMNodePool.create({
5556
el: $($('.txt2').val()).get(null)
5657
});
58+
*/
59+
60+
window.el1 = $($('.txt1').val()).get(null) ;
61+
window.el2 = $($('.txt2').val()).get(null) ;
5762

5863
localStorage.setItem('txt1Val', $('.txt1').val());
5964
localStorage.setItem('txt2Val', $('.txt2').val());
6065

61-
var comp = VWO.DOMComparator.create({
62-
nodeA: dom1,
63-
nodeB: dom2
66+
var domComparator = VWO.DOMComparator.create({
67+
elA: el1 ,
68+
elB: el2
6469
});
6570

66-
comp.compare();
71+
var ret = domComparator.compare();
72+
//alert(JSON.stringify(ret));
73+
document.getElementById('output').value = JSON.stringify(ret) ;
74+
75+
var res = domComparator.verifyComparison()
76+
alert(res) ;
77+
6778
});
6879
});
6980
</script>
@@ -106,5 +117,10 @@ <h1 class="entry-title"><a href="http://fleonlabs.com/2012/06/hello-world/" titl
106117
<button class="compare">Compare</button>
107118

108119

120+
<textarea id="output">
121+
</textarea>
122+
123+
124+
109125
</body>
110126
</html>

test/unit/.dom-comparator.spec.js.swp

72 KB
Binary file not shown.

test/unit/dom-comparator.spec.js

+9-8
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ describe('module: DOMNode-Comparator', function () {
693693

694694
// Not working ...
695695
describe('method: Compare', function () {
696-
xit('case DE_1:compares the dom trees and outputs the final result', function () {
696+
it('case DE_1:compares the dom trees and outputs the final result', function () {
697697

698698

699699
var el1 = $('<div><a>1</a><a>2</a><a>3</a><a>5</a></div>').get(0) ;
@@ -705,38 +705,39 @@ describe('module: DOMNode-Comparator', function () {
705705
}) ;
706706

707707
var ret = domComparator.compare() ;
708-
//expect(ret).toEqual() ;
708+
// expect(ret).toEqual() ;
709709
expect(domComparator.verifyComparison()).toEqual(true) ;
710710

711711
});
712712
});
713713

714714

715715
describe('method: Compare', function () {
716-
xit('case SOlve:compares the dom trees and outputs the final result', function () {
716+
it('case SOlve:compares the dom trees and outputs the final result', function () {
717717

718718

719-
var el1 = $('<nav style="display: block;"><ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;"><li><a href="/about">Our Team</a></li><li><a href="/labs">Labs</a></li><li><a href="/careers">Careers</a></li><li class="trigger-contact"><a href="/contact" class="">Contact Us</a></li></ul><div class="clr"></div></nav>').get(null) ;
720-
var el2 = $('<nav style="display: block;"><ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;"><li><a href="/about">Our Team</a></li><li><a href="/careers">Careers</a></li><li>HImanshu</li><li class="trigger-contact"><a href="/contact" class="">Contact Us</a></li><li><a href="/labs">Labs</a></li></ul><div class="cl"></div></nav>').get(null) ;
719+
var el1 = $('<div style="display: block;"><ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;"><li><a href="/about">Our Team</a></li><li><a href="/labs">Labs</a></li><li><a href="/careers">Careers</a></li><li class="trigger-contact"><a href="/contact" class="">Contact Us</a></li></ul><div class="clr">ORIGINAL TEXT</div></div>').get(null) ;
721720

721+
var el2 = $('<div style="display: block;"><ul class="navigation vwo_1405423029796" style="cursor: auto; display: block;"><li><a href="/about">Our Team</a></li><li><a href="/careers">Careers</a></li><li><a href="/labs">Labs</a></li><li class="trigger-contact"><a href="/contact" class="">Contact Us</a></li></ul><div class="clear" style="color: red;">CHANGED TEXT</div></div>').get(null) ;
722+
722723
var domComparator = VWO.DOMComparator.create({
723724
elA : el1,
724725
elB : el2
725726
}) ;
726727

727728
var ret = domComparator.compare() ;
728-
// expect(ret).toEqual() ;
729+
//expect(ret).toEqual() ;
729730
expect(domComparator.verifyComparison()).toEqual(true) ;
730731

731732
});
732733
});
733734

734735

735736
describe('method: Compare', function () {
736-
it('case :compares the dom trees and outputs the final result', function () {
737+
xit('case :compares the dom trees and outputs the final result', function () {
737738

738739

739-
var el1 = $('<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>').get(0) ;
740+
var el1 = $('<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>').get(null) ;
740741
var el2 = $('<ul><li>2</li><li>Jai ho</li><li>4</li><li>5</li><li>HImanshu</li></ul><li>1</li>').get(null) ;
741742

742743
var domComparator = VWO.DOMComparator.create({

0 commit comments

Comments
 (0)