From a5c2cb75568501a15bb0bbdab94b24d18a7b1816 Mon Sep 17 00:00:00 2001 From: trichoplax Date: Sun, 2 Aug 2026 21:27:41 +0100 Subject: [PATCH 1/8] Ignore line ending changes manually rather than with Diffy's ignore_crlf --- app/views/post_history/_diff.html.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/post_history/_diff.html.erb b/app/views/post_history/_diff.html.erb index 77eb63d7b..2515e0c4e 100644 --- a/app/views/post_history/_diff.html.erb +++ b/app/views/post_history/_diff.html.erb @@ -1,7 +1,9 @@
<% if before.present? && after.present? %> <% if before.is_a?(String) && after.is_a?(String) %> - <% diff = Diffy::SplitDiff.new(before, after, format: :html, ignore_crlf: true) %> + <% before = before.encode(before.encoding, universal_newline: true).strip %> + <% after = after.encode(after.encoding, universal_newline: true).strip %> + <% diff = Diffy::SplitDiff.new(before, after, format: :html) %>
<%= raw(diff.left) %> From c6dbced57132aa6ebd1055c8c6788a986d7de560 Mon Sep 17 00:00:00 2001 From: trichoplax Date: Sun, 2 Aug 2026 21:28:07 +0100 Subject: [PATCH 2/8] Fix incorrect encoding option in test --- test/controllers/posts/update_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/posts/update_test.rb b/test/controllers/posts/update_test.rb index 88e512dbb..98c2c3891 100644 --- a/test/controllers/posts/update_test.rb +++ b/test/controllers/posts/update_test.rb @@ -77,7 +77,7 @@ class PostsControllerTest < ActionController::TestCase post = posts(:question_three) before_history = PostHistory.where(post: post).count bm = post.body_markdown - body_markdown_with_crlf = bm.encode(bm.encoding, normalize_newlines: true).split("\n").join("\r\n") + body_markdown_with_crlf = bm.encode(bm.encoding, universal_newline: true).split("\n").join("\r\n") patch :update, params: { id: post.id, post: { title: post.title, body_markdown: body_markdown_with_crlf, From e94c9480340be154bf1b1d1b815f23bf77ad732d Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 00:10:11 +0100 Subject: [PATCH 3/8] Add newline normalization concern to post and post history models --- app/models/concerns/line_ending_normalization.rb | 8 ++++++++ app/models/post.rb | 1 + app/models/post_history.rb | 8 +++----- app/views/post_history/_diff.html.erb | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 app/models/concerns/line_ending_normalization.rb diff --git a/app/models/concerns/line_ending_normalization.rb b/app/models/concerns/line_ending_normalization.rb new file mode 100644 index 000000000..45b8666d4 --- /dev/null +++ b/app/models/concerns/line_ending_normalization.rb @@ -0,0 +1,8 @@ +module LineEndingNormalization + extend ActiveSupport::Concern + + def normalize_newlines(text) + text.encode(text.encoding, universal_newline: true).strip + end + +end diff --git a/app/models/post.rb b/app/models/post.rb index 1d3012a9b..4e3518797 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,5 +1,6 @@ class Post < ApplicationRecord include CommunityRelated + include LineEndingNormalization include Lockable include PostValidations include SoftDeletable diff --git a/app/models/post_history.rb b/app/models/post_history.rb index 2190ac642..79d23ddd6 100644 --- a/app/models/post_history.rb +++ b/app/models/post_history.rb @@ -1,4 +1,5 @@ class PostHistory < ApplicationRecord + include LineEndingNormalization include PostRelated include EditsValidations @@ -11,11 +12,8 @@ class PostHistory < ApplicationRecord scope :of_type, ->(name) { joins(:post_history_type).where(post_history_types: { name: name }) } scope :on_undeleted, -> { joins(:post).where(posts: { deleted: false }) } - normalize_newlines = lambda { |text| - text.encode(text.encoding, universal_newline: true) - } - normalizes :before_state, with: normalize_newlines - normalizes :after_state, with: normalize_newlines + normalizes :before_state, with: :normalize_newlines + normalizes :after_state, with: :normalize_newlines def before_tags tags.where(post_history_tags: { relationship: 'before' }) diff --git a/app/views/post_history/_diff.html.erb b/app/views/post_history/_diff.html.erb index 2515e0c4e..c0f181021 100644 --- a/app/views/post_history/_diff.html.erb +++ b/app/views/post_history/_diff.html.erb @@ -1,8 +1,8 @@
<% if before.present? && after.present? %> <% if before.is_a?(String) && after.is_a?(String) %> - <% before = before.encode(before.encoding, universal_newline: true).strip %> - <% after = after.encode(after.encoding, universal_newline: true).strip %> + <% before = post.normalize_newlines(before) %> + <% after = post.normalize_newlines(after) %> <% diff = Diffy::SplitDiff.new(before, after, format: :html) %>
From 99fcec5b9eadd7d161618e56aa5d9e443cda6ed4 Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 00:20:21 +0100 Subject: [PATCH 4/8] Remove blank line for rubocop --- app/models/concerns/line_ending_normalization.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/concerns/line_ending_normalization.rb b/app/models/concerns/line_ending_normalization.rb index 45b8666d4..e3d2a80f4 100644 --- a/app/models/concerns/line_ending_normalization.rb +++ b/app/models/concerns/line_ending_normalization.rb @@ -4,5 +4,4 @@ module LineEndingNormalization def normalize_newlines(text) text.encode(text.encoding, universal_newline: true).strip end - end From 260e204bf972849010786ebc92142906f8b17a25 Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 00:23:25 +0100 Subject: [PATCH 5/8] Rename concern --- .../{line_ending_normalization.rb => post_normalizations.rb} | 2 +- app/models/post.rb | 2 +- app/models/post_history.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/models/concerns/{line_ending_normalization.rb => post_normalizations.rb} (81%) diff --git a/app/models/concerns/line_ending_normalization.rb b/app/models/concerns/post_normalizations.rb similarity index 81% rename from app/models/concerns/line_ending_normalization.rb rename to app/models/concerns/post_normalizations.rb index e3d2a80f4..9ac7d09d1 100644 --- a/app/models/concerns/line_ending_normalization.rb +++ b/app/models/concerns/post_normalizations.rb @@ -1,4 +1,4 @@ -module LineEndingNormalization +module PostNormalizations extend ActiveSupport::Concern def normalize_newlines(text) diff --git a/app/models/post.rb b/app/models/post.rb index 4e3518797..fa5bb9ba8 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,7 +1,7 @@ class Post < ApplicationRecord include CommunityRelated - include LineEndingNormalization include Lockable + include PostNormalizations include PostValidations include SoftDeletable include Timestamped diff --git a/app/models/post_history.rb b/app/models/post_history.rb index 79d23ddd6..afdcf7b23 100644 --- a/app/models/post_history.rb +++ b/app/models/post_history.rb @@ -1,5 +1,5 @@ class PostHistory < ApplicationRecord - include LineEndingNormalization + include PostNormalizations include PostRelated include EditsValidations From 78cd4698d2c5d43d0ee13ed0022c69ddb570494c Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 01:42:41 +0100 Subject: [PATCH 6/8] Fix concern to use class_methods do --- app/models/concerns/post_normalizations.rb | 10 ++++++++-- app/models/post_history.rb | 3 --- app/views/post_history/_diff.html.erb | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/models/concerns/post_normalizations.rb b/app/models/concerns/post_normalizations.rb index 9ac7d09d1..1f05d3220 100644 --- a/app/models/concerns/post_normalizations.rb +++ b/app/models/concerns/post_normalizations.rb @@ -1,7 +1,13 @@ module PostNormalizations extend ActiveSupport::Concern - def normalize_newlines(text) - text.encode(text.encoding, universal_newline: true).strip + included do + normalizes :before_state, :after_state, with: -> text { normalize_newlines(text) } + end + + class_methods do + def normalize_newlines(text) + text.encode(text.encoding, universal_newline: true).strip + end end end diff --git a/app/models/post_history.rb b/app/models/post_history.rb index afdcf7b23..311a91f66 100644 --- a/app/models/post_history.rb +++ b/app/models/post_history.rb @@ -12,9 +12,6 @@ class PostHistory < ApplicationRecord scope :of_type, ->(name) { joins(:post_history_type).where(post_history_types: { name: name }) } scope :on_undeleted, -> { joins(:post).where(posts: { deleted: false }) } - normalizes :before_state, with: :normalize_newlines - normalizes :after_state, with: :normalize_newlines - def before_tags tags.where(post_history_tags: { relationship: 'before' }) end diff --git a/app/views/post_history/_diff.html.erb b/app/views/post_history/_diff.html.erb index c0f181021..fa5b7944d 100644 --- a/app/views/post_history/_diff.html.erb +++ b/app/views/post_history/_diff.html.erb @@ -1,8 +1,8 @@
<% if before.present? && after.present? %> <% if before.is_a?(String) && after.is_a?(String) %> - <% before = post.normalize_newlines(before) %> - <% after = post.normalize_newlines(after) %> + <% before = Post.normalize_newlines(before) %> + <% after = Post.normalize_newlines(after) %> <% diff = Diffy::SplitDiff.new(before, after, format: :html) %>
From 7c74168392c8fc349d5ca6382d1e6c76c950bf33 Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 01:46:26 +0100 Subject: [PATCH 7/8] Make lambda compatible with rubocop --- app/models/concerns/post_normalizations.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/concerns/post_normalizations.rb b/app/models/concerns/post_normalizations.rb index 1f05d3220..aa44e79c2 100644 --- a/app/models/concerns/post_normalizations.rb +++ b/app/models/concerns/post_normalizations.rb @@ -2,7 +2,7 @@ module PostNormalizations extend ActiveSupport::Concern included do - normalizes :before_state, :after_state, with: -> text { normalize_newlines(text) } + normalizes :before_state, :after_state, with: ->(text) { normalize_newlines(text) } end class_methods do From 7498cdb912a25d52c8f43d6def06e31b1dc1243b Mon Sep 17 00:00:00 2001 From: trichoplax Date: Mon, 3 Aug 2026 01:53:50 +0100 Subject: [PATCH 8/8] Move post history specific normalizes back to that model --- app/models/concerns/post_normalizations.rb | 4 ---- app/models/post_history.rb | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/concerns/post_normalizations.rb b/app/models/concerns/post_normalizations.rb index aa44e79c2..2533a1a4a 100644 --- a/app/models/concerns/post_normalizations.rb +++ b/app/models/concerns/post_normalizations.rb @@ -1,10 +1,6 @@ module PostNormalizations extend ActiveSupport::Concern - included do - normalizes :before_state, :after_state, with: ->(text) { normalize_newlines(text) } - end - class_methods do def normalize_newlines(text) text.encode(text.encoding, universal_newline: true).strip diff --git a/app/models/post_history.rb b/app/models/post_history.rb index 311a91f66..5e6d25d33 100644 --- a/app/models/post_history.rb +++ b/app/models/post_history.rb @@ -12,6 +12,8 @@ class PostHistory < ApplicationRecord scope :of_type, ->(name) { joins(:post_history_type).where(post_history_types: { name: name }) } scope :on_undeleted, -> { joins(:post).where(posts: { deleted: false }) } + normalizes :before_state, :after_state, with: ->(text) { normalize_newlines(text) } + def before_tags tags.where(post_history_tags: { relationship: 'before' }) end