govspeak 5.1.0 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebdbbfa89f69d8876bdd0728e13474e97f43eb88
4
- data.tar.gz: 757ccbe46be1e4f503251b349e97a39985091733
3
+ metadata.gz: a4a6fee8680d3b04ed7c86d26efcfdd73fa58f5b
4
+ data.tar.gz: f3102b0907209a598118940cf7fc1b81258be172
5
5
  SHA512:
6
- metadata.gz: b8edf0d8658ada877429cf8b8747b205a4734f697bc3a9c5bec444edee15a334f9ae92faf4029344646483f3fba05174be6b2c4d13225ef037b965ad8652f521
7
- data.tar.gz: bd9cea16633290ef7a5eb6d7b4c4d05430d28cb09c8be44fbe8dbee0c17f939e44cee3f92c6b558432e991db5424f6f9a9081131302aad7bd100e340f546264e
6
+ metadata.gz: 62b7674a6488a733859c07147734a663a9e0217d9ee7527a1d79cf9d8f04d0bfc50cb3c3d57736e3e87bcd2547a481d31cd5f91e6c923f134c7932a46a7fdd8b
7
+ data.tar.gz: 56c16ff2616269cd93089a480fa373ba6b6251f66cda4f725e354359a6d7d8141f604e7765304425bd93ff9d0ed6df4fcc5fd6a3bc90bdb6053dd81b9aa73682
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 5.2.0
2
+ * Add button component for govspeak [#114](https://github.com/alphagov/govspeak/pull/114) see README for usage
3
+
1
4
  ## 5.1.0
2
5
  * Update Kramdown version to 1.15.0
3
6
 
data/README.md CHANGED
@@ -525,3 +525,65 @@ will output
525
525
  </div>
526
526
  </div>
527
527
  ```
528
+
529
+ ### Button
530
+
531
+ An accessible way to add button links into content, that can also allow cross domain tracking with [Google Analytics](https://support.google.com/analytics/answer/7372977?hl=en)
532
+
533
+ This button component is [extended from static](http://govuk-static.herokuapp.com/component-guide/button) for [use in govspeak](http://govuk-static.herokuapp.com/component-guide/govspeak/button)
534
+ Note: Ideally we'd use the original component directly but this currently isnt possible
535
+
536
+ You must use the [link](https://daringfireball.net/projects/markdown/syntax#link) syntax within the button tags.
537
+
538
+ #### Examples
539
+
540
+ To get the most basic button.
541
+
542
+ ```
543
+ {button}[Continue](https://gov.uk/random){/button}
544
+ ```
545
+
546
+ which outputs
547
+
548
+ ```html
549
+ <a role="button" class="button" href="https://gov.uk/random">
550
+ Continue
551
+ </a>
552
+ ```
553
+
554
+ To turn a button into a ['Start now' button](https://www.gov.uk/service-manual/design/start-pages#start-page-elements), you can pass `start` to the button tag.
555
+
556
+ ```
557
+ {button start}[Start Now](https://gov.uk/random){/button}
558
+ ```
559
+
560
+ which outputs
561
+
562
+ ```html
563
+ <a role="button" class="button button-start" href="https://gov.uk/random">
564
+ Start Now
565
+ </a>
566
+ ```
567
+
568
+ You can pass a Google Analytics [tracking id](https://support.google.com/analytics/answer/7372977?hl=en) which will send page views to another domain, this is used to help services understand the start of their users journeys.
569
+
570
+ ```
571
+ {button start cross-domain-tracking:UA-XXXXXX-Y}
572
+ [Start Now](https://example.com/external-service/start-now)
573
+ {/button}
574
+ ```
575
+
576
+ which outputs
577
+
578
+ ```html
579
+ <a
580
+ role="button"
581
+ class="button button-start"
582
+ href="https://example.com/external-service/start-now"
583
+ data-module="cross-domain-tracking"
584
+ data-tracking-code="UA-XXXXXX-Y"
585
+ data-tracking-name="govspeakButtonTracker"
586
+ >
587
+ Start Now
588
+ </a>
589
+ ```
data/lib/govspeak.rb CHANGED
@@ -135,6 +135,33 @@ module Govspeak
135
135
  parser.new(body.strip).to_html.sub(/^<p>(.*)<\/p>$/,"<p><strong>\\1</strong></p>")
136
136
  end
137
137
 
138
+ extension('button', %r{
139
+ {button(.*?)} # match opening bracket and capture attributes
140
+ \s* # any whitespace between opening bracket and link
141
+ \[ # match start of link markdown
142
+ ([^\]]+) # capture inside of link markdown
143
+ \] # match end of link markdown
144
+ \( # match start of link text markdown
145
+ ([^)]+) # capture inside of link text markdown
146
+ \) # match end of link text markdown
147
+ \s* # any whitespace between opening bracket and link
148
+ {\/button} # match ending bracket
149
+ }x) { |attributes, text, href|
150
+ button_classes = "button"
151
+ button_classes << " button-start" if attributes =~ /start/
152
+ /cross-domain-tracking:(?<cross_domain_tracking>.[^\s*]+)/ =~ attributes
153
+ data_attribute = ""
154
+ if cross_domain_tracking
155
+ data_attribute << " data-module='cross-domain-tracking'"
156
+ data_attribute << " data-tracking-code='#{cross_domain_tracking.strip}'"
157
+ data_attribute << " data-tracking-name='govspeakButtonTracker'"
158
+ end
159
+ text = text.strip
160
+ href = href.strip
161
+
162
+ %{\n<a role="button" class="#{button_classes}" href="#{href}" #{data_attribute}>#{text}</a>\n}
163
+ }
164
+
138
165
  extension('highlight-answer') { |body|
139
166
  %{\n\n<div class="highlight-answer">
140
167
  #{Govspeak::Document.new(body.strip).to_html}</div>\n}
@@ -57,11 +57,19 @@ class Govspeak::HtmlSanitizer
57
57
  Sanitize.clean(@dirty_html, config)
58
58
  end
59
59
 
60
+ def button_sanitize_config
61
+ [
62
+ "data-module='cross-domain-tracking'",
63
+ "data-tracking-code",
64
+ "data-tracking-name"
65
+ ]
66
+ end
67
+
60
68
  def sanitize_config
61
69
  deep_merge(Sanitize::Config::RELAXED, {
62
70
  attributes: {
63
71
  :all => Sanitize::Config::RELAXED[:attributes][:all] + [ "id", "class", "role", "aria-label" ],
64
- "a" => Sanitize::Config::RELAXED[:attributes]["a"] + [ "rel" ],
72
+ "a" => Sanitize::Config::RELAXED[:attributes]["a"] + ["rel"] + button_sanitize_config,
65
73
  "th" => Sanitize::Config::RELAXED[:attributes]["th"] + [ "style" ],
66
74
  "td" => Sanitize::Config::RELAXED[:attributes]["td"] + [ "style" ],
67
75
  },
@@ -1,3 +1,3 @@
1
1
  module Govspeak
2
- VERSION = "5.1.0".freeze
2
+ VERSION = "5.2.0".freeze
3
3
  end
@@ -0,0 +1,85 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+ require 'govspeak_test_helper'
5
+
6
+ require 'ostruct'
7
+
8
+ class GovspeakTest < Minitest::Test
9
+ include GovspeakTestHelper
10
+
11
+ test_given_govspeak "{button start cross-domain-tracking:UA-23066786-5}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
12
+ assert_html_output '<p><a role="button" class="button button-start" href="https://www.registertovote.service.gov.uk/register-to-vote/start" data-module="cross-domain-tracking" data-tracking-code="UA-23066786-5" data-tracking-name="govspeakButtonTracker">Start now</a></p>'
13
+ assert_text_output "Start now"
14
+ end
15
+
16
+ # The same as above but with line breaks
17
+ test_given_govspeak "{button start cross-domain-tracking:UA-23066786-5}\n\n\n[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start)\n\n\n{/button}" do
18
+ assert_html_output '<p><a role="button" class="button button-start" href="https://www.registertovote.service.gov.uk/register-to-vote/start" data-module="cross-domain-tracking" data-tracking-code="UA-23066786-5" data-tracking-name="govspeakButtonTracker">Start now</a></p>'
19
+ assert_text_output "Start now"
20
+ end
21
+
22
+ test_given_govspeak "{button cross-domain-tracking:UA-23066786-5}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
23
+ assert_html_output '<p><a role="button" class="button" href="https://www.registertovote.service.gov.uk/register-to-vote/start" data-module="cross-domain-tracking" data-tracking-code="UA-23066786-5" data-tracking-name="govspeakButtonTracker">Start now</a></p>'
24
+ assert_text_output "Start now"
25
+ end
26
+
27
+ test_given_govspeak "{button start}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
28
+ assert_html_output '<p><a role="button" class="button button-start" href="https://www.registertovote.service.gov.uk/register-to-vote/start">Start now</a></p>'
29
+ assert_text_output "Start now"
30
+ end
31
+
32
+ test_given_govspeak "{button}[Start now](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
33
+ assert_html_output '<p><a role="button" class="button" href="https://www.registertovote.service.gov.uk/register-to-vote/start">Start now</a></p>'
34
+ assert_text_output "Start now"
35
+ end
36
+
37
+ # Test other text outputs
38
+ test_given_govspeak "{button}[Something else](https://www.registertovote.service.gov.uk/register-to-vote/start){/button}" do
39
+ assert_html_output '<p><a role="button" class="button" href="https://www.registertovote.service.gov.uk/register-to-vote/start">Something else</a></p>'
40
+ assert_text_output "Something else"
41
+ end
42
+
43
+ # Test that nothing renders when not given a link
44
+ test_given_govspeak "{button}I shouldn't render a button{/button}" do
45
+ assert_html_output '<p>{button}I shouldn’t render a button{/button}</p>'
46
+ end
47
+
48
+ test_given_govspeak "Text before the button {button}[Start Now](http://www.gov.uk){/button} test after the button" do
49
+ # rubocop:disable Layout/TrailingWhitespace
50
+ assert_html_output %{
51
+ <p>Text before the button
52
+ <a role="button" class="button" href="http://www.gov.uk">Start Now</a>
53
+ test after the button</p>
54
+ }
55
+ # rubocop:enable Layout/TrailingWhitespace
56
+ assert_text_output "Text before the button Start Now test after the button"
57
+ end
58
+
59
+ test_given_govspeak "Text before the button with line breaks \n\n\n{button}[Start Now](http://www.gov.uk){/button}\n\n\n test after the button" do
60
+ assert_html_output %{
61
+ <p>Text before the button with line breaks</p>
62
+
63
+ <p><a role="button" class="button" href="http://www.gov.uk">Start Now</a></p>
64
+
65
+ <p>test after the button</p>
66
+ }
67
+ assert_text_output "Text before the button with line breaks Start Now test after the button"
68
+ end
69
+
70
+ # Test README examples
71
+ test_given_govspeak "{button}[Continue](https://gov.uk/random){/button}" do
72
+ assert_html_output '<p><a role="button" class="button" href="https://gov.uk/random">Continue</a></p>'
73
+ assert_text_output "Continue"
74
+ end
75
+
76
+ test_given_govspeak "{button start}[Start Now](https://gov.uk/random){/button}" do
77
+ assert_html_output '<p><a role="button" class="button button-start" href="https://gov.uk/random">Start Now</a></p>'
78
+ assert_text_output "Start Now"
79
+ end
80
+
81
+ test_given_govspeak "{button start cross-domain-tracking:UA-XXXXXX-Y}[Start Now](https://example.com/external-service/start-now){/button}" do
82
+ assert_html_output '<p><a role="button" class="button button-start" href="https://example.com/external-service/start-now" data-module="cross-domain-tracking" data-tracking-code="UA-XXXXXX-Y" data-tracking-name="govspeakButtonTracker">Start Now</a></p>'
83
+ assert_text_output "Start Now"
84
+ end
85
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: govspeak
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Griffiths
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-27 00:00:00.000000000 Z
12
+ date: 2017-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: kramdown
@@ -285,6 +285,7 @@ files:
285
285
  - test/govspeak_attachments_image_test.rb
286
286
  - test/govspeak_attachments_inline_test.rb
287
287
  - test/govspeak_attachments_test.rb
288
+ - test/govspeak_button_test.rb
288
289
  - test/govspeak_contacts_test.rb
289
290
  - test/govspeak_link_test.rb
290
291
  - test/govspeak_structured_headers_test.rb
@@ -319,17 +320,18 @@ signing_key:
319
320
  specification_version: 4
320
321
  summary: Markup language for single domain
321
322
  test_files:
323
+ - test/blockquote_extra_quote_remover_test.rb
324
+ - test/govspeak_test_helper.rb
325
+ - test/govspeak_structured_headers_test.rb
326
+ - test/govspeak_attachments_image_test.rb
322
327
  - test/govspeak_attachments_test.rb
323
- - test/govspeak_attachments_inline_test.rb
324
- - test/govspeak_link_test.rb
325
- - test/govspeak_contacts_test.rb
326
328
  - test/test_helper.rb
327
- - test/govspeak_test.rb
328
- - test/govspeak_attachments_image_test.rb
329
+ - test/govspeak_attachments_inline_test.rb
330
+ - test/html_sanitizer_test.rb
331
+ - test/govspeak_button_test.rb
329
332
  - test/with_deep_merge_test.rb
330
333
  - test/html_validator_test.rb
331
- - test/govspeak_structured_headers_test.rb
332
- - test/blockquote_extra_quote_remover_test.rb
334
+ - test/govspeak_test.rb
335
+ - test/govspeak_link_test.rb
336
+ - test/govspeak_contacts_test.rb
333
337
  - test/presenters/h_card_presenter_test.rb
334
- - test/govspeak_test_helper.rb
335
- - test/html_sanitizer_test.rb