diff --git a/js/htmldiff.js b/js/htmldiff.js
index 5e0c28b..c88539c 100644
--- a/js/htmldiff.js
+++ b/js/htmldiff.js
@@ -59,7 +59,7 @@
* null otherwise
*/
function is_start_of_atomic_tag(word){
- var result = /^<(iframe|object|math|svg|script)/.exec(word);
+ var result = /^<(iframe|object|math|svg|script|video)/.exec(word);
if (result){
result = result[1];
}
@@ -99,7 +99,8 @@
* @return {boolean} True if the token can be wrapped inside a tag, false otherwise.
*/
function is_wrappable(token){
- return isnt_tag(token) || is_start_of_atomic_tag(token) || is_void_tag(token);
+ var is_img = /^]/.test(token);
+ return is_img|| isnt_tag(token) || is_start_of_atomic_tag(token) || is_void_tag(token);
}
/**
@@ -250,10 +251,44 @@
* @return {string} The identifying key that should be used to match before and after tokens.
*/
function get_key_for_token(token){
+ // If the token is an image element, grab it's src attribute to include in the key.
+ var img = /^$/.exec(token);
+ if (img) {
+ return '';
+ }
+
+ // If the token is an object element, grab it's data attribute to include in the key.
+ var object = /^';
+ }
+
+ // If it's a video, math or svg element, the entire token should be compared except the
+ // data-uuid.
+ if(/^<(svg|math|video)[\s>]/.test(token)) {
+ var uuid = token.indexOf('data-uuid="');
+ if (uuid !== -1) {
+ var start = token.slice(0, uuid);
+ var end = token.slice(uuid + 44);
+ return start + end;
+ } else {
+ return token;
+ }
+ }
+
+ // If the token is an iframe element, grab it's src attribute to include in it's key.
+ var iframe = /^/.exec(token);
+ if (iframe) {
+ return '';
+ }
+
+ // If token any other element, just grab the tag name.
var tag_name = /<([^\s>]+)[\s>]/.exec(token);
if (tag_name){
return '<' + (tag_name[1].toLowerCase()) + '>';
}
+
+ // Otherwise, the token is text, collapse the whitespace.
if (token){
return token.replace(/(\s+| | )/g, ' ');
}
diff --git a/test/diff.spec.js b/test/diff.spec.js
index e286224..ea0fd72 100644
--- a/test/diff.spec.js
+++ b/test/diff.spec.js
@@ -1,8 +1,10 @@
describe('Diff', function(){
- var cut, res;
+ var cut, res, html_to_tokens, calculate_operations;
beforeEach(function(){
cut = require('../js/htmldiff');
+ html_to_tokens = cut.html_to_tokens;
+ calculate_operations = cut.calculate_operations;
});
describe('When both inputs are the same', function(){
@@ -45,4 +47,164 @@ describe('Diff', function(){
'input 2');
});
}); // describe('When a class name is specified')
+
+ describe('Image Differences', function(){
+ it('show two images as different if their src attributes are different', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'replace',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+
+ it('should show two images are the same if their src attributes are the same', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'equal',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+ }); // describe('Image Differences')
+
+ describe('Widget Differences', function(){
+ it('show two widgets as different if their data attributes are different', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'replace',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+
+ it('should show two widgets are the same if their data attributes are the same', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'equal',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+ }); // describe('Widget Differences')
+
+ describe('Math Differences', function(){
+ it('should show two math elements as different if their contents are different', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'replace',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+
+ it('should show two math elements as the same if their contents are the same', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'equal',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+ }); // describe('Math Differences')
+
+ describe('Video Differences', function(){
+ it('show two widgets as different if their data attributes are different', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'replace',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+
+ });
+
+ it('should show two widgets are the same if their data attributes are the same', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'equal',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+ }); // describe('Video Differences')
+
+ describe('iframe Differences', function(){
+ it('show two widgets as different if their data attributes are different', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'replace',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+
+ it('should show two widgets are the same if their data attributes are the same', function() {
+ var before = html_to_tokens('');
+ var after = html_to_tokens('');
+ var ops = calculate_operations(before, after);
+ expect(ops.length).to.equal(1);
+ expect(ops[0]).to.eql({
+ action: 'equal',
+ start_in_before: 0,
+ end_in_before: 0,
+ start_in_after: 0,
+ end_in_after: 0
+ });
+ });
+ }); // describe('iframe Differences')
+
}); // describe('Diff')