diff --git a/app/assets/stylesheets/legislation_process.scss b/app/assets/stylesheets/legislation_process.scss index c605af7e7..a18266d97 100644 --- a/app/assets/stylesheets/legislation_process.scss +++ b/app/assets/stylesheets/legislation_process.scss @@ -459,6 +459,10 @@ padding: rem-calc(32) rem-calc(32) rem-calc(32) rem-calc(48); } + table { + @include table-scroll; + } + h2 { font-weight: 400; margin-bottom: rem-calc(32); diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a0ff6f621..3b2b25315 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -13,7 +13,6 @@ module ApplicationHelper def markdown(text) return text if text.blank? - # See https://github.com/vmg/redcarpet for options render_options = { filter_html: false, hard_wrap: true, diff --git a/app/models/legislation/draft_version.rb b/app/models/legislation/draft_version.rb index c7576c421..7dd36dfa0 100644 --- a/app/models/legislation/draft_version.rb +++ b/app/models/legislation/draft_version.rb @@ -22,9 +22,15 @@ class Legislation::DraftVersion < ApplicationRecord scope :published, -> { where(status: "published").order("id DESC") } def body_html - renderer = Redcarpet::Render::HTML.new(with_toc_data: true) + render_options = { + with_toc_data: true + } + renderer = Redcarpet::Render::HTML.new(render_options) + extensions = { + tables: true + } - Redcarpet::Markdown.new(renderer).render(body) + Redcarpet::Markdown.new(renderer, extensions).render(body) end def toc_html diff --git a/lib/admin_legislation_sanitizer.rb b/lib/admin_legislation_sanitizer.rb index 103b305b6..358de0199 100644 --- a/lib/admin_legislation_sanitizer.rb +++ b/lib/admin_legislation_sanitizer.rb @@ -1,6 +1,6 @@ class AdminLegislationSanitizer < WYSIWYGSanitizer def allowed_tags - super + %w[img h1 h4 h5 h6] + super + %w[img h1 h4 h5 h6 table thead tbody tr th td] end def allowed_attributes diff --git a/spec/factories/legislations.rb b/spec/factories/legislations.rb index 069899884..3c1dbe41b 100644 --- a/spec/factories/legislations.rb +++ b/spec/factories/legislations.rb @@ -127,6 +127,15 @@ FactoryBot.define do trait :final_version do final_version { true } end + + trait :with_table do + body { <<~BODY_MARKDOWN } + | id | name | age | gender | + |----|---------|-----|--------| + | 1 | Roberta | 39 | M | + | 2 | Oliver | 25 | F | + BODY_MARKDOWN + end end factory :legislation_annotation, class: "Legislation::Annotation" do diff --git a/spec/lib/admin_legislation_sanitizer_spec.rb b/spec/lib/admin_legislation_sanitizer_spec.rb new file mode 100644 index 000000000..bc467ba84 --- /dev/null +++ b/spec/lib/admin_legislation_sanitizer_spec.rb @@ -0,0 +1,65 @@ +require "rails_helper" + +describe AdminLegislationSanitizer do + let(:sanitizer) { AdminLegislationSanitizer.new } + + describe "#sanitize" do + it "allows images" do + html = 'DangerousSmile image' + expect(sanitizer.sanitize(html)).to eq(html) + end + + it "allows h1 to h6" do + html = '

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
' + expect(sanitizer.sanitize(html)).to eq(html) + end + + it "allows tables" do + html = ' + + + + + + + + + + + + + + + + + + + + + + +
idnameagegender
1Roberta39M
2Oliver25F
' + expect(sanitizer.sanitize(html)).to eq(html) + end + + it "allows alt src and id" do + html = 'DangerousSmile image' + expect(sanitizer.sanitize(html)).to eq(html) + end + + it "doesn't allow style" do + html = 'DangerousSmile image' + expect(sanitizer.sanitize(html)).not_to eq(html) + end + + it "doesn't allow class" do + html = 'DangerousSmile image' + expect(sanitizer.sanitize(html)).not_to eq(html) + end + end +end diff --git a/spec/models/legislation/draft_version_spec.rb b/spec/models/legislation/draft_version_spec.rb index 910a15f65..59e29d67f 100644 --- a/spec/models/legislation/draft_version_spec.rb +++ b/spec/models/legislation/draft_version_spec.rb @@ -29,6 +29,15 @@ describe Legislation::DraftVersion do expect(legislation_draft_version.toc_html).to eq(toc_html) end + it "renders the tables from the markdown body field" do + legislation_draft_version.body = body_with_table_markdown + + legislation_draft_version.save! + + expect(legislation_draft_version.body_html).to eq(body_with_table_html) + expect(legislation_draft_version.toc_html).to eq(toc_html) + end + def body_markdown <<~BODY_MARKDOWN # Title 1 @@ -50,6 +59,32 @@ describe Legislation::DraftVersion do BODY_MARKDOWN end + def body_with_table_markdown + <<~BODY_MARKDOWN + # Title 1 + + Some paragraph. + + A list: + + - item 1 + - item 2 + + ## Subtitle + + Another paragraph. + + # Title 2 + + Something about this. + + | id | name | age | gender | + |----|---------|-----|--------| + | 1 | Roberta | 39 | M | + | 2 | Oliver | 25 | F | + BODY_MARKDOWN + end + def body_html <<~BODY_HTML

Title 1

@@ -73,6 +108,51 @@ describe Legislation::DraftVersion do BODY_HTML end + def body_with_table_html + <<~BODY_HTML +

Title 1

+ +

Some paragraph.

+ +

A list:

+ + + +

Subtitle

+ +

Another paragraph.

+ +

Title 2

+ +

Something about this.

+ + + + + + + + + + + + + + + + + + + + + +
idnameagegender
1Roberta39M
2Oliver25F
+ BODY_HTML + end + def toc_html <<~TOC_HTML