govuk_publishing_components 21.69.0 → 23.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) 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 +56 -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/assets/stylesheets/govuk_publishing_components/components/_layout-header.scss +5 -0
  21. data/app/assets/stylesheets/govuk_publishing_components/components/_print-link.scss +0 -2
  22. data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +7 -1
  23. data/app/assets/stylesheets/govuk_publishing_components/components/print/_govspeak.scss +4 -0
  24. data/app/views/govuk_publishing_components/components/_contents_list.html.erb +8 -13
  25. data/app/views/govuk_publishing_components/components/_govspeak.html.erb +8 -12
  26. data/app/views/govuk_publishing_components/components/_input.html.erb +17 -4
  27. data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +0 -1
  28. data/app/views/govuk_publishing_components/components/_layout_header.html.erb +6 -5
  29. data/app/views/govuk_publishing_components/components/_panel.html.erb +5 -2
  30. data/app/views/govuk_publishing_components/components/_print_link.html.erb +18 -11
  31. data/app/views/govuk_publishing_components/components/docs/contents_list.yml +0 -37
  32. data/app/views/govuk_publishing_components/components/docs/govspeak.yml +1 -6
  33. data/app/views/govuk_publishing_components/components/docs/input.yml +7 -3
  34. data/app/views/govuk_publishing_components/components/docs/layout_header.yml +0 -3
  35. data/app/views/govuk_publishing_components/components/docs/panel.yml +4 -0
  36. data/app/views/govuk_publishing_components/components/docs/print_link.yml +5 -0
  37. data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +3 -1
  38. data/config/initializers/assets.rb +1 -0
  39. data/config/locales/et.yml +4 -0
  40. data/config/locales/fr.yml +4 -0
  41. data/lib/govuk_publishing_components/version.rb +1 -1
  42. 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
 
@@ -104,11 +104,16 @@
104
104
  }
105
105
  }
106
106
 
107
+ .govuk-header__logotype {
108
+ vertical-align: middle;
109
+ }
110
+
107
111
  .gem-c-header__product-name {
108
112
  display: none;
109
113
 
110
114
  @include govuk-media-query($from: tablet) {
111
115
  display: inline-block;
116
+ vertical-align: middle;
112
117
  }
113
118
  }
114
119
 
@@ -3,8 +3,6 @@ $gem-c-print-link-background-height: 18px;
3
3
 
4
4
  .gem-c-print-link {
5
5
  display: none;
6
- margin-bottom: 2em;
7
- margin-top: 2em;
8
6
  }
9
7
 
10
8
  .gem-c-print-link.gem-c-print-link--show-without-js {
@@ -36,7 +36,6 @@ $large-input-size: 50px;
36
36
 
37
37
  .gem-c-search__input[type="search"] { // overly specific to prevent some overrides from outside
38
38
  @include govuk-font($size: 19, $line-height: (28 / 19));
39
-
40
39
  padding: 6px;
41
40
  margin: 0;
42
41
  width: 100%;
@@ -71,6 +70,13 @@ $large-input-size: 50px;
71
70
  }
72
71
  }
73
72
 
73
+ @include govuk-compatibility(govuk_template) {
74
+ // ultra specific rule overrides focus styling from govuk_template
75
+ #global-header .gem-c-search__input[type="search"]:focus { // stylelint-disable selector-max-id
76
+ @extend .gem-c-search__input[type="search"]:focus; // stylelint-disable scss/at-extend-no-missing-placeholder
77
+ }
78
+ }
79
+
74
80
  .gem-c-search__submit {
75
81
  border: 0;
76
82
  cursor: pointer;
@@ -58,6 +58,10 @@
58
58
 
59
59
  .footnotes {
60
60
  border-top: 1px solid $govuk-text-colour;
61
+
62
+ a[role="doc-backlink"] {
63
+ display: none;
64
+ }
61
65
  }
62
66
 
63
67
  .legislative-list {
@@ -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 %>