govuk_publishing_components 21.69.0 → 23.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics.js +16 -0
  3. data/app/assets/javascripts/govuk_publishing_components/analytics/analytics.js +85 -0
  4. data/app/assets/javascripts/govuk_publishing_components/analytics/auto-track-event.js +30 -0
  5. data/app/assets/javascripts/govuk_publishing_components/analytics/custom-dimensions.js +120 -0
  6. data/app/assets/javascripts/govuk_publishing_components/analytics/download-link-tracker.js +41 -0
  7. data/app/assets/javascripts/govuk_publishing_components/analytics/ecommerce.js +101 -0
  8. data/app/assets/javascripts/govuk_publishing_components/analytics/error-tracking.js +51 -0
  9. data/app/assets/javascripts/govuk_publishing_components/analytics/external-link-tracker.js +56 -0
  10. data/app/assets/javascripts/govuk_publishing_components/analytics/google-analytics-universal-tracker.js +198 -0
  11. data/app/assets/javascripts/govuk_publishing_components/analytics/init.js.erb +50 -0
  12. data/app/assets/javascripts/govuk_publishing_components/analytics/mailto-link-tracker.js +38 -0
  13. data/app/assets/javascripts/govuk_publishing_components/analytics/page-content.js +129 -0
  14. data/app/assets/javascripts/govuk_publishing_components/analytics/pii.js +74 -0
  15. data/app/assets/javascripts/govuk_publishing_components/analytics/print-intent.js +39 -0
  16. data/app/assets/javascripts/govuk_publishing_components/analytics/scroll-tracker.js +513 -0
  17. data/app/assets/javascripts/govuk_publishing_components/analytics/static-analytics.js +132 -0
  18. data/app/assets/javascripts/govuk_publishing_components/lib/track-click.js +61 -0
  19. data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +4 -10
  20. data/app/views/govuk_publishing_components/components/_contents_list.html.erb +8 -13
  21. data/app/views/govuk_publishing_components/components/_govspeak.html.erb +8 -12
  22. data/app/views/govuk_publishing_components/components/_input.html.erb +17 -4
  23. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +0 -1
  24. data/app/views/govuk_publishing_components/components/_layout_header.html.erb +6 -5
  25. data/app/views/govuk_publishing_components/components/_panel.html.erb +5 -2
  26. data/app/views/govuk_publishing_components/components/docs/contents_list.yml +0 -37
  27. data/app/views/govuk_publishing_components/components/docs/govspeak.yml +1 -6
  28. data/app/views/govuk_publishing_components/components/docs/input.yml +7 -3
  29. data/app/views/govuk_publishing_components/components/docs/layout_header.yml +0 -3
  30. data/app/views/govuk_publishing_components/components/docs/panel.yml +4 -0
  31. data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +3 -1
  32. data/config/initializers/assets.rb +1 -0
  33. data/config/locales/et.yml +4 -0
  34. data/config/locales/fr.yml +4 -0
  35. data/lib/govuk_publishing_components/version.rb +1 -1
  36. metadata +21 -2
@@ -0,0 +1,132 @@
1
+ /* global GOVUK, $, ga */
2
+
3
+ (function () {
4
+ 'use strict'
5
+ window.GOVUK = window.GOVUK || {}
6
+ var StaticAnalytics = function (config) {
7
+ // Create universal tracker
8
+ // https://github.com/alphagov/govuk_frontend_toolkit/blob/master/docs/analytics.md
9
+ // https://github.com/alphagov/govuk_frontend_toolkit/blob/master/javascripts/govuk/analytics/analytics.js
10
+ var consentCookie = window.GOVUK.getConsentCookie()
11
+
12
+ if (!consentCookie || consentCookie.usage) {
13
+ this.analytics = new GOVUK.Analytics(config)
14
+ }
15
+
16
+ var trackingOptions = getOptionsFromCookie()
17
+
18
+ // We're setting the client ID inside a callback function because
19
+ // we don't have access to the client ID until GA returns a tracker object.
20
+ ga(function (tracker) {
21
+ this.gaClientId = tracker.get('clientId')
22
+
23
+ $(window).trigger('gaClientSet')
24
+
25
+ // Start up ecommerce tracking
26
+ GOVUK.Ecommerce.start()
27
+
28
+ // Track initial pageview
29
+ this.trackPageview(null, null, trackingOptions)
30
+
31
+ // Begin error and print tracking
32
+ GOVUK.analyticsPlugins.error({ filenameMustMatch: /gov\.uk/ })
33
+ GOVUK.analyticsPlugins.printIntent()
34
+ GOVUK.analyticsPlugins.mailtoLinkTracker()
35
+ GOVUK.analyticsPlugins.externalLinkTracker({
36
+ externalLinkUploadCustomDimension: 36
37
+ })
38
+ GOVUK.analyticsPlugins.downloadLinkTracker({
39
+ selector: 'a[href*="/government/uploads"], a[href*="assets.publishing.service.gov.uk"]'
40
+ })
41
+ }.bind(this))
42
+ }
43
+
44
+ StaticAnalytics.load = function () {
45
+ GOVUK.Analytics.load()
46
+ }
47
+
48
+ StaticAnalytics.prototype.trackPageview = function (path, title, options) {
49
+ // Add the cookie banner status as a custom dimension
50
+ var cookieBannerShown = !this.getCookie('seen_cookie_message')
51
+ var cookieBannerDimension = { dimension100: cookieBannerShown ? cookieBannerShown.toString() : 'false' }
52
+ $.extend(options, cookieBannerDimension)
53
+
54
+ var trackingOptions = GOVUK.CustomDimensions.getAndExtendDefaultTrackingOptions(options)
55
+ this.analytics.trackPageview(path, title, trackingOptions)
56
+ }
57
+
58
+ StaticAnalytics.prototype.trackEvent = function (category, action, options) {
59
+ var trackingOptions = GOVUK.CustomDimensions.getAndExtendDefaultTrackingOptions(options)
60
+ this.analytics.trackEvent(category, action, trackingOptions)
61
+ }
62
+
63
+ StaticAnalytics.prototype.setDimension = function (index, value, name, scope) {
64
+ if (typeof value === 'undefined') {
65
+ return
66
+ }
67
+ this.analytics.setDimension(index, value, name, scope)
68
+ }
69
+
70
+ StaticAnalytics.prototype.trackShare = function (network) {
71
+ var trackingOptions = GOVUK.CustomDimensions.getAndExtendDefaultTrackingOptions()
72
+ this.analytics.trackShare(network, trackingOptions)
73
+ }
74
+
75
+ StaticAnalytics.prototype.addLinkedTrackerDomain = function (trackerId, name, domain, sendPageView) {
76
+ this.analytics.addLinkedTrackerDomain(trackerId, name, domain, sendPageView)
77
+ }
78
+
79
+ StaticAnalytics.prototype.setOptionsForNextPageview = function (options) {
80
+ if (typeof options !== 'object') {
81
+ return
82
+ }
83
+
84
+ var cookieOptions = getOptionsFromCookie()
85
+
86
+ $.extend(cookieOptions, options)
87
+
88
+ this.setCookie('analytics_next_page_call', cookieOptions)
89
+ }
90
+
91
+ StaticAnalytics.prototype.setCookie = function (cookieName, object) {
92
+ if (!GOVUK.cookie) {
93
+ return
94
+ }
95
+
96
+ if (!object) {
97
+ GOVUK.cookie(cookieName, null)
98
+ } else {
99
+ // Singly-stringified JSON sometimes gets escaped when put into a cookie, but inconsistently. The command-line
100
+ // tests will escape, but browser tests will not. Double-stringify in order to get consistently-escaped strings.
101
+ GOVUK.cookie(cookieName, JSON.stringify(JSON.stringify(object)))
102
+ }
103
+ }
104
+
105
+ StaticAnalytics.prototype.getCookie = function (cookieName) {
106
+ if (!GOVUK.cookie) {
107
+ return
108
+ }
109
+
110
+ try {
111
+ return JSON.parse(JSON.parse(GOVUK.cookie(cookieName)))
112
+ } catch (error) {
113
+ return null
114
+ }
115
+ }
116
+
117
+ StaticAnalytics.prototype.stripPII = function (value) {
118
+ return this.analytics.pii.stripPII(value)
119
+ }
120
+
121
+ function getOptionsFromCookie () {
122
+ try {
123
+ var cookie = StaticAnalytics.prototype.getCookie('analytics_next_page_call')
124
+ StaticAnalytics.prototype.setCookie('analytics_next_page_call', null)
125
+ return cookie || {}
126
+ } catch (e) {
127
+ return {}
128
+ }
129
+ }
130
+
131
+ GOVUK.StaticAnalytics = StaticAnalytics
132
+ })()
@@ -0,0 +1,61 @@
1
+ //= require ../vendor/polyfills/closest.js
2
+
3
+ window.GOVUK = window.GOVUK || {}
4
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
5
+
6
+ (function (Modules) {
7
+ function GemTrackClick () { }
8
+
9
+ GemTrackClick.prototype.start = function ($module) {
10
+ this.$module = $module[0]
11
+ this.$module.handleClick = this.handleClick.bind(this)
12
+
13
+ var that = this
14
+ // add a listener to the whole element
15
+ this.$module.addEventListener('click', function (e) {
16
+ that.$module.handleClick(e.target)
17
+ })
18
+ }
19
+
20
+ GemTrackClick.prototype.handleClick = function (target) {
21
+ var options = { transport: 'beacon' }
22
+
23
+ // if clicked element hasn't got the right attributes, look for a parent that matches
24
+ if (!target.hasAttribute('data-track-category') && !target.hasAttribute('data-track-action')) {
25
+ target = target.closest('[data-track-category][data-track-action]')
26
+ }
27
+
28
+ if (target) {
29
+ var category = target.getAttribute('data-track-category')
30
+ var action = target.getAttribute('data-track-action')
31
+ var label = target.getAttribute('data-track-label')
32
+ var value = target.getAttribute('data-track-value')
33
+ var dimension = target.getAttribute('data-track-dimension')
34
+ var dimensionIndex = target.getAttribute('data-track-dimension-index')
35
+ var extraOptions = target.getAttribute('data-track-options')
36
+
37
+ if (label) {
38
+ options.label = label
39
+ }
40
+
41
+ if (value) {
42
+ options.value = value
43
+ }
44
+
45
+ if (dimension && dimensionIndex) {
46
+ options['dimension' + dimensionIndex] = dimension
47
+ }
48
+
49
+ if (extraOptions) {
50
+ extraOptions = JSON.parse(extraOptions)
51
+ for (var k in extraOptions) options[k] = extraOptions[k]
52
+ }
53
+
54
+ if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
55
+ window.GOVUK.analytics.trackEvent(category, action, options)
56
+ }
57
+ }
58
+ }
59
+
60
+ Modules.GemTrackClick = GemTrackClick
61
+ })(window.GOVUK.Modules)
@@ -38,10 +38,9 @@ $gem-hover-dark-background: #dddcdb;
38
38
  text-decoration: underline;
39
39
  }
40
40
 
41
- &:focus,
42
- &:active {
41
+ &:focus {
43
42
  text-decoration: none;
44
- color: govuk-colour("black");
43
+ color: $govuk-focus-text-colour;
45
44
  }
46
45
  }
47
46
 
@@ -193,14 +192,9 @@ $gem-hover-dark-background: #dddcdb;
193
192
  color: $gem-hover-dark-background;
194
193
  }
195
194
 
196
- &:focus,
197
- &:active {
195
+ &:focus {
198
196
  text-decoration: none;
199
- color: govuk-colour("black");
200
-
201
- &:hover {
202
- color: govuk-colour("black");
203
- }
197
+ color: $govuk-focus-text-colour;
204
198
  }
205
199
  }
206
200
 
@@ -1,13 +1,10 @@
1
1
  <%-
2
2
  cl_helper = GovukPublishingComponents::Presenters::ContentsListHelper.new(local_assigns)
3
- aria_label ||= "Contents"
3
+ aria_label ||= t("components.contents_list.contents")
4
4
  format_numbers ||= false
5
- title_lang ||= false
6
- title = local_assigns[:title].presence || t("components.contents_list.contents")
7
- hide_title ||= false
8
5
  brand ||= false
9
6
  brand_helper = GovukPublishingComponents::AppHelpers::BrandHelper.new(brand)
10
-
7
+ title_fallback = t("components.contents_list.contents", locale: I18n.locale, fallback: false, default: "en")
11
8
  classes = cl_helper.classes
12
9
  classes << brand_helper.brand_class
13
10
  -%>
@@ -21,14 +18,12 @@
21
18
  module: "track-click"
22
19
  }
23
20
  ) do %>
24
- <% unless hide_title %>
25
- <%= content_tag(
26
- :h2,
27
- class: "gem-c-contents-list__title",
28
- lang: title_lang.presence
29
- ) do %>
30
- <%= title %>
31
- <% end %>
21
+ <%= content_tag(
22
+ :h2, {class: "gem-c-contents-list__title"}.merge(
23
+ title_fallback == "en" ? {:lang => "en",} : {}
24
+ )
25
+ ) do %>
26
+ <%= t("components.contents_list.contents") %>
32
27
  <% end %>
33
28
 
34
29
  <ol class="gem-c-contents-list__list">
@@ -12,22 +12,18 @@
12
12
  <% if content.html_safe? %>
13
13
  <%= content %>
14
14
  <% else %>
15
- <% puts "
16
- You've passed in unsanitised HTML into the govspeak component as the
17
- `content` param.
15
+ <% raise "
16
+ You've passed in unsanitised HTML into the Govspeak component as the
17
+ `content` parameter.
18
18
 
19
- Passing in unsafe HTML is deprecated and will be removed in a future
20
- version. You need to pass in a block instead or use the `capture` helper.
21
-
22
- See the component guide for examples.
23
-
24
- If you're 100% sure there's no unsanitised user input in the string you
25
- could also call `.html_safe` on the string or use the `raw` helper before
26
- passing it in.
19
+ To fix this use a `do` block with the sanitize method - see
20
+ https://components.publishing.service.gov.uk/component-guide/govspeak/
21
+ for the updated documentation and
22
+ https://github.com/alphagov/govuk_publishing_components/pull/1632/
23
+ for further examples.
27
24
 
28
25
  Called from #{caller_locations.find { |l| l.to_s.include?('.erb') }}
29
26
  " %>
30
- <%= raw content %>
31
27
  <% end %>
32
28
  <% elsif block_given? %>
33
29
  <%= yield %>
@@ -1,4 +1,6 @@
1
1
  <%
2
+ shared_helper = GovukPublishingComponents::Presenters::SharedHelper.new(local_assigns)
3
+
2
4
  id ||= "input-#{SecureRandom.hex(4)}"
3
5
  value ||= nil
4
6
  type ||= "text"
@@ -22,6 +24,7 @@
22
24
  error_id = "error-#{SecureRandom.hex(4)}"
23
25
  search_icon ||= nil
24
26
  heading_size = false unless ['s', 'm', 'l', 'xl'].include?(heading_size)
27
+ heading_level ||= nil
25
28
  prefix ||= nil
26
29
  suffix ||= nil
27
30
 
@@ -53,10 +56,20 @@
53
56
 
54
57
  <%= content_tag :div, class: form_group_css_classes do %>
55
58
  <% if label %>
56
- <%= render "govuk_publishing_components/components/label", {
57
- html_for: id,
58
- heading_size: heading_size
59
- }.merge(label.symbolize_keys) %>
59
+ <% label_markup = capture do %>
60
+ <%= render "govuk_publishing_components/components/label", {
61
+ html_for: id,
62
+ heading_size: heading_size
63
+ }.merge(label.symbolize_keys) %>
64
+ <% end %>
65
+
66
+ <% if heading_level %>
67
+ <%= content_tag(shared_helper.get_heading_level, class: "govuk-label-wrapper") do %>
68
+ <%= label_markup %>
69
+ <% end %>
70
+ <% else %>
71
+ <%= label_markup %>
72
+ <% end %>
60
73
  <% end %>
61
74
 
62
75
  <% if hint %>
@@ -47,7 +47,6 @@
47
47
 
48
48
  <% unless omit_header %>
49
49
  <%= render "govuk_publishing_components/components/layout_header", {
50
- environment: "public",
51
50
  search: show_search,
52
51
  # layout-header will always have border-bottom, unless the layout is full width
53
52
  remove_bottom_border: full_width,
@@ -1,6 +1,6 @@
1
1
  <%
2
- product_name ||= "Publishing"
3
- public_environment = environment.eql?("public")
2
+ product_name ||= nil
3
+ environment ||= nil
4
4
  full_width ||= false
5
5
  search ||= false
6
6
  search_left ||= false
@@ -8,8 +8,9 @@
8
8
  remove_bottom_border ||= false
9
9
  search_left ||= false
10
10
  width_class = full_width ? "govuk-header__container--full-width" : "govuk-width-container"
11
+
11
12
  header_classes = %w(gem-c-layout-header govuk-header)
12
- header_classes << "gem-c-layout-header--#{environment}"
13
+ header_classes << "gem-c-layout-header--#{environment}" if environment
13
14
  header_classes << "gem-c-layout-header--no-bottom-border" if remove_bottom_border
14
15
  header_classes << "gem-c-layout-header--search-left" if search_left
15
16
  %>
@@ -19,7 +20,7 @@
19
20
  <% if search_left %>
20
21
  <div class="govuk-grid-row govuk-!-margin-left-0 govuk-!-margin-right-0">
21
22
  <div class="gem-c-layout-header__logo govuk-grid-column-one-third-from-desktop">
22
- <%= render "govuk_publishing_components/components/layout_header/header_logo", public_environment: public_environment, environment: environment, product_name: product_name %>
23
+ <%= render "govuk_publishing_components/components/layout_header/header_logo", environment: environment, product_name: product_name %>
23
24
  </div>
24
25
  </div>
25
26
  <div class="govuk-grid-row govuk-!-margin-left-0 govuk-!-margin-right-0">
@@ -33,7 +34,7 @@
33
34
  <% else %>
34
35
  <div class="govuk-grid-row govuk-!-margin-left-0 govuk-!-margin-right-0">
35
36
  <div class="gem-c-layout-header__logo govuk-grid-column-two-thirds">
36
- <%= render "govuk_publishing_components/components/layout_header/header_logo", public_environment: public_environment, environment: environment, product_name: product_name %>
37
+ <%= render "govuk_publishing_components/components/layout_header/header_logo", environment: environment, product_name: product_name %>
37
38
  </div>
38
39
  <div class="govuk-header__content gem-c-header__content">
39
40
  <%= render "govuk_publishing_components/components/layout_header/navigation_items", navigation_items: navigation_items %>
@@ -2,9 +2,11 @@
2
2
  description ||= false
3
3
  prepend ||= false
4
4
  append ||= false
5
+
6
+ shared_helper = GovukPublishingComponents::Presenters::SharedHelper.new(local_assigns)
5
7
  %>
6
8
  <div class="gem-c-panel govuk-panel govuk-panel--confirmation">
7
- <h2 class="govuk-panel__title">
9
+ <%= content_tag(shared_helper.get_heading_level, class: "govuk-panel__title") do %>
8
10
  <% if prepend %>
9
11
  <span class="gem-c-panel__prepend">
10
12
  <%= prepend %>
@@ -18,7 +20,8 @@
18
20
  <%= append %>
19
21
  </span>
20
22
  <% end %>
21
- </h2>
23
+ <% end %>
24
+
22
25
  <% if description %>
23
26
  <div class="govuk-panel__body">
24
27
  <%= description %>
@@ -203,40 +203,3 @@ examples:
203
203
  text: 2. Numbers not parsed
204
204
  - href: "#third-thing"
205
205
  text: 3. Numbers are just text
206
- without_a_title:
207
- description: The component can be used to provide a list of links to other pages, in which case the 'Contents' title is inappropriate and can be removed.
208
- data:
209
- hide_title: true
210
- contents:
211
- - href: "#first-thing"
212
- text: Community best practice
213
- items:
214
- - href: "#second-thing"
215
- text: Guidance and regulation
216
- - href: "#third-thing"
217
- text: Consultations
218
- with_a_custom_title:
219
- description: Override the default title of "Contents" with a custom title
220
- data:
221
- title: "On this page"
222
- contents:
223
- - href: "#first-thing"
224
- text: First thing
225
- - href: "#second-thing"
226
- text: Second thing
227
- - href: "#third-thing"
228
- text: Third thing
229
- with_a_custom_title_locale:
230
- description: |
231
- This component is often used on translated pages that don’t have a translation for the title of the contents list. This means that it could display the fallback English string if the translate method can’t find an appropriate translation. This makes sure that the lang can be set to ensure that browsers understand which parts of the page are in each language.
232
-
233
- The lang attribute must be set to a [valid BCP47 string](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang#Language_tag_syntax). A valid code can be the two or three letter language code - for example, English is en or eng, Korean is ko or kor - but if in doubt please check.
234
- data:
235
- title_lang: "cy"
236
- contents:
237
- - href: "#first-thing"
238
- text: First thing
239
- - href: "#second-thing"
240
- text: Second thing
241
- - href: "#third-thing"
242
- text: Third thing
@@ -24,12 +24,7 @@ examples:
24
24
  data:
25
25
  block: |
26
26
  <h2>This is a title</h2>
27
- <p>This is some body text with <a href=#>a link</a></p>
28
- with_content:
29
- data:
30
- content: |
31
- <h2>This is a title</h2>
32
- <p>This is some body text with <a href=#>a link</a></p>
27
+ <p>This is some body text with <a href="https://example.com">a link</a>.</p>
33
28
  heading_levels:
34
29
  data:
35
30
  block: |