FIX: Show a correct diff when editing consecutive paragraphs (#8177)
This commit is contained in:
parent
694a5bf229
commit
7d2f5240d9
|
@ -12,7 +12,7 @@ class DiscourseDiff
|
|||
before_markdown = tokenize_line(CGI::escapeHTML(@before))
|
||||
after_markdown = tokenize_line(CGI::escapeHTML(@after))
|
||||
|
||||
@block_by_block_diff = ONPDiff.new(before_html, after_html).diff
|
||||
@block_by_block_diff = ONPDiff.new(before_html, after_html).paragraph_diff
|
||||
@line_by_line_diff = ONPDiff.new(before_markdown, after_markdown).short_diff
|
||||
end
|
||||
|
||||
|
|
|
@ -25,6 +25,10 @@ class ONPDiff
|
|||
@short_diff ||= build_short_edit_script(compose)
|
||||
end
|
||||
|
||||
def paragraph_diff
|
||||
@paragraph_diff ||= build_paragraph_edit_script(diff)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compose
|
||||
|
@ -156,4 +160,71 @@ class ONPDiff
|
|||
ses
|
||||
end
|
||||
|
||||
def build_paragraph_edit_script(ses)
|
||||
paragraph_ses = []
|
||||
i = 0
|
||||
while i < ses.size
|
||||
if ses[i][1] == :common
|
||||
paragraph_ses << ses[i]
|
||||
else
|
||||
if ses[i][1] == :add
|
||||
op_code = :add
|
||||
opposite_op_code = :delete
|
||||
else
|
||||
op_code = :delete
|
||||
opposite_op_code = :add
|
||||
end
|
||||
j = i + 1
|
||||
|
||||
while j < ses.size && ses[j][1] == op_code
|
||||
j += 1
|
||||
end
|
||||
|
||||
if j >= ses.size
|
||||
paragraph_ses = paragraph_ses.concat(ses[i..j])
|
||||
i = j
|
||||
else
|
||||
k = j
|
||||
j -= 1
|
||||
|
||||
while k < ses.size && ses[k][1] == opposite_op_code
|
||||
k += 1
|
||||
end
|
||||
k -= 1
|
||||
|
||||
num_before = j - i + 1
|
||||
num_after = k - j
|
||||
if num_after > 1
|
||||
if num_before > num_after
|
||||
i2 = i + num_before - num_after
|
||||
paragraph_ses = paragraph_ses.concat(ses[i..i2 - 1])
|
||||
i = i2
|
||||
elsif num_after > num_before
|
||||
k -= num_after - num_before
|
||||
end
|
||||
paragraph_ses = paragraph_ses.concat(pair_paragraphs(ses, i, j))
|
||||
else
|
||||
paragraph_ses = paragraph_ses.concat(ses[i..k])
|
||||
end
|
||||
i = k
|
||||
end
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
|
||||
paragraph_ses
|
||||
end
|
||||
|
||||
def pair_paragraphs(ses, i, j)
|
||||
pairs = []
|
||||
num_pairs = j - i + 1
|
||||
num_pairs.times do
|
||||
pairs << ses[i]
|
||||
pairs << ses[i + num_pairs]
|
||||
i += 1
|
||||
end
|
||||
|
||||
pairs
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -76,6 +76,13 @@ describe DiscourseDiff do
|
|||
expect(DiscourseDiff.new(before, after).side_by_side_html).to eq("<div class=\"revision-content\"><p>this is a paragraph</p></div><div class=\"revision-content\"><p>this is a <ins>great </ins>paragraph</p></div>")
|
||||
end
|
||||
|
||||
it "adds <ins> and <del> tags on consecutive paragraphs", :focus do
|
||||
before = "<p>this is one paragraph</p><p>here is yet another</p>"
|
||||
after = "<p>this is one great paragraph</p><p>here is another</p>"
|
||||
got = DiscourseDiff.new(before, after).side_by_side_html
|
||||
expect(got).to eq("<div class=\"revision-content\"><p>this is one paragraph</p><p>here is <del>yet </del>another</p></div><div class=\"revision-content\"><p>this is one <ins>great </ins>paragraph</p><p>here is another</p></div>")
|
||||
end
|
||||
|
||||
it "adds <del> tags around removed text on the left div" do
|
||||
before = "<p>this is a great paragraph</p>"
|
||||
after = "<p>this is a paragraph</p>"
|
||||
|
|
|
@ -39,4 +39,38 @@ describe ONPDiff do
|
|||
|
||||
end
|
||||
|
||||
describe "paragraph_diff" do
|
||||
|
||||
it "returns an empty array when there is no content to diff" do
|
||||
expect(ONPDiff.new("", "").paragraph_diff).to eq([])
|
||||
end
|
||||
|
||||
it "returns an array with the operation code for each element" do
|
||||
expect(ONPDiff.new("abc", "acd").paragraph_diff).to eq([["a", :common], ["b", :delete], ["c", :common], ["d", :add]])
|
||||
end
|
||||
|
||||
it "pairs as many elements as possible", :focus do
|
||||
expect(ONPDiff.new("abcd", "abef").paragraph_diff).to eq([
|
||||
["a", :common], ["b", :common],
|
||||
["e", :add], ["c", :delete],
|
||||
["f", :add], ["d", :delete]
|
||||
])
|
||||
|
||||
expect(ONPDiff.new("abcde", "abfg").paragraph_diff).to eq([
|
||||
["a", :common], ["b", :common],
|
||||
["c", :delete],
|
||||
["d", :delete], ["f", :add],
|
||||
["e", :delete], ["g", :add]
|
||||
])
|
||||
|
||||
expect(ONPDiff.new("abcd", "abefg").paragraph_diff).to eq([
|
||||
["a", :common], ["b", :common],
|
||||
["e", :add],
|
||||
["f", :add], ["c", :delete],
|
||||
["g", :add], ["d", :delete]
|
||||
])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue