govspeak 6.5.8 → 6.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26ef4d3bfb3ed9dcf07d44a1428e815928a4fa1ee94f388de829bb999b3cd79c
4
- data.tar.gz: c2982f083911dcaf38a0883d48e9ca302a3b514b7bc05b99b827830c02db884d
3
+ metadata.gz: 14e93ed0928bdacce945ae5d1ea81d3bbc40508fcc1875c59e02297aed7f78e8
4
+ data.tar.gz: b6f7f01034081da748db3d02e81fe31f72f155f2921de02b6d07f65d04587e09
5
5
  SHA512:
6
- metadata.gz: f75532f9905ae86df812be38a837d60abe1007cad72e8d886c95019f2563734a9e136368b74c1d1499d41bc8c83b2c3a41f415128c93c7025c4f4aacb9765e6f
7
- data.tar.gz: e6ef52ca611f2b3e74e77a3330ddaf602385eb90685b3839c8bd28f4bdf06c21652c50cff4a85fc2b157e8e009e11c5ce9c7c439a92d5abdf78821725fbaba2c
6
+ metadata.gz: 00e6e768ecdc8ce782f849957370199bdbfde7a85973c83366590b09155395455f62be45e86bcf8864053070ecb3a9560645bef410e562121ef08acefe2bccac
7
+ data.tar.gz: dd68a811064c4e63a092b00ffef191db7f3221308eb84cf916304b8e2207522baea4e37226c09527c4dc25f618b74b2604b39fc96ac986dfbb8008e93454f8fb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## 6.7.0
2
+
3
+ * Update heading & docs [#206](https://github.com/alphagov/govspeak/pull/206)
4
+
5
+ ## 6.6.0
6
+
7
+ * Allow passed elements to be relaxed from sanitization [#203](https://github.com/alphagov/govspeak/pull/203)
8
+
9
+ ## 6.5.11
10
+
11
+ * Fix issue rendering $CTA blocks before $C (PR#202)
12
+
13
+ ## 6.5.10
14
+
15
+ * Be optimistic in versions of govuk_publishing_components and i18n allowed (PR#200)
16
+
17
+ ## 6.5.9
18
+
19
+ * Adjust footnote markup to accommodate multiple references (PR#198)
20
+
1
21
  ## 6.5.8
2
22
 
3
23
  * Customise footnote markup for accessibility (PR#192)
data/README.md CHANGED
@@ -65,7 +65,7 @@ creates an example box
65
65
 
66
66
  ## Highlights
67
67
 
68
- ### Advisory
68
+ ### Advisory (DEPRECATED: marked for removal. Use 'Information callouts' instead.)
69
69
 
70
70
  @This is a very important message or warning@
71
71
 
@@ -77,7 +77,7 @@ highlights the enclosed text in yellow
77
77
  </h3>
78
78
  ```
79
79
 
80
- ### Answer
80
+ ### Answer (DEPRECATED: marked for removal)
81
81
 
82
82
  {::highlight-answer}
83
83
  The VAT rate is *20%*
@@ -598,8 +598,8 @@ will output
598
598
  ```html
599
599
  <div id="contact_123" class="contact">
600
600
  <div class="content">
601
- <h3>Government Digital Service</h3>
602
601
  <div class="vcard contact-inner">
602
+ <p>Government Digital Service</p>
603
603
  <div class="email-url-number">
604
604
  <p class="email">
605
605
  <span class="type">Email</span>
data/lib/govspeak.rb CHANGED
@@ -53,6 +53,7 @@ module Govspeak
53
53
  @source = source ? source.dup : ""
54
54
 
55
55
  @images = options.delete(:images) || []
56
+ @allowed_elements = options.delete(:allowed_elements) || []
56
57
  @attachments = Array.wrap(options.delete(:attachments))
57
58
  @links = Array.wrap(options.delete(:links))
58
59
  @contacts = Array.wrap(options.delete(:contacts))
@@ -66,7 +67,7 @@ module Govspeak
66
67
  def to_html
67
68
  @to_html ||= begin
68
69
  html = if @options[:sanitize]
69
- HtmlSanitizer.new(kramdown_doc.to_html).sanitize
70
+ HtmlSanitizer.new(kramdown_doc.to_html).sanitize(allowed_elements: @allowed_elements)
70
71
  else
71
72
  kramdown_doc.to_html
72
73
  end
@@ -272,6 +273,10 @@ module Govspeak
272
273
  lines.join
273
274
  end
274
275
 
276
+ # More specific tags must be defined first. Those defined earlier have a
277
+ # higher precedence for being matched. For example $CTA must be defined
278
+ # before $C otherwise the first ($C)TA fill be matched to a contact tag.
279
+ wrap_with_div("call-to-action", "$CTA", Govspeak::Document)
275
280
  wrap_with_div("summary", "$!")
276
281
  wrap_with_div("form-download", "$D")
277
282
  wrap_with_div("contact", "$C")
@@ -279,7 +284,6 @@ module Govspeak
279
284
  wrap_with_div("information", "$I", Govspeak::Document)
280
285
  wrap_with_div("additional-information", "$AI")
281
286
  wrap_with_div("example", "$E", Govspeak::Document)
282
- wrap_with_div("call-to-action", "$CTA", Govspeak::Document)
283
287
 
284
288
  extension("address", surrounded_by("$A")) do |body|
285
289
  %(\n<div class="address"><div class="adr org fn"><p>\n#{body.sub("\n", '').gsub("\n", '<br />')}\n</p></div></div>\n)
@@ -40,18 +40,19 @@ class Govspeak::HtmlSanitizer
40
40
  @allowed_image_hosts = options[:allowed_image_hosts]
41
41
  end
42
42
 
43
- def sanitize
43
+ def sanitize(allowed_elements: [])
44
44
  transformers = [TableCellTextAlignWhitelister.new]
45
45
  if @allowed_image_hosts && @allowed_image_hosts.any?
46
46
  transformers << ImageSourceWhitelister.new(@allowed_image_hosts)
47
47
  end
48
- Sanitize.clean(@dirty_html, Sanitize::Config.merge(sanitize_config, transformers: transformers))
48
+
49
+ Sanitize.clean(@dirty_html, Sanitize::Config.merge(sanitize_config(allowed_elements: allowed_elements), transformers: transformers))
49
50
  end
50
51
 
51
- def sanitize_config
52
+ def sanitize_config(allowed_elements: [])
52
53
  Sanitize::Config.merge(
53
54
  Sanitize::Config::RELAXED,
54
- elements: Sanitize::Config::RELAXED[:elements] + %w[govspeak-embed-attachment govspeak-embed-attachment-link svg path],
55
+ elements: Sanitize::Config::RELAXED[:elements] + %w[govspeak-embed-attachment govspeak-embed-attachment-link svg path].concat(allowed_elements),
55
56
  attributes: {
56
57
  :all => Sanitize::Config::RELAXED[:attributes][:all] + %w[role aria-label],
57
58
  "a" => Sanitize::Config::RELAXED[:attributes]["a"] + [:data],
@@ -126,7 +126,8 @@ module Govspeak
126
126
  el.content = "[footnote #{footnote_number}]"
127
127
  end
128
128
  document.css("[role='doc-backlink']").map do |el|
129
- el.content = "[go to where this is referenced]"
129
+ backlink_number = " " + el.css("sup")[0].content if el.css("sup")[0].present?
130
+ el["aria-label"] = "go to where this is referenced#{backlink_number}"
130
131
  end
131
132
  end
132
133
 
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "6.5.8".freeze
2
+ VERSION = "6.7.0".freeze
3
3
  end
@@ -4,8 +4,8 @@
4
4
  %>
5
5
  <div id="contact_<%= contact.content_id %>" class="<%= ['contact', extra_class].flatten.join(' ') %>">
6
6
  <div class="content">
7
- <h3><%= contact.title %></h3>
8
7
  <div class="vcard contact-inner">
8
+ <p><%= contact.title %></p>
9
9
  <% contact.post_addresses.each do |address| %>
10
10
  <%= Govspeak::HCardPresenter.new(address).render %>
11
11
  <% end %>
@@ -62,8 +62,8 @@ class GovspeakContactsTest < Minitest::Test
62
62
  expected_html_output = %(
63
63
  <div id="contact_4f3383e4-48a2-4461-a41d-f85ea8b89ba0" class="contact postal-address">
64
64
  <div class="content">
65
- <h3>Government Digital Service</h3>
66
65
  <div class="vcard contact-inner">
66
+ <p>Government Digital Service</p>
67
67
  <p class="adr">
68
68
  <span class="street-address">125 Kingsway</span><br>
69
69
  <span class="locality">Holborn</span><br>
@@ -106,8 +106,8 @@ class GovspeakContactsTest < Minitest::Test
106
106
  expected_html_output = %(
107
107
  <div id="contact_4f3383e4-48a2-4461-a41d-f85ea8b89ba0" class="contact">
108
108
  <div class="content">
109
- <h3>Government Digital Service</h3>
110
109
  <div class="vcard contact-inner">
110
+ <p>Government Digital Service</p>
111
111
  <div class="email-url-number">
112
112
  <p class="email">
113
113
  <span class="type">Email</span>
@@ -11,21 +11,36 @@ class GovspeakFootnoteTest < Minitest::Test
11
11
 
12
12
  Footnotes can be added too[^2].
13
13
 
14
- [^2]: And then later defined too." do
15
- assert_html_output '
14
+ [^2]: And then later defined too.
15
+
16
+ This footnote has a reference number[^3].
17
+
18
+ And this footnote has the same reference number[^3].
19
+
20
+ [^3]: And then they both point here." do
21
+ assert_html_output(
22
+ %(
16
23
  <p>Footnotes can be added<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote">[footnote 1]</a></sup>.</p>
17
24
 
18
25
  <p>Footnotes can be added too<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote">[footnote 2]</a></sup>.</p>
19
26
 
27
+ <p>This footnote has a reference number<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote">[footnote 3]</a></sup>.</p>
28
+
29
+ <p>And this footnote has the same reference number<sup id="fnref:3:1" role="doc-noteref"><a href="#fn:3" class="footnote">[footnote 3]</a></sup>.</p>
30
+
20
31
  <div class="footnotes" role="doc-endnotes">
21
32
  <ol>
22
33
  <li id="fn:1" role="doc-endnote">
23
- <p>And then later defined. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">[go to where this is referenced]</a></p>
34
+ <p>And then later defined. <a href="#fnref:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a></p>
24
35
  </li>
25
36
  <li id="fn:2" role="doc-endnote">
26
- <p>And then later defined too. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">[go to where this is referenced]</a></p>
37
+ <p>And then later defined too. <a href="#fnref:2" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a></p>
38
+ </li>
39
+ <li id="fn:3" role="doc-endnote">
40
+ <p>And then they both point here. <a href="#fnref:3" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced">↩</a> <a href="#fnref:3:1" class="reversefootnote" role="doc-backlink" aria-label="go to where this is referenced 2">↩<sup>2</sup></a></p>
27
41
  </li>
28
42
  </ol>
29
- </div>'
43
+ </div>),
44
+ )
30
45
  end
31
46
  end
@@ -440,6 +440,25 @@ Teston
440
440
  </div>)
441
441
  end
442
442
 
443
+ test_given_govspeak "
444
+ $CTA
445
+ Click here to start the tool
446
+ $CTA
447
+
448
+ $C
449
+ Here is some text
450
+ $C
451
+ " do
452
+ assert_html_output %(
453
+ <div class="call-to-action">
454
+ <p>Click here to start the tool</p>
455
+ </div>
456
+
457
+ <div class="contact">
458
+ <p>Here is some text</p>
459
+ </div>)
460
+ end
461
+
443
462
  test_given_govspeak "
444
463
  [internal link](http://www.not-external.com)
445
464
 
@@ -647,6 +666,11 @@ Teston
647
666
  assert_equal "<script>doGoodThings();</script>", document.to_html.strip
648
667
  end
649
668
 
669
+ test "it can exclude stipulated elements from sanitization" do
670
+ document = Govspeak::Document.new("<uncommon-element>some content</uncommon-element>", allowed_elements: %w[uncommon-element])
671
+ assert_equal "<uncommon-element>some content</uncommon-element>", document.to_html.strip
672
+ end
673
+
650
674
  test "identifies a Govspeak document containing malicious HTML as invalid" do
651
675
  document = Govspeak::Document.new("<script>doBadThings();</script>")
652
676
  refute document.valid?
@@ -96,4 +96,10 @@ class HtmlSanitizerTest < Minitest::Test
96
96
  assert_equal "<table><thead><tr><th>thing</th></tr></thead><tbody><tr><td>thing</td></tr></tbody></table>", Govspeak::HtmlSanitizer.new(html).sanitize
97
97
  end
98
98
  end
99
+
100
+ test "excludes specified elements from sanitization" do
101
+ html = "<custom-allowed-element><p>text</p></custom-allowed-element>"
102
+ assert_equal "<p>text</p>", Govspeak::HtmlSanitizer.new(html).sanitize
103
+ assert_equal html, Govspeak::HtmlSanitizer.new(html).sanitize(allowed_elements: %w[custom-allowed-element])
104
+ end
99
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govspeak
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.5.8
4
+ version: 6.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-05 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -56,20 +56,14 @@ dependencies:
56
56
  requirements:
57
57
  - - ">="
58
58
  - !ruby/object:Gem::Version
59
- version: '23.0'
60
- - - "<"
61
- - !ruby/object:Gem::Version
62
- version: '23.4'
59
+ version: '23'
63
60
  type: :runtime
64
61
  prerelease: false
65
62
  version_requirements: !ruby/object:Gem::Requirement
66
63
  requirements:
67
64
  - - ">="
68
65
  - !ruby/object:Gem::Version
69
- version: '23.0'
70
- - - "<"
71
- - !ruby/object:Gem::Version
72
- version: '23.4'
66
+ version: '23'
73
67
  - !ruby/object:Gem::Dependency
74
68
  name: htmlentities
75
69
  requirement: !ruby/object:Gem::Requirement
@@ -88,14 +82,14 @@ dependencies:
88
82
  name: i18n
89
83
  requirement: !ruby/object:Gem::Requirement
90
84
  requirements:
91
- - - "~>"
85
+ - - ">="
92
86
  - !ruby/object:Gem::Version
93
87
  version: '0.7'
94
88
  type: :runtime
95
89
  prerelease: false
96
90
  version_requirements: !ruby/object:Gem::Requirement
97
91
  requirements:
98
- - - "~>"
92
+ - - ">="
99
93
  - !ruby/object:Gem::Version
100
94
  version: '0.7'
101
95
  - !ruby/object:Gem::Dependency
@@ -180,14 +174,14 @@ dependencies:
180
174
  requirements:
181
175
  - - "~>"
182
176
  - !ruby/object:Gem::Version
183
- version: 5.14.1
177
+ version: '5.14'
184
178
  type: :development
185
179
  prerelease: false
186
180
  version_requirements: !ruby/object:Gem::Requirement
187
181
  requirements:
188
182
  - - "~>"
189
183
  - !ruby/object:Gem::Version
190
- version: 5.14.1
184
+ version: '5.14'
191
185
  - !ruby/object:Gem::Dependency
192
186
  name: pry-byebug
193
187
  requirement: !ruby/object:Gem::Requirement