Class: Crm::ArticleRevisionDiffRowComponent::ContentDiff

Inherits:
Object
  • Object
show all
Includes:
ActionView::Helpers::SanitizeHelper
Defined in:
app/components/crm/article_revision_diff_row_component/content_diff.rb

Overview

Sanitizes and annotates the rendered content for one comparison row.

Constant Summary collapse

INPUT_ALLOWED_TAGS =

Tags allowed in rich-text input before diffing (safe list plus tables).

(
  Rails::HTML5::SafeListSanitizer.allowed_tags + %w[table thead tbody tfoot tr th td]
).freeze
INPUT_ALLOWED_ATTRIBUTES =

Attributes allowed in rich-text input before diffing.

(
  Rails::HTML5::SafeListSanitizer.allowed_attributes + %w[colspan rowspan align]
).freeze
OUTPUT_ALLOWED_TAGS =

Tags allowed in rendered diff output (input tags plus diff markers).

(INPUT_ALLOWED_TAGS + %w[del ins]).freeze
OUTPUT_ALLOWED_ATTRIBUTES =

Attributes allowed in rendered diff output (input attributes plus class).

(INPUT_ALLOWED_ATTRIBUTES + %w[class]).freeze

Delegated Instance Attributes collapse

Instance Method Summary collapse

Constructor Details

#initialize(current:, proposed:, rich_text:) ⇒ ContentDiff

Returns a new instance of ContentDiff.

Parameters:

  • current (Object)

    the current (existing) value for the row

  • proposed (Object)

    the proposed (incoming) value for the row

  • rich_text (Boolean)

    whether the values hold rich-text HTML



26
27
28
29
30
# File 'app/components/crm/article_revision_diff_row_component/content_diff.rb', line 26

def initialize(current:, proposed:, rich_text:)
  @current = current
  @proposed = proposed
  @rich_text = rich_text
end

Instance Method Details

#coarse?Boolean

Whether the token diff fell back to coarse (line-level) comparison.

Returns:

  • (Boolean)


58
# File 'app/components/crm/article_revision_diff_row_component/content_diff.rb', line 58

delegate :coarse?, to: :token_diff

#formatting_only_change?Boolean

Whether the values differ only in formatting, with identical text.

Returns:

  • (Boolean)

    true when rich text differs but every diff change is equal



51
52
53
# File 'app/components/crm/article_revision_diff_row_component/content_diff.rb', line 51

def formatting_only_change?
  rich_text && current.to_s != proposed.to_s && diff_changes.all? { |change| change.first == "=" }
end

#html(side) ⇒ String

Renders one side of the diff with changed segments wrapped in
+del+/+ins+ markers, sanitized against the output allow-list.

Parameters:

  • side (Symbol)

    which side to render, +:current+ or +:proposed+

Returns:

  • (String)

    sanitized HTML for the requested side



37
38
39
40
41
42
43
44
45
46
# File 'app/components/crm/article_revision_diff_row_component/content_diff.rb', line 37

def html(side)
  fragment = fragment_for(side)
  Crm::ArticleRevisionDiffRowComponent::FragmentMarker.new(
    fragment:,
    segments: segments_for(side),
    element: side == :current ? :del : :ins,
    css_class: "article-revision-diff-#{side == :current ? 'removed' : 'added'}"
  ).call
  sanitize(fragment.to_html, tags: OUTPUT_ALLOWED_TAGS, attributes: OUTPUT_ALLOWED_ATTRIBUTES)
end