diff --git a/.gitignore b/.gitignore index 06f62bf..3c3629e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -*.js node_modules diff --git a/README.md b/README.md index 7da4ee1..fce14f0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # htmldiff.js ### HTML Diffing in JavaScript (ok, CoffeeScript actually.) -[![Build Status](https://secure.travis-ci.org/tnwinc/htmldiff.js.png)](http://travis-ci.org/tnwinc/htmldiff.js) +[![Build Status](https://travis-ci.org/keanulee/htmldiff.js.svg?branch=master)](https://travis-ci.org/keanulee/htmldiff.js) `htmldiff.js` is a CoffeeScript port of https://github.com/myobie/htmldiff (This one has a few more tests.) diff --git a/js/htmldiff.js b/js/htmldiff.js new file mode 100644 index 0000000..e4c56f0 --- /dev/null +++ b/js/htmldiff.js @@ -0,0 +1,482 @@ +// Generated by CoffeeScript 1.7.1 +(function() { + var Match, calculate_operations, consecutive_where, create_index, diff, find_match, find_matching_blocks, get_key_for_token, html_to_tokens, is_end_of_atomic_tag, is_end_of_tag, is_start_of_atomic_tag, is_start_of_tag, is_tag, is_whitespace, isnt_tag, op_map, recursively_find_matching_blocks, render_operations, wrap; + + is_end_of_tag = function(char) { + return char === '>'; + }; + + is_start_of_tag = function(char) { + return char === '<'; + }; + + is_whitespace = function(char) { + return /^\s+$/.test(char); + }; + + is_tag = function(token) { + return /^\s*<[^>]+>\s*$/.test(token); + }; + + isnt_tag = function(token) { + return !is_tag(token); + }; + + + /* + * Checks if the current word is the beginning of an atomic tag. An atomic tag is one whose + * child nodes should not be compared - the entire tag should be treated as one token. + * + * @param {string} word The characters of the current token read so far. + * + * @return {string|null} The name of the atomic tag if the word will be an atomic tag, + * null otherwise + */ + + is_start_of_atomic_tag = function(word) { + var result; + result = /^<(iframe|object|math|svg)/.exec(word); + if (result) { + result = result[1]; + } + return result; + }; + + + /* + * Checks if the current word is the end of an atomic tag (i.e. it has all the characters, + * except for the end bracket of the closing tag, such as "

') + .eql ['

', '', '

'] + + it 'should identify an object tag as a single token', -> + (expect @cut '

') + .eql ['

', '', '

'] + + it 'should identify a math tag as a single token', -> + (expect @cut '

' + + 'π' + + '' + + 'r2

') + .eql [ + '

', + '' + + 'π' + + '' + + 'r2', + '

'] + + it 'should identify an svg tag as a single token', -> + (expect @cut '

' + + '' + + '

') + .eql [ + '

', + '' + + '' + + '', + '

'] diff --git a/test/render_operations.spec.coffee b/test/render_operations.spec.coffee index a233315..179889a 100644 --- a/test/render_operations.spec.coffee +++ b/test/render_operations.spec.coffee @@ -63,3 +63,30 @@ describe 'render_operations', -> it 'should keep the change inside the

', -> (expect @res).to.equal '

thisI is awesome

' + + describe 'empty tokens', -> + it 'should not be wrapped', -> + before = ['text'] + after = ['text', ' '] + + @res = @cut before, after + + (expect @res).to.equal 'text' + + describe 'tags with attributes', -> + it 'should treat attribute changes as equal and output the after tag', -> + before = ['

', 'this', ' ', 'is', ' ', 'awesome', '

'] + after = ['

', 'this', ' ', 'is', ' ', 'awesome', '

'] + + @res = @cut before, after + + (expect @res).to.equal '

this is awesome

' + + it 'should show changes within tags with different attributes', -> + before = ['

', 'this', ' ', 'is', ' ', 'awesome', '

'] + after = ['

', 'that', ' ', 'is', ' ', 'awesome', '

'] + + @res = @cut before, after + + (expect @res).to.equal \ + '

thisthat is awesome

'