Skip to content

Commit 39ed076

Browse files
committed
Merge pull request #49 from Shuhrat/master
Some refactoring
2 parents ad30723 + 515e582 commit 39ed076

7 files changed

Lines changed: 275 additions & 183 deletions

File tree

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
node_modules/
2-
.DS_Store
32
coverage/
3+
4+
.DS_Store
5+
.idea/

lib/cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var path = require('path'),
22
vow = require('vow'),
33
vfs = require('vow-fs'),
4-
HtmlDiffer = require('./html-differ').HtmlDiffer,
4+
HtmlDiffer = require('./index').HtmlDiffer,
55
diffLogger = require('./diff-logger');
66

77
module.exports = require('coa').Cmd()

lib/html-differ.js

Lines changed: 0 additions & 178 deletions
This file was deleted.

lib/index.js

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
var utils = require('./utils'),
2+
3+
diff = require('diff'),
4+
htmlParser = require('htmlparser'),
5+
AST2Html = require('htmlparser-to-html'),
6+
_ = require('lodash');
7+
8+
/**
9+
* Converts HTML to DOM Tree
10+
* @param {String} HTML
11+
* @param {Object} options
12+
* @returns {AST}
13+
*/
14+
function htmlToAST(HTML, options) {
15+
var parser,
16+
parserHandler;
17+
18+
parserHandler = new htmlParser.DefaultHandler(function(err) {
19+
if (err) console.log(err);
20+
}, options);
21+
22+
parser = new htmlParser.Parser(parserHandler);
23+
parser.parseComplete(HTML);
24+
25+
return parserHandler.dom;
26+
}
27+
28+
/**
29+
*
30+
* @param {AST} tree
31+
* @param {Object} options
32+
* @returns {AST}
33+
*/
34+
function modifyASTTree(tree, options) {
35+
_.each(tree, function(node) {
36+
Object.keys(node).forEach(function(leaf) {
37+
if (leaf === 'attribs') {
38+
var attrs = utils.sortObj(node[leaf]);
39+
40+
if (attrs.hasOwnProperty('class')) {
41+
attrs['class'] = utils.sortCssClasses(attrs['class']);
42+
}
43+
44+
_.each(options.compareHtmlAttrsAsJSON, function(attr) {
45+
var attrValue,
46+
isFunction = (attr === 'onclick' || attr === 'ondblclick'); // @FIXME: should be configurable
47+
48+
if (attrs.hasOwnProperty(attr)) {
49+
50+
attrValue = utils.parseAttr(attrs[attr].replace(/"/g, '"'), isFunction);
51+
attrValue = utils.sortObj(attrValue);
52+
attrValue = JSON.stringify(attrValue);
53+
54+
attrs[attr] = (isFunction ? 'return ' : '') + attrValue.replace(/"/g, '"')
55+
}
56+
});
57+
58+
_.each(options.ignoreHtmlAttrs, function(attr) {
59+
attrs.hasOwnProperty(attr) && (attrs[attr] = '');
60+
});
61+
62+
node[leaf] = attrs;
63+
}
64+
else if (leaf === 'children') {
65+
modifyASTTree(node.children, options);
66+
}
67+
});
68+
});
69+
70+
return tree;
71+
}
72+
73+
/**
74+
*
75+
* @param [options]
76+
* @param {String[]} [options.ignoreHtmlAttrs]
77+
* @param {String[]} [options.compareHtmlAttrsAsJSON]
78+
* @param {Boolean} [options.verbose]
79+
* @param {Boolean} [options.ignoreWhitespace=true]
80+
* @param {Boolean} [options.bem=true]
81+
* @constructor
82+
*/
83+
var HtmlDiff = function(options) {
84+
this.options = utils.defaults(options);
85+
};
86+
87+
var Diff = diff.Diff;
88+
89+
HtmlDiff.prototype = Diff.prototype;
90+
91+
/**
92+
* Tokenizes a given string
93+
* @param {String} value
94+
* @returns {Array}
95+
*/
96+
HtmlDiff.prototype.tokenize = function(value) {
97+
var options = this.options,
98+
ASTTree = htmlToAST(value, options);
99+
100+
ASTTree = modifyASTTree(ASTTree, options);
101+
102+
/*
103+
* Bug in 'html-parser-to-html'
104+
* String '"' is converted into '"'
105+
* Added issue => github.com/mixu/htmlparser-to-html/issues/1
106+
*/
107+
value = AST2Html(ASTTree).replace(/"/g, '"');
108+
109+
return _.filter(value.split(/(\s+|\b)/));
110+
};
111+
112+
/**
113+
*
114+
* @param [options]
115+
* @param {String[]} [options.ignoreHtmlAttrs]
116+
* @param {String[]} [options.compareHtmlAttrsAsJSON]
117+
* @param {Boolean} [options.verbose]
118+
* @param {Boolean} [options.ignoreWhitespace=true]
119+
* @param {Boolean} [options.bem=true]
120+
* @constructor
121+
*/
122+
var HtmlDiffer = function(options) {
123+
options = utils.defaults(options);
124+
125+
if (options['bem']) {
126+
options.ignoreHtmlAttrs = ['id', 'for'];
127+
options.compareHtmlAttrsAsJSON = ['data-bem', 'onclick', 'ondblclick'];
128+
}
129+
130+
this.options = options;
131+
};
132+
133+
/**
134+
*
135+
* @param {String} html1
136+
* @param {String} html2
137+
* @param {Object} [options]
138+
* @returns {Diff}
139+
*/
140+
HtmlDiffer.prototype.diffHtml = function(html1, html2, options) {
141+
if (options) {
142+
console.warn('WARNING! The third param of "diffHtml" method is deprecated!');
143+
}
144+
145+
var htmlDiffer = new HtmlDiff(options);
146+
147+
return htmlDiffer.diff(html1, html2);
148+
};
149+
150+
/**
151+
* Compares two given chunks of HTML
152+
* @param {String} html1
153+
* @param {String} html2
154+
* @param {Object} [options]
155+
* @returns {Boolean}
156+
*/
157+
HtmlDiffer.prototype.isEqual = function(html1, html2, options) {
158+
if (options) {
159+
console.warn('WARNING! The third param of "isEqual" method is deprecated!');
160+
}
161+
162+
options = _.defaults(this.options, options);
163+
164+
var htmlDiffer = new HtmlDiff(options),
165+
diff = htmlDiffer.diff(html1, html2);
166+
167+
return (diff.length === 1 && !diff[0].added && !diff[0].removed);
168+
};
169+
170+
/**
171+
* @deprecated
172+
* @param {String} html1
173+
* @param {String} html2
174+
*/
175+
function bemDiff(html1, html2) {
176+
console.warn('WARNING! You use deprecated method \'bemDiff\'!');
177+
178+
var logger = require('./diff-logger'),
179+
options = {
180+
ignoreHtmlAttrs: ['id', 'for'],
181+
compareHtmlAttrsAsJSON: ['data-bem', 'onclick', 'ondblclick']
182+
},
183+
loggerOptions = {
184+
showCharacters: 20
185+
},
186+
187+
htmlDiffer = new HtmlDiff(options);
188+
189+
logger.log(htmlDiffer.diff(html1, html2), loggerOptions);
190+
}
191+
192+
193+
var htmlDiffer = new HtmlDiffer();
194+
195+
module.exports = {
196+
HtmlDiff: HtmlDiff,
197+
HtmlDiffer: HtmlDiffer,
198+
diffHtml: htmlDiffer.diffHtml.bind(htmlDiffer),
199+
isEqual: htmlDiffer.isEqual.bind(htmlDiffer),
200+
201+
bemDiff: bemDiff
202+
};

0 commit comments

Comments
 (0)