From fd98a2d3053279bd4a848faa52a3ac676db10cbb Mon Sep 17 00:00:00 2001
From: erdgeist
tokens in regardless -- invalid nesting
that browsers silently repair by dropping the unmatched closing tag,
leaving everything downstream rendered inside an with nothing
left to close it. Same failure mode as the retired cacycle_diff.js,
different cause.
Tag tokens now render as a plain-text pilcrow with a tooltip naming
the actual tag, never as literal markup inside / Der Vortragsraum ist ab 19 Uhr geöffnet, der Zugang erfolgt über den Hinterhof. Der Vortragsraum ist ab 19 Uhr geöffnet, der Zugang erfolgt über den Hinterhof.. Applies to
both inline and side-by-side. Side-by-side's new panel flattening a
real paragraph break into a marker, rather than showing its own true
structure, is a known, accepted trade-off for now -- not the same
problem, and not fixed here.
---
lib/html_word_diff.rb | 36 +++++++++++++++++++++++++++++-------
test/models/page_test.rb | 18 ++++++++++++++++++
2 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/lib/html_word_diff.rb b/lib/html_word_diff.rb
index 1f28cf5..aa0cb86 100644
--- a/lib/html_word_diff.rb
+++ b/lib/html_word_diff.rb
@@ -1,4 +1,5 @@
require 'diff/lcs'
+require 'cgi'
module HtmlWordDiff
TOKEN_REGEXP = /<[^>]*>|[[:space:]]+|[[:alnum:]]+|[^[:space:][:alnum:]<>]/
@@ -10,11 +11,12 @@ module HtmlWordDiff
when '='
html << new_token
when '-'
- html << "#{old_token}"
+ html << wrap_removed(old_token)
when '+'
- html << "#{new_token}"
+ html << wrap_inserted(new_token)
when '!'
- html << "#{old_token}#{new_token}"
+ html << wrap_removed(old_token)
+ html << wrap_inserted(new_token)
end
end
html
@@ -29,12 +31,12 @@ module HtmlWordDiff
old_out << old_token
new_out << new_token
when '-'
- old_out << "#{old_token}"
+ old_out << wrap_removed(old_token)
when '+'
- new_out << "#{new_token}"
+ new_out << wrap_inserted(new_token)
when '!'
- old_out << "#{old_token}"
- new_out << "#{new_token}"
+ old_out << wrap_removed(old_token)
+ new_out << wrap_inserted(new_token)
end
end
[old_out, new_out]
@@ -49,4 +51,24 @@ module HtmlWordDiff
def self.tokenize(html)
html.to_s.scan(TOKEN_REGEXP)
end
+
+ def self.tag_token?(token)
+ token.to_s.match?(/\A<[^>]*>\z/)
+ end
+
+ def self.wrap_removed(token)
+ if tag_token?(token)
+ %(\u00b6)
+ else
+ "#{token}"
+ end
+ end
+
+ def self.wrap_inserted(token)
+ if tag_token?(token)
+ %(\u00b6)
+ else
+ "#{token}"
+ end
+ end
end
diff --git a/test/models/page_test.rb b/test/models/page_test.rb
index ac5691a..3868a53 100644
--- a/test/models/page_test.rb
+++ b/test/models/page_test.rb
@@ -210,4 +210,22 @@ class PageTest < ActiveSupport::TestCase
assert_match "Old", old_html
assert_match "New", new_html
end
+
+ test "diff_against handles an inserted paragraph split without corrupting the document" do
+ n = Node.root.children.create! :slug => "paragraph_split_test"
+ d = n.find_or_create_draft @user1
+ d.body = "