govuk_publishing_components 27.14.2 → 27.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/analytics/custom-dimensions.js +52 -26
  3. data/app/assets/javascripts/govuk_publishing_components/analytics/ecommerce.js +25 -25
  4. data/app/assets/javascripts/govuk_publishing_components/analytics/explicit-cross-domain-links.js +49 -48
  5. data/app/assets/javascripts/govuk_publishing_components/analytics/page-content.js +74 -65
  6. data/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js +0 -1
  7. data/app/assets/javascripts/govuk_publishing_components/components/single-page-notification-button.js +25 -11
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_big-number.scss +10 -2
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_layout-super-navigation-header.scss +17 -115
  10. data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +24 -14
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_single-page-notification-button.scss +8 -0
  12. data/app/assets/stylesheets/govuk_publishing_components/components/govspeak/_tables.scss +8 -4
  13. data/app/assets/stylesheets/govuk_publishing_components/components/mixins/_grid-helper.scss +141 -0
  14. data/app/views/govuk_publishing_components/components/_button.html.erb +1 -1
  15. data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +1 -1
  16. data/app/views/govuk_publishing_components/components/_intervention.html.erb +21 -4
  17. data/app/views/govuk_publishing_components/components/_search.html.erb +1 -0
  18. data/app/views/govuk_publishing_components/components/_single_page_notification_button.html.erb +1 -1
  19. data/app/views/govuk_publishing_components/components/_success_alert.html.erb +4 -1
  20. data/app/views/govuk_publishing_components/components/docs/intervention.yml +11 -0
  21. data/app/views/govuk_publishing_components/components/docs/layout_for_public.yml +1 -1
  22. data/app/views/govuk_publishing_components/components/docs/radio.yml +40 -33
  23. data/app/views/govuk_publishing_components/components/docs/search.yml +3 -0
  24. data/app/views/govuk_publishing_components/components/docs/success_alert.yml +6 -0
  25. data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +1 -1
  26. data/config/i18n-tasks.yml +8 -0
  27. data/config/locales/ar.yml +134 -131
  28. data/config/locales/az.yml +131 -131
  29. data/config/locales/be.yml +136 -130
  30. data/config/locales/bg.yml +135 -131
  31. data/config/locales/bn.yml +132 -131
  32. data/config/locales/cs.yml +136 -131
  33. data/config/locales/cy.yml +129 -125
  34. data/config/locales/da.yml +132 -131
  35. data/config/locales/de.yml +135 -131
  36. data/config/locales/dr.yml +133 -131
  37. data/config/locales/el.yml +131 -131
  38. data/config/locales/en.yml +17 -14
  39. data/config/locales/es-419.yml +131 -131
  40. data/config/locales/es.yml +131 -131
  41. data/config/locales/et.yml +134 -131
  42. data/config/locales/fa.yml +130 -131
  43. data/config/locales/fi.yml +133 -131
  44. data/config/locales/fr.yml +130 -130
  45. data/config/locales/gd.yml +133 -131
  46. data/config/locales/gu.yml +131 -131
  47. data/config/locales/he.yml +131 -131
  48. data/config/locales/hi.yml +131 -131
  49. data/config/locales/hr.yml +133 -131
  50. data/config/locales/hu.yml +134 -131
  51. data/config/locales/hy.yml +135 -131
  52. data/config/locales/id.yml +132 -131
  53. data/config/locales/is.yml +131 -131
  54. data/config/locales/it.yml +131 -131
  55. data/config/locales/ja.yml +128 -131
  56. data/config/locales/ka.yml +134 -131
  57. data/config/locales/kk.yml +131 -131
  58. data/config/locales/ko.yml +13 -17
  59. data/config/locales/lt.yml +136 -131
  60. data/config/locales/lv.yml +135 -131
  61. data/config/locales/ms.yml +131 -131
  62. data/config/locales/mt.yml +133 -131
  63. data/config/locales/nl.yml +131 -131
  64. data/config/locales/no.yml +131 -131
  65. data/config/locales/pa-pk.yml +128 -132
  66. data/config/locales/pa.yml +131 -131
  67. data/config/locales/pl.yml +135 -131
  68. data/config/locales/ps.yml +128 -131
  69. data/config/locales/pt.yml +131 -131
  70. data/config/locales/ro.yml +132 -131
  71. data/config/locales/ru.yml +135 -131
  72. data/config/locales/si.yml +131 -131
  73. data/config/locales/sk.yml +136 -131
  74. data/config/locales/sl.yml +138 -131
  75. data/config/locales/so.yml +131 -131
  76. data/config/locales/sq.yml +131 -131
  77. data/config/locales/sr.yml +133 -131
  78. data/config/locales/sv.yml +131 -131
  79. data/config/locales/sw.yml +131 -131
  80. data/config/locales/ta.yml +132 -131
  81. data/config/locales/th.yml +130 -131
  82. data/config/locales/tk.yml +132 -131
  83. data/config/locales/tr.yml +132 -131
  84. data/config/locales/uk.yml +138 -131
  85. data/config/locales/ur.yml +128 -131
  86. data/config/locales/uz.yml +133 -131
  87. data/config/locales/vi.yml +131 -131
  88. data/config/locales/zh-hk.yml +130 -131
  89. data/config/locales/zh-tw.yml +130 -131
  90. data/config/locales/zh.yml +130 -131
  91. data/lib/govuk_publishing_components/presenters/button_helper.rb +24 -0
  92. data/lib/govuk_publishing_components/presenters/intervention_helper.rb +20 -2
  93. data/lib/govuk_publishing_components/presenters/single_page_notification_button_helper.rb +3 -1
  94. data/lib/govuk_publishing_components/version.rb +1 -1
  95. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07e0c548e46fc4a7dcb04e7f2838f17b7fc6234804695cfbeca50d1aec4f4431
4
- data.tar.gz: 33b0e798aed35a5ab8808ad6b6e0ee99a929c6d2b8da837d6acb156cf66d4f2c
3
+ metadata.gz: 49373bd0b9e370b948f7c91c83647ca22f7f2e112bb0d12dee4686c980f831f4
4
+ data.tar.gz: 4868f4234fcf242d553c90ab60f35e2354480c30f6c44f3066b5fc60079175b7
5
5
  SHA512:
6
- metadata.gz: b48854f3ab1990a2166fbef3f8e57f2487778b7c9df6a0327e05318821b978ba3ef21f0a0865c6cc3cb714d0bff8a3fd6e102cd855fa1b28b78c32d66d92f0a0
7
- data.tar.gz: 7bb47453cfc2208ffe22cb79c6493d85720a137b405709a545b3a6a6f37ee59e05b953a59c8cd067d2661038d3dbe323950b6662378ee24ee1ae8c14e98dbcd0
6
+ metadata.gz: 7e68c23966e5498ca1ae0c386d2a91703b94bac02808fbae86755ca35b12d3fdd45859a2d3eaa6f052912890296554c0478c717354bd29fb1dd5336a8a3bad5e
7
+ data.tar.gz: ada5d7c714155391431943c17850d379e4bc9fce3e20fa35bff736b21b60b13d92140dbd7102237f2c64b9c0a948723954e677ef5935b4d91b7bc6a4014bfbd9
@@ -1,4 +1,4 @@
1
- /* global GOVUK, $ */
1
+ /* global GOVUK */
2
2
 
3
3
  (function () {
4
4
  'use strict'
@@ -7,11 +7,11 @@
7
7
 
8
8
  CustomDimensions.getAndExtendDefaultTrackingOptions = function (extraOptions) {
9
9
  var trackingOptions = this.customDimensions()
10
- return $.extend(trackingOptions, extraOptions)
10
+ return this.extend(trackingOptions, extraOptions)
11
11
  }
12
12
 
13
13
  CustomDimensions.customDimensions = function () {
14
- var dimensions = $.extend(
14
+ var dimensions = this.extend(
15
15
  {},
16
16
  customDimensionsFromBrowser(),
17
17
  customDimensionsFromMetaTags(),
@@ -19,9 +19,28 @@
19
19
  abTestCustomDimensions()
20
20
  )
21
21
 
22
- return $.each(dimensions, function (key, value) {
23
- dimensions[key] = new GOVUK.Analytics.PIISafe(String(value))
24
- })
22
+ for (var key in dimensions) {
23
+ dimensions[key] = new GOVUK.Analytics.PIISafe(String(dimensions[key]))
24
+ }
25
+ return dimensions
26
+ }
27
+
28
+ CustomDimensions.extend = function (out) {
29
+ out = out || {}
30
+
31
+ for (var i = 1; i < arguments.length; i++) {
32
+ if (!arguments[i]) {
33
+ continue
34
+ }
35
+
36
+ for (var key in arguments[i]) {
37
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
38
+ out[key] = arguments[i][key]
39
+ }
40
+ }
41
+ }
42
+
43
+ return out
25
44
  }
26
45
 
27
46
  function customDimensionsFromBrowser () {
@@ -70,52 +89,59 @@
70
89
  'spelling-suggestion': { dimension: 81 }
71
90
  }
72
91
 
73
- var $metas = $('meta[name^="govuk:"]')
92
+ var metas = document.querySelectorAll("meta[name^='govuk']")
74
93
  var customDimensions = {}
75
94
  var tags = {}
76
95
 
77
- $metas.each(function () {
78
- var $meta = $(this)
79
- var key = $meta.attr('name').split('govuk:')[1]
80
-
81
- var dimension = dimensionMappings[key]
96
+ for (var i = 0; i < metas.length; i++) {
97
+ var meta = metas[i]
98
+ var metaKey = meta.getAttribute('name').split('govuk:')[1]
99
+ var dimension = dimensionMappings[metaKey]
82
100
  if (dimension) {
83
- tags[key] = $meta.attr('content')
101
+ tags[metaKey] = meta.getAttribute('content')
84
102
  }
85
- })
103
+ }
86
104
 
87
- $.each(dimensionMappings, function (key, dimension) {
88
- var value = tags[key] || dimension.defaultValue
105
+ for (var key in dimensionMappings) {
106
+ var value = tags[key] || dimensionMappings[key].defaultValue
89
107
  if (typeof value !== 'undefined') {
90
- customDimensions['dimension' + dimension.dimension] = value
108
+ customDimensions['dimension' + dimensionMappings[key].dimension] = value
91
109
  }
92
- })
110
+ }
93
111
 
94
112
  return customDimensions
95
113
  }
96
114
 
97
115
  function customDimensionsFromDom () {
116
+ var mainLang = document.getElementById('content')
117
+ if (mainLang) {
118
+ mainLang = mainLang.getAttribute('lang')
119
+ }
120
+ var globalBar = document.querySelector('[data-module="global-bar"]') || false
121
+ if (globalBar) {
122
+ globalBar = globalBar.style.display !== 'none'
123
+ }
98
124
  return {
99
125
  dimension26: GOVUK.PageContent.getNumberOfSections(),
100
126
  dimension27: GOVUK.PageContent.getNumberOfLinks(),
101
- dimension23: $('main[id="content"]').attr('lang') || 'unknown',
102
- dimension38: $('[data-module="global-bar"]').is(':visible') && 'Global Banner viewed'
127
+ dimension23: mainLang || 'unknown',
128
+ dimension38: globalBar && 'Global Banner viewed'
103
129
  }
104
130
  }
105
131
 
106
132
  function abTestCustomDimensions () {
107
- var $abMetas = $('meta[name^="govuk:ab-test"]')
133
+ var abMetas = document.querySelectorAll("meta[name^='govuk:ab-test']")
108
134
  var customDimensions = {}
109
135
 
110
- $abMetas.each(function () {
111
- var $meta = $(this)
112
- var dimension = parseInt($meta.data('analytics-dimension'))
113
- var testNameAndBucket = $meta.attr('content')
136
+ for (var i = 0; i < abMetas.length; i++) {
137
+ var meta = abMetas[i]
138
+ var dimension = parseInt(meta.getAttribute('data-analytics-dimension'))
139
+ var testNameAndBucket = meta.getAttribute('content')
114
140
 
115
141
  if (dimension) {
116
142
  customDimensions['dimension' + dimension] = testNameAndBucket
117
143
  }
118
- })
144
+ }
119
145
 
120
146
  return customDimensions
121
147
  }
@@ -1,5 +1,5 @@
1
1
  // https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce
2
- /* global GOVUK, $, ga */
2
+ /* global GOVUK, ga */
3
3
 
4
4
  (function () {
5
5
  'use strict'
@@ -12,25 +12,25 @@
12
12
  this.init = function (element) {
13
13
  // Limiting to 100 characters to avoid noise from extra longs search queries
14
14
  // and to stop the size of the payload going over 8k limit.
15
- var searchQuery = GOVUK.analytics.stripPII(element.attr('data-search-query')).substring(0, 100).toLowerCase()
16
- var ecommerceRows = element.find('[data-ecommerce-row]')
17
- var startPosition = parseInt(element.data('ecommerce-start-index'), 10)
18
- var listTitle = element.data('list-title') || DEFAULT_LIST_TITLE
19
- var variant = element.data('ecommerce-variant')
20
- var trackClickLabel = element.data('track-click-label') || DEFAULT_TRACK_CLICK_LABEL
21
-
22
- ecommerceRows.each(function (index, ecommerceRow) {
23
- var $ecommerceRow = $(ecommerceRow)
24
- var listSubheading = $ecommerceRow.data('ecommerce-subheading') || undefined
25
- var contentId = $ecommerceRow.attr('data-ecommerce-content-id')
26
- var path = $ecommerceRow.attr('data-ecommerce-path')
27
-
28
- var indexOverride = $ecommerceRow.attr('data-ecommerce-index')
29
- index = indexOverride ? parseInt(indexOverride, 10) - 1 : index
15
+ var searchQuery = GOVUK.analytics.stripPII(element.getAttribute('data-search-query')).substring(0, 100).toLowerCase()
16
+ var ecommerceRows = element.querySelectorAll('[data-ecommerce-row]')
17
+ var startPosition = parseInt(element.getAttribute('data-ecommerce-start-index'), 10)
18
+ var listTitle = element.getAttribute('data-list-title') || DEFAULT_LIST_TITLE
19
+ var variant = element.getAttribute('data-ecommerce-variant') || undefined
20
+ var trackClickLabel = element.getAttribute('data-track-click-label') || DEFAULT_TRACK_CLICK_LABEL
21
+
22
+ for (var i = 0; i < ecommerceRows.length; i++) {
23
+ var ecommerceRow = ecommerceRows[i]
24
+ var listSubheading = ecommerceRow.getAttribute('data-ecommerce-subheading') || undefined
25
+ var contentId = ecommerceRow.getAttribute('data-ecommerce-content-id') || undefined
26
+ var path = ecommerceRow.getAttribute('data-ecommerce-path')
27
+
28
+ var indexOverride = ecommerceRow.getAttribute('data-ecommerce-index')
29
+ var index = indexOverride ? parseInt(indexOverride, 10) - 1 : i
30
30
 
31
31
  addImpression(contentId, path, index + startPosition, searchQuery, listTitle, listSubheading, variant)
32
- trackProductOnClick($ecommerceRow, contentId, path, index + startPosition, searchQuery, listTitle, listSubheading, variant, trackClickLabel)
33
- })
32
+ trackProductOnClick(ecommerceRow, contentId, path, index + startPosition, searchQuery, listTitle, listSubheading, variant, trackClickLabel)
33
+ }
34
34
  }
35
35
 
36
36
  function constructData (contentId, path, position, listTitle, listSubheading, searchQuery, variant) {
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  function trackProductOnClick (row, contentId, path, position, searchQuery, listTitle, listSubheading, variant, trackClickLabel) {
70
- row.click(function () {
70
+ row.addEventListener('click', function () {
71
71
  if (contentId || path) {
72
72
  var clickData = constructData(contentId, path, position, listTitle, listSubheading, searchQuery, variant)
73
73
  ga('ec:addProduct', clickData)
@@ -82,18 +82,18 @@
82
82
  }
83
83
 
84
84
  Ecommerce.ecLoaded = false
85
- Ecommerce.start = function (element) {
85
+ Ecommerce.start = function (elements) {
86
86
  if (!window.ga) { return }
87
- element = element || $('[data-analytics-ecommerce]')
88
- if (element.length > 0) {
87
+ elements = elements || document.querySelectorAll('[data-analytics-ecommerce]')
88
+ if (elements.length > 0) {
89
89
  if (!Ecommerce.ecLoaded) {
90
90
  ga('require', 'ec')
91
91
  Ecommerce.ecLoaded = true
92
92
  }
93
- element.each(function (index) {
93
+ for (var i = 0; i < elements.length; i++) {
94
94
  var ecommerce = new Ecommerce()
95
- ecommerce.init($(this))
96
- })
95
+ ecommerce.init(elements[i])
96
+ }
97
97
  }
98
98
  }
99
99
 
@@ -6,33 +6,57 @@
6
6
 
7
7
  GOVUK.Modules.ExplicitCrossDomainLinks = function () {
8
8
  this.start = function ($module) {
9
- var element = $module[0]
9
+ this.element = $module[0]
10
+ this.attribute = 'href'
11
+ this.attributeValue = this.element.getAttribute(this.attribute)
12
+ this.eventType = 'click'
13
+ if (!this.attributeValue) {
14
+ this.attribute = 'action'
15
+ this.attributeValue = this.element.getAttribute(this.attribute)
16
+ this.eventType = 'submit'
17
+ }
10
18
 
11
- var cookieBannerEngaged = GOVUK.cookie('cookies_preferences_set')
19
+ this.handleEvent = this.handleEvent.bind(this)
20
+ this.handleCookiesAccepted = this.handleCookiesAccepted.bind(this)
21
+ // Listens for the 'submit' event if the element is a form, and the 'click' event if it is a link
22
+ this.element.addEventListener(this.eventType, this.handleEvent)
23
+ }
12
24
 
13
- // If not engaged, append only ?cookie_consent=not-engaged
14
- // If engaged and rejected, append only ?cookie_consent=reject
15
- // If engaged and accepted usage, append ?_ga=clientid if available and cookie_consent=accept
25
+ this.handleEvent = function (e) {
26
+ // prevent default: we want the link href and/or form action to be decorated before we navigate away
27
+ e.preventDefault()
28
+ var cookieBannerEngaged = GOVUK.cookie('cookies_preferences_set')
29
+ var cookieConsent = GOVUK.getConsentCookie()
16
30
 
17
31
  if (cookieBannerEngaged !== 'true') {
18
- this.decorate(element, 'cookie_consent=not-engaged')
19
- this.start = this.start.bind(this, $module)
20
-
21
- // if the user has not engaged with the cookie banner yet, listen for the cookie consent accept/reject events
22
- // re-start the module if cookies are accepted or rejected on the current page – setting cookie preferences does not reload the page
23
- window.addEventListener('cookie-consent', this.start)
24
- window.addEventListener('cookie-reject', this.start)
25
- return
32
+ // If not engaged, append only ?cookie_consent=not-engaged
33
+ this.decorate(this.element, 'cookie_consent=not-engaged', this.attribute)
34
+ } else if (cookieConsent && cookieConsent.usage === true) {
35
+ this.handleCookiesAccepted()
36
+ } else {
37
+ this.decorate(this.element, 'cookie_consent=reject', this.attribute)
26
38
  }
27
- var cookieConsent = GOVUK.getConsentCookie()
28
- if (cookieConsent && cookieConsent.usage === false) {
29
- this.decorate(element, 'cookie_consent=reject')
30
- return
39
+
40
+ // remove the event listener to avoid an infinite loop
41
+ this.element.removeEventListener(this.eventType, this.handleEvent)
42
+
43
+ // if the element is a form, submit it. If it is a link, click it
44
+ if (this.eventType === 'submit') {
45
+ this.element.submit()
46
+ } else {
47
+ this.element.click()
31
48
  }
49
+ }
32
50
 
33
- this.decorate(element, 'cookie_consent=accept')
51
+ this.handleCookiesAccepted = function () {
52
+ // If the cookie banner was engaged and usage cookie accepted, append ?_ga=clientid if available and cookie_consent=accept
53
+ var element = this.element
54
+ var attribute = this.attribute
55
+ this.decorate(element, 'cookie_consent=accept', attribute)
34
56
 
35
- if (!global.ga) { return }
57
+ if (!global.ga) {
58
+ return
59
+ }
36
60
 
37
61
  global.ga(function () {
38
62
  var trackers = global.ga.getAll()
@@ -40,44 +64,21 @@
40
64
  if (!trackers.length) { return }
41
65
 
42
66
  var linker = new global.gaplugins.Linker(trackers[0])
67
+ var attrValue = element.getAttribute(attribute)
43
68
 
44
- var attrAction = element.getAttribute('action')
45
- if (attrAction) {
46
- element.setAttribute('action', linker.decorate(attrAction))
47
- }
48
-
49
- var attrHref = element.getAttribute('href')
50
- if (attrHref) {
51
- element.href = linker.decorate(attrHref)
52
- }
69
+ element.setAttribute(attribute, linker.decorate(attrValue))
53
70
  })
54
71
  }
55
72
 
56
- this.decorate = function (element, param) {
57
- var attribute = 'href'
73
+ this.decorate = function (element, param, attribute) {
58
74
  var attributeValue = element.getAttribute(attribute)
59
- var cookieConsentParameterPattern = /cookie_consent=[^&]*/
60
- var paramIsCookieConsent = param.match(cookieConsentParameterPattern)
61
-
62
- if (!attributeValue) {
63
- attribute = 'action'
64
- attributeValue = element.getAttribute(attribute)
65
- }
66
75
 
67
76
  if (!attributeValue) { return }
68
77
 
69
- var attributeHasCookieConsent = attributeValue.match(cookieConsentParameterPattern)
70
-
71
- if (attributeHasCookieConsent && paramIsCookieConsent) {
72
- // if the decorate function has received a cookie_consent parameter, but the target element already has a cookie_consent parameter, replace the existing parameter with the new value
73
- attributeValue = attributeValue.replace(cookieConsentParameterPattern, param)
78
+ if (attributeValue.indexOf('?') !== -1) {
79
+ attributeValue += '&' + param
74
80
  } else {
75
- // otherwise, simply append the parameter to the target element href query string
76
- if (attributeValue.includes('?')) {
77
- attributeValue += '&' + param
78
- } else {
79
- attributeValue += '?' + param
80
- }
81
+ attributeValue += '?' + param
81
82
  }
82
83
 
83
84
  element.setAttribute(attribute, attributeValue)
@@ -1,4 +1,4 @@
1
- /* global GOVUK, $ */
1
+ /* global GOVUK */
2
2
 
3
3
  (function () {
4
4
  'use strict'
@@ -8,17 +8,17 @@
8
8
  PageContent.getNumberOfSections = function () {
9
9
  switch (true) {
10
10
  case isNavigationGridPage():
11
- return 1 + $('.parent-topic-contents').length
11
+ return 1 + document.querySelectorAll('.parent-topic-contents').length
12
12
  case isNavigationAccordionPage():
13
- return $('[data-track-count="accordionSection"]').length
13
+ return document.querySelectorAll('[data-track-count="accordionSection"]').length
14
14
  case isDocumentCollectionPage():
15
- return $('.document-collection .group-title').length
15
+ return document.querySelectorAll('.document-collection .group-title').length
16
16
  case isMainstreamBrowsePage():
17
- return $('#subsection ul:visible').length || $('#section ul').length
17
+ return countVisible(document.querySelectorAll('#subsection ul')) || document.querySelectorAll('#section ul').length
18
18
  case isTopicPage():
19
- return $('.topics-page nav.index-list').length
19
+ return document.querySelectorAll('.topics-page nav.index-list').length
20
20
  case isPolicyAreaPage():
21
- return $('.topic section h1.label').length
21
+ return document.querySelectorAll('.topic section h1.label').length
22
22
  case isFinderPage():
23
23
  case isWhitehallFinderPage():
24
24
  case isNavigationLeafPage():
@@ -28,8 +28,8 @@
28
28
  return 1
29
29
  default:
30
30
  // It's a content page, not a "finding" page
31
- var sidebarSections = $('[data-track-count="sidebarRelatedItemSection"]').length
32
- var sidebarTaxons = $('[data-track-count="sidebarTaxonSection"]').length
31
+ var sidebarSections = document.querySelectorAll('[data-track-count="sidebarRelatedItemSection"]').length
32
+ var sidebarTaxons = document.querySelectorAll('[data-track-count="sidebarTaxonSection"]').length
33
33
 
34
34
  return sidebarSections || sidebarTaxons
35
35
  }
@@ -38,92 +38,101 @@
38
38
  PageContent.getNumberOfLinks = function () {
39
39
  switch (true) {
40
40
  case isNavigationGridPage():
41
- return $('a[data-track-category="navGridLinkClicked"]').length +
42
- $('a[data-track-category="navGridLeafLinkClicked"]').length
41
+ return document.querySelectorAll('a[data-track-category="navGridLinkClicked"]').length +
42
+ document.querySelectorAll('a[data-track-category="navGridLeafLinkClicked"]').length
43
43
  case isNavigationAccordionPage():
44
- return $('a[data-track-category="navAccordionLinkClicked"]').length
45
- case isNavigationLeafPage():
46
- return $('a[data-track-category="navLeafLinkClicked"]').length
44
+ return document.querySelectorAll('a[data-track-category="navAccordionLinkClicked"]').length
47
45
  case isDocumentCollectionPage():
48
- return $('.document-collection .group-document-list li a').length
46
+ return document.querySelectorAll('.document-collection .group-document-list li a').length
49
47
  case isMainstreamBrowsePage():
50
- return $('#subsection ul a:visible').length ||
51
- $('#section ul a').length
48
+ return countVisible(document.querySelectorAll('#subsection ul a')) || document.querySelectorAll('#section ul a').length
52
49
  case isTopicPage():
53
- return $('.topics-page .index-list ul a').length ||
54
- $('.topics-page .topics ul a').length
50
+ return document.querySelectorAll('.topics-page .index-list ul a').length ||
51
+ document.querySelectorAll('.topics-page .topics ul a').length
55
52
  case isPolicyAreaPage():
56
- return $('section.document-block a').length +
57
- $('section .collection-list h2 a').length
58
- case isWhitehallFinderPage():
59
- return $('.document-list .document-row h3 a').length
53
+ return document.querySelectorAll('section.document-block a').length +
54
+ document.querySelectorAll('section .collection-list h2 a').length
60
55
  case isFinderPage():
61
- return $('.finder-frontend-content li.document a').length
56
+ return document.querySelectorAll('.finder-frontend-content li.document a').length
57
+ case isWhitehallFinderPage():
58
+ return document.querySelectorAll('.document-list .document-row h3 a').length
59
+ case isNavigationLeafPage():
60
+ return document.querySelectorAll('a[data-track-category="navLeafLinkClicked"]').length
62
61
  default:
63
62
  // It's a content page, not a "finding" page, count related links
64
- return $('a[data-track-category="relatedLinkClicked"]').length
63
+ return document.querySelectorAll('a[data-track-category="relatedLinkClicked"]').length
65
64
  }
66
65
  }
67
66
 
68
- function getRenderingApplication () {
69
- return $('meta[name="govuk:rendering-application"]').attr('content')
70
- };
71
-
72
- function getFormat () {
73
- return $('meta[name="govuk:format"]').attr('content')
74
- };
67
+ var metaApplicationSelector = 'meta[name="govuk:rendering-application"]'
68
+ var metaFormatSelector = 'meta[name="govuk:format"]'
69
+ var metaNavigationTypeSelector = 'meta[name="govuk:navigation-page-type"]'
75
70
 
76
- function getNavigationPageType () {
77
- return $('meta[name="govuk:navigation-page-type"]').attr('content')
78
- };
71
+ function getMetaAttribute (selector) {
72
+ var element = document.querySelector(selector)
73
+ if (element) {
74
+ return element.getAttribute('content')
75
+ }
76
+ }
79
77
 
80
78
  function isNavigationGridPage () {
81
- return getRenderingApplication() === 'collections' &&
82
- getFormat() === 'taxon' &&
83
- getNavigationPageType() === 'grid'
84
- };
79
+ return getMetaAttribute(metaApplicationSelector) === 'collections' &&
80
+ getMetaAttribute(metaFormatSelector) === 'taxon' &&
81
+ getMetaAttribute(metaNavigationTypeSelector) === 'grid'
82
+ }
85
83
 
86
84
  function isNavigationAccordionPage () {
87
- return getRenderingApplication() === 'collections' &&
88
- getFormat() === 'taxon' &&
89
- getNavigationPageType() === 'accordion'
90
- };
85
+ return getMetaAttribute(metaApplicationSelector) === 'collections' &&
86
+ getMetaAttribute(metaFormatSelector) === 'taxon' &&
87
+ getMetaAttribute(metaNavigationTypeSelector) === 'accordion'
88
+ }
91
89
 
92
90
  function isNavigationLeafPage () {
93
- return getRenderingApplication() === 'collections' &&
94
- getFormat() === 'taxon' &&
95
- getNavigationPageType() === 'leaf'
96
- };
91
+ return getMetaAttribute(metaApplicationSelector) === 'collections' &&
92
+ getMetaAttribute(metaFormatSelector) === 'taxon' &&
93
+ getMetaAttribute(metaNavigationTypeSelector) === 'leaf'
94
+ }
97
95
 
98
96
  function isMainstreamBrowsePage () {
99
- return getRenderingApplication() === 'collections' &&
100
- getFormat() === 'mainstream_browse_page'
101
- };
97
+ return getMetaAttribute(metaApplicationSelector) === 'collections' &&
98
+ getMetaAttribute(metaFormatSelector) === 'mainstream_browse_page'
99
+ }
102
100
 
103
101
  function isTopicPage () {
104
- return getRenderingApplication() === 'collections' &&
105
- getFormat() === 'topic'
106
- };
102
+ return getMetaAttribute(metaApplicationSelector) === 'collections' &&
103
+ getMetaAttribute(metaFormatSelector) === 'topic'
104
+ }
107
105
 
108
106
  function isPolicyAreaPage () {
109
- return getRenderingApplication() === 'whitehall' &&
110
- getFormat() === 'placeholder_policy_area'
111
- };
107
+ return getMetaAttribute(metaApplicationSelector) === 'whitehall' &&
108
+ getMetaAttribute(metaFormatSelector) === 'placeholder_policy_area'
109
+ }
112
110
 
113
111
  function isDocumentCollectionPage () {
114
- return getRenderingApplication() === 'government-frontend' &&
115
- getFormat() === 'document_collection'
116
- };
112
+ return getMetaAttribute(metaApplicationSelector) === 'government-frontend' &&
113
+ getMetaAttribute(metaFormatSelector) === 'document_collection'
114
+ }
117
115
 
118
116
  function isFinderPage () {
119
- return getRenderingApplication() === 'finder-frontend' &&
120
- getFormat() === 'finder'
121
- };
117
+ return getMetaAttribute(metaApplicationSelector) === 'finder-frontend' &&
118
+ getMetaAttribute(metaFormatSelector) === 'finder'
119
+ }
122
120
 
123
121
  function isWhitehallFinderPage () {
124
- return getRenderingApplication() === 'whitehall' &&
125
- getFormat() === 'finder'
126
- };
122
+ return getMetaAttribute(metaApplicationSelector) === 'whitehall' &&
123
+ getMetaAttribute(metaFormatSelector) === 'finder'
124
+ }
125
+
126
+ function countVisible (elements) {
127
+ var count = 0
128
+ for (var i = 0; i < elements.length; i++) {
129
+ var style = window.getComputedStyle(elements[i])
130
+ if (!(style.display === 'none' || style.visibility === 'hidden')) {
131
+ count++
132
+ }
133
+ }
134
+ return count
135
+ }
127
136
 
128
137
  GOVUK.PageContent = PageContent
129
138
  })()
@@ -97,7 +97,6 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
97
97
  this.$module.cookieBannerConfirmationMessage.focus()
98
98
  window.GOVUK.cookie('cookies_preferences_set', 'true', { days: 365 })
99
99
  window.GOVUK.setDefaultConsentCookie()
100
- window.GOVUK.triggerEvent(window, 'cookie-reject')
101
100
  }
102
101
 
103
102
  CookieBanner.prototype.showConfirmationMessage = function () {
@@ -7,6 +7,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
7
7
  this.$module = $module
8
8
  this.basePath = this.$module.querySelector('input[name="base_path"]').value
9
9
  this.buttonLocation = this.$module.getAttribute('data-button-location')
10
+ this.buttonVisibleClass = 'gem-c-single-page-notification-button--visible'
10
11
 
11
12
  this.personalisationEndpoint = '/api/personalisation/check-email-subscription?base_path=' + this.basePath
12
13
  // This attribute is passed through to the personalisation API to ensure the updated button has the same button_location for analytics
@@ -16,21 +17,30 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
16
17
  SinglePageNotificationButton.prototype.init = function () {
17
18
  var xhr = new XMLHttpRequest()
18
19
  xhr.open('GET', this.personalisationEndpoint, true)
20
+ // if XHR to the personalisation endpoint is taking an incredibly long time to complete, we are better off leaving the button in its default unpersonalised state. Content changing before the user's eyes while they are browsing can be jarring and should be avoided.
21
+ xhr.timeout = 10000
22
+
23
+ xhr.ontimeout = function () {
24
+ this.makeVisible(this.$module)
25
+ }.bind(this)
19
26
 
20
27
  xhr.onreadystatechange = function () {
21
- if (xhr.readyState === 4 && xhr.status === 200) {
22
- var responseText = xhr.responseText
23
- // if response text exists and is JSON parse-able, parse the response and get the button html
24
- if (responseText && this.responseIsJSON(responseText)) {
25
- var newButton = JSON.parse(responseText).button_html
26
- var html = document.createElement('div')
27
- html.innerHTML = newButton
28
- // test that the html returned contains the button component; if yes, swap the button for the updated version
29
- var responseButtonContainer = html.querySelector('form.gem-c-single-page-notification-button')
30
- if (responseButtonContainer) {
31
- this.$module.parentNode.replaceChild(responseButtonContainer, this.$module)
28
+ if (xhr.readyState === 4) {
29
+ if (xhr.status === 200) {
30
+ var responseText = xhr.responseText
31
+ // if response text exists and is JSON parse-able, parse the response and get the button html
32
+ if (responseText && this.responseIsJSON(responseText)) {
33
+ var newButton = JSON.parse(responseText).button_html
34
+ var html = document.createElement('div')
35
+ html.innerHTML = newButton
36
+ // test that the html returned contains the button component; if yes, swap the button for the updated version
37
+ var responseButtonContainer = html.querySelector('form.gem-c-single-page-notification-button')
38
+ if (responseButtonContainer) {
39
+ this.$module.parentNode.replaceChild(responseButtonContainer, this.$module)
40
+ }
32
41
  }
33
42
  }
43
+ this.makeVisible(this.$module)
34
44
  }
35
45
  }.bind(this)
36
46
  xhr.send()
@@ -44,5 +54,9 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
44
54
  }
45
55
  return true
46
56
  }
57
+
58
+ SinglePageNotificationButton.prototype.makeVisible = function (target) {
59
+ target.classList.add(this.buttonVisibleClass)
60
+ }
47
61
  Modules.SinglePageNotificationButton = SinglePageNotificationButton
48
62
  })(window.GOVUK.Modules)
@@ -1,13 +1,21 @@
1
1
  .gem-c-big-number {
2
2
  margin-bottom: govuk-spacing(3);
3
+ @include govuk-typography-common;
4
+ @include govuk-text-colour;
3
5
  }
4
6
 
5
7
  .gem-c-big-number__value {
6
- @include govuk-font($size: 80, $weight: bold);
8
+ font-size: 80px;
9
+ @include govuk-typography-weight-bold;
10
+ line-height: 1;
11
+
12
+ @if $govuk-typography-use-rem {
13
+ font-size: govuk-px-to-rem(80px);
14
+ }
7
15
  }
8
16
 
9
17
  .gem-c-big-number__label {
10
- @include govuk-font($size: 16, $weight: bold, $line-height: 2);
18
+ @include govuk-font($size: 19, $weight: bold);
11
19
 
12
20
  // This pseudo element is to bypass an issue with NVDA where block level elements are dictated separately.
13
21
  // What's happening here is that the label and the number technically have an inline relationship but appear to have a block relationship thanks to this element