govuk_publishing_components 24.13.1 → 24.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/govuk_publishing_components/analytics/analytics.js +3 -1
- data/app/assets/javascripts/govuk_publishing_components/analytics/custom-dimensions.js +2 -0
- data/app/assets/javascripts/govuk_publishing_components/components/accordion.js +6 -5
- data/app/assets/javascripts/govuk_publishing_components/components/checkboxes.js +9 -7
- data/app/assets/javascripts/govuk_publishing_components/components/contextual-guidance.js +6 -7
- data/app/assets/javascripts/govuk_publishing_components/components/cookie-banner.js +7 -7
- data/app/assets/javascripts/govuk_publishing_components/components/copy-to-clipboard.js +13 -12
- data/app/assets/javascripts/govuk_publishing_components/components/details.js +12 -18
- data/app/assets/javascripts/govuk_publishing_components/components/feedback.js +213 -215
- data/app/assets/javascripts/govuk_publishing_components/components/govspeak.js +4 -4
- data/app/assets/javascripts/govuk_publishing_components/components/modal-dialogue.js +6 -4
- data/app/assets/javascripts/govuk_publishing_components/components/print-link.js +4 -3
- data/app/assets/javascripts/govuk_publishing_components/components/reorderable-list.js +13 -13
- data/app/assets/javascripts/govuk_publishing_components/components/show-password.js +5 -4
- data/app/assets/javascripts/govuk_publishing_components/components/step-by-step-nav.js +4 -4
- data/app/assets/javascripts/govuk_publishing_components/lib/govspeak/magna-charta.js +3 -3
- data/app/assets/javascripts/govuk_publishing_components/lib/header-navigation.js +6 -0
- data/app/assets/javascripts/govuk_publishing_components/lib/trigger-event.js +5 -3
- data/app/assets/javascripts/govuk_publishing_components/rum-loader.js.erb +36 -0
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux-polyfill.js +159 -0
- data/app/assets/javascripts/govuk_publishing_components/vendor/lux/lux.js +844 -0
- data/app/views/govuk_publishing_components/components/_contextual_sidebar.html.erb +1 -1
- data/app/views/govuk_publishing_components/components/_government_navigation.html.erb +50 -8
- data/app/views/govuk_publishing_components/components/_layout_for_public.html.erb +4 -0
- data/app/views/govuk_publishing_components/components/_layout_header.html.erb +11 -2
- data/app/views/govuk_publishing_components/components/_search.html.erb +5 -2
- data/app/views/govuk_publishing_components/components/contextual_sidebar/_brexit_cta.html.erb +9 -4
- data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +3 -3
- data/config/initializers/assets.rb +3 -0
- data/config/locales/ar.yml +3 -0
- data/config/locales/az.yml +3 -0
- data/config/locales/be.yml +3 -0
- data/config/locales/bg.yml +3 -0
- data/config/locales/bn.yml +3 -0
- data/config/locales/cs.yml +3 -0
- data/config/locales/cy.yml +3 -0
- data/config/locales/da.yml +3 -0
- data/config/locales/de.yml +3 -0
- data/config/locales/dr.yml +3 -0
- data/config/locales/el.yml +3 -0
- data/config/locales/en.yml +3 -0
- data/config/locales/es-419.yml +3 -0
- data/config/locales/es.yml +3 -0
- data/config/locales/et.yml +3 -0
- data/config/locales/fa.yml +3 -0
- data/config/locales/fi.yml +3 -0
- data/config/locales/fr.yml +3 -0
- data/config/locales/gd.yml +3 -0
- data/config/locales/gu.yml +3 -0
- data/config/locales/he.yml +3 -0
- data/config/locales/hi.yml +3 -0
- data/config/locales/hr.yml +3 -0
- data/config/locales/hu.yml +3 -0
- data/config/locales/hy.yml +3 -0
- data/config/locales/id.yml +3 -0
- data/config/locales/is.yml +3 -0
- data/config/locales/it.yml +3 -0
- data/config/locales/ja.yml +3 -0
- data/config/locales/ka.yml +3 -0
- data/config/locales/kk.yml +3 -0
- data/config/locales/ko.yml +3 -0
- data/config/locales/lt.yml +3 -0
- data/config/locales/lv.yml +3 -0
- data/config/locales/ms.yml +3 -0
- data/config/locales/mt.yml +3 -0
- data/config/locales/nl.yml +3 -0
- data/config/locales/no.yml +3 -0
- data/config/locales/pa-pk.yml +3 -0
- data/config/locales/pa.yml +3 -0
- data/config/locales/pl.yml +3 -0
- data/config/locales/ps.yml +3 -0
- data/config/locales/pt.yml +3 -0
- data/config/locales/ro.yml +3 -0
- data/config/locales/ru.yml +3 -0
- data/config/locales/si.yml +3 -0
- data/config/locales/sk.yml +3 -0
- data/config/locales/sl.yml +3 -0
- data/config/locales/so.yml +3 -0
- data/config/locales/sq.yml +3 -0
- data/config/locales/sr.yml +3 -0
- data/config/locales/sv.yml +3 -0
- data/config/locales/sw.yml +3 -0
- data/config/locales/ta.yml +3 -0
- data/config/locales/th.yml +3 -0
- data/config/locales/tk.yml +3 -0
- data/config/locales/tr.yml +3 -0
- data/config/locales/uk.yml +3 -0
- data/config/locales/ur.yml +3 -0
- data/config/locales/uz.yml +3 -0
- data/config/locales/vi.yml +3 -0
- data/config/locales/zh-hk.yml +3 -0
- data/config/locales/zh-tw.yml +3 -0
- data/config/locales/zh.yml +3 -0
- data/lib/govuk_publishing_components.rb +1 -0
- data/lib/govuk_publishing_components/presenters/brexit_cta_helper.rb +33 -0
- data/lib/govuk_publishing_components/presenters/content_breadcrumbs_based_on_priority.rb +32 -3
- data/lib/govuk_publishing_components/presenters/contextual_navigation.rb +1 -0
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83c35c9f2649e67c8a1afb3c98c6c6017eecfd762eae1d96c1cd695d03907af3
|
4
|
+
data.tar.gz: 7a2cab9a09d767a5b60d2b725b3dbb4219acd03ff06fc64d3410be04e8902b28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4f467944c4c94230b55ab05a1fb75b26dcc561bccd253a67f61176ad5240f914011dfe602097a544b43886b7cf4f6cfd0821c8828bfc145489acfb752b696b7
|
7
|
+
data.tar.gz: c7113db1463f8a20ffd3071851280fb26e4b0ee1874fea5a2300aecb283e817cabdb75762f34aed367569f23cc7fafbba4f5f9ef1b6bc5b495e9397df44eca01
|
@@ -41,7 +41,9 @@
|
|
41
41
|
// we ignore the possibility of there being campaign variables in the
|
42
42
|
// anchor because we wouldn't know how to detect and parse them if they
|
43
43
|
// were present
|
44
|
-
|
44
|
+
// IE can't access window.location.origin, so we have to do this slightly complex thing
|
45
|
+
var root = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '')
|
46
|
+
return this.pii.stripPIIFromString(location.href.substring(root.length).split('#')[0])
|
45
47
|
}
|
46
48
|
|
47
49
|
Analytics.prototype.trackPageview = function (path, title, options) {
|
@@ -7,15 +7,12 @@ window.GOVUK = window.GOVUK || {}
|
|
7
7
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
8
8
|
|
9
9
|
(function (Modules) {
|
10
|
-
function GemAccordion () {
|
11
|
-
|
12
|
-
GemAccordion.prototype.start = function ($module) {
|
13
|
-
this.$module = $module[0]
|
10
|
+
function GemAccordion ($module) {
|
11
|
+
this.$module = $module
|
14
12
|
this.sectionClass = 'gem-c-accordion__section'
|
15
13
|
this.moduleId = this.$module.getAttribute('id')
|
16
14
|
this.sections = this.$module.querySelectorAll('.' + this.sectionClass)
|
17
15
|
this.openAllButton = ''
|
18
|
-
this.browserSupportsSessionStorage = helper.checkForSessionStorage()
|
19
16
|
this.controlsClass = 'gem-c-accordion__controls'
|
20
17
|
this.openAllClass = 'gem-c-accordion__open-all'
|
21
18
|
this.openAllTextClass = 'gem-c-accordion__open-all-text'
|
@@ -39,6 +36,10 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
|
|
39
36
|
this.$module.actions.showAllText = this.$module.getAttribute('data-show-all-text')
|
40
37
|
this.$module.actions.hideAllText = this.$module.getAttribute('data-hide-all-text')
|
41
38
|
this.$module.actions.thisSectionVisuallyHidden = this.$module.getAttribute('data-this-section-visually-hidden')
|
39
|
+
}
|
40
|
+
|
41
|
+
GemAccordion.prototype.init = function () {
|
42
|
+
this.browserSupportsSessionStorage = helper.checkForSessionStorage()
|
42
43
|
|
43
44
|
// Indicate that JavaScript has worked
|
44
45
|
this.$module.classList.add('gem-c-accordion--active')
|
@@ -6,14 +6,14 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}
|
|
6
6
|
window.GOVUK.Modules.Checkboxes = window.GOVUKFrontend;
|
7
7
|
|
8
8
|
(function (Modules) {
|
9
|
-
function GovukCheckboxes () {
|
10
|
-
|
11
|
-
GovukCheckboxes.prototype.start = function ($module) {
|
12
|
-
this.$module = $module[0]
|
9
|
+
function GovukCheckboxes ($module) {
|
10
|
+
this.$module = $module
|
13
11
|
this.$checkboxes = this.$module.querySelectorAll('input[type=checkbox]')
|
14
12
|
this.$nestedCheckboxes = this.$module.querySelectorAll('[data-nested=true] input[type=checkbox]')
|
15
13
|
this.$exclusiveCheckboxes = this.$module.querySelectorAll('[data-exclusive=true] input[type=checkbox]')
|
14
|
+
}
|
16
15
|
|
16
|
+
GovukCheckboxes.prototype.init = function () {
|
17
17
|
this.applyAriaControlsAttributes(this.$module)
|
18
18
|
|
19
19
|
for (var i = 0; i < this.$checkboxes.length; i++) {
|
@@ -33,7 +33,9 @@ window.GOVUK.Modules.Checkboxes = window.GOVUKFrontend;
|
|
33
33
|
if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
|
34
34
|
// Where checkboxes are manipulated externally in finders, `suppressAnalytics`
|
35
35
|
// is passed to prevent duplicate GA events.
|
36
|
-
|
36
|
+
// use Oliver Steele's Nested Object Access Pattern https://hackernoon.com/accessing-nested-objects-in-javascript-f02f1bd6387f
|
37
|
+
var allowAnalytics = ((event || {}).detail || {}).suppressAnalytics !== true
|
38
|
+
if (allowAnalytics) {
|
37
39
|
var $checkbox = event.target
|
38
40
|
var category = $checkbox.getAttribute('data-track-category')
|
39
41
|
if (category) {
|
@@ -100,11 +102,11 @@ window.GOVUK.Modules.Checkboxes = window.GOVUKFrontend;
|
|
100
102
|
var $exclusiveOption = $checkboxes.querySelector('input[type=checkbox][data-exclusive]')
|
101
103
|
var $nonExclusiveOptions = $checkboxes.querySelectorAll('input[type=checkbox]:not([data-exclusive])')
|
102
104
|
|
103
|
-
if ($currentCheckbox.
|
105
|
+
if ($currentCheckbox.getAttribute('data-exclusive') === 'true' && $currentCheckbox.checked === true) {
|
104
106
|
for (var i = 0; i < $nonExclusiveOptions.length; i++) {
|
105
107
|
$nonExclusiveOptions[i].checked = false
|
106
108
|
}
|
107
|
-
} else if ($currentCheckbox.
|
109
|
+
} else if ($currentCheckbox.getAttribute('data-exclusive') !== 'true' && $currentCheckbox.checked === true) {
|
108
110
|
if ($exclusiveOption) {
|
109
111
|
$exclusiveOption.checked = false
|
110
112
|
}
|
@@ -2,22 +2,21 @@ window.GOVUK = window.GOVUK || {}
|
|
2
2
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
3
|
|
4
4
|
(function (Modules) {
|
5
|
-
function ContextualGuidance () {
|
6
|
-
|
7
|
-
ContextualGuidance.prototype.start = function ($module) {
|
8
|
-
this.$module = $module[0]
|
5
|
+
function ContextualGuidance ($module) {
|
6
|
+
this.$module = $module
|
9
7
|
this.$guidance = this.$module.querySelector('.gem-c-contextual-guidance__wrapper')
|
10
8
|
this.$inputId = this.$guidance.getAttribute('for')
|
11
9
|
this.$input = this.$module.querySelector('#' + this.$inputId)
|
10
|
+
}
|
11
|
+
|
12
|
+
ContextualGuidance.prototype.init = function () {
|
12
13
|
if (!this.$input) return
|
13
14
|
this.$input.addEventListener('focus', this.handleFocus.bind(this))
|
14
15
|
}
|
15
16
|
|
16
17
|
ContextualGuidance.prototype.handleFocus = function (event) {
|
17
18
|
this.hideAllGuidance()
|
18
|
-
|
19
|
-
this.$guidance.style.display = 'block'
|
20
|
-
}
|
19
|
+
this.$guidance.style.display = 'block'
|
21
20
|
}
|
22
21
|
|
23
22
|
ContextualGuidance.prototype.hideAllGuidance = function () {
|
@@ -2,18 +2,18 @@ window.GOVUK = window.GOVUK || {}
|
|
2
2
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
3
|
|
4
4
|
(function (Modules) {
|
5
|
-
function CookieBanner () {
|
5
|
+
function CookieBanner ($module) {
|
6
|
+
this.$module = $module
|
7
|
+
this.$module.cookieBanner = document.querySelector('.gem-c-cookie-banner')
|
8
|
+
this.$module.cookieBannerConfirmationMessage = this.$module.querySelector('.gem-c-cookie-banner__confirmation')
|
9
|
+
this.$module.cookieBannerConfirmationMessageText = this.$module.querySelector('.gem-c-cookie-banner__confirmation-message')
|
10
|
+
}
|
6
11
|
|
7
|
-
CookieBanner.prototype.
|
8
|
-
this.$module = $module[0]
|
12
|
+
CookieBanner.prototype.init = function () {
|
9
13
|
this.$module.hideCookieMessage = this.hideCookieMessage.bind(this)
|
10
14
|
this.$module.showConfirmationMessage = this.showConfirmationMessage.bind(this)
|
11
15
|
this.$module.setCookieConsent = this.setCookieConsent.bind(this)
|
12
16
|
this.$module.rejectCookieConsent = this.rejectCookieConsent.bind(this)
|
13
|
-
|
14
|
-
this.$module.cookieBanner = document.querySelector('.gem-c-cookie-banner')
|
15
|
-
this.$module.cookieBannerConfirmationMessage = this.$module.querySelector('.gem-c-cookie-banner__confirmation')
|
16
|
-
this.$module.cookieBannerConfirmationMessageText = this.$module.querySelector('.gem-c-cookie-banner__confirmation-message')
|
17
17
|
this.setupCookieMessage()
|
18
18
|
}
|
19
19
|
|
@@ -2,23 +2,24 @@ window.GOVUK = window.GOVUK || {}
|
|
2
2
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
3
|
|
4
4
|
(function (Modules) {
|
5
|
-
function CopyToClipboard () {
|
6
|
-
|
7
|
-
|
8
|
-
this.$
|
5
|
+
function CopyToClipboard ($module) {
|
6
|
+
this.$module = $module
|
7
|
+
this.$input = this.$module.querySelector('.gem-c-input')
|
8
|
+
this.$copyButton = this.$module.querySelector('.gem-c-button')
|
9
|
+
}
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
CopyToClipboard.prototype.init = function () {
|
12
|
+
if (!this.$input || !this.$copyButton) return
|
12
13
|
|
13
|
-
input.addEventListener('click', function () {
|
14
|
-
input.select()
|
15
|
-
})
|
14
|
+
this.$input.addEventListener('click', function () {
|
15
|
+
this.$input.select()
|
16
|
+
}.bind(this))
|
16
17
|
|
17
|
-
copyButton.addEventListener('click', function (event) {
|
18
|
+
this.$copyButton.addEventListener('click', function (event) {
|
18
19
|
event.preventDefault()
|
19
|
-
input.select()
|
20
|
+
this.$input.select()
|
20
21
|
document.execCommand('copy')
|
21
|
-
})
|
22
|
+
}.bind(this))
|
22
23
|
}
|
23
24
|
|
24
25
|
Modules.CopyToClipboard = CopyToClipboard
|
@@ -5,26 +5,20 @@ window.GOVUK.Modules = window.GOVUK.Modules || {}
|
|
5
5
|
window.GOVUK.Modules.Details = window.GOVUKFrontend;
|
6
6
|
|
7
7
|
(function (Modules) {
|
8
|
-
function GovukDetails () {
|
9
|
-
|
10
|
-
|
11
|
-
this
|
12
|
-
|
13
|
-
var customTrackLabel = this.$module.getAttribute('data-track-label')
|
8
|
+
function GovukDetails ($module) {
|
9
|
+
this.$module = $module
|
10
|
+
this.customTrackLabel = this.$module.getAttribute('data-track-label')
|
11
|
+
this.detailsClick = this.$module.querySelector('[data-details-track-click]')
|
12
|
+
}
|
14
13
|
|
15
|
-
|
16
|
-
if (customTrackLabel) {
|
14
|
+
GovukDetails.prototype.init = function () {
|
15
|
+
if (this.customTrackLabel) { // If a custom label has been provided, we can simply call the tracking module
|
17
16
|
var trackDetails = new window.GOVUK.Modules.GemTrackClick()
|
18
|
-
trackDetails.start($module)
|
19
|
-
} else {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
if (detailsClick) {
|
24
|
-
detailsClick.addEventListener('click', function (event) {
|
25
|
-
this.trackDefault(this.$module)
|
26
|
-
}.bind(this))
|
27
|
-
}
|
17
|
+
trackDetails.start($(this.$module))
|
18
|
+
} else if (this.detailsClick) { // If no custom label is set, we use the open/close status as the label
|
19
|
+
this.detailsClick.addEventListener('click', function (event) {
|
20
|
+
this.trackDefault(this.$module)
|
21
|
+
}.bind(this))
|
28
22
|
}
|
29
23
|
}
|
30
24
|
|
@@ -3,244 +3,242 @@ window.GOVUK = window.GOVUK || {}
|
|
3
3
|
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
4
4
|
|
5
5
|
(function (Modules) {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
this.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
this.surveyWrapper = this.element.querySelector('#survey-wrapper')
|
6
|
+
function Feedback ($module) {
|
7
|
+
this.$module = $module
|
8
|
+
this.somethingIsWrongForm = this.$module.querySelector('#something-is-wrong')
|
9
|
+
this.surveyForm = this.$module.querySelector('#page-is-not-useful')
|
10
|
+
this.prompt = this.$module.querySelector('.js-prompt')
|
11
|
+
this.forms = this.$module.querySelectorAll('.js-feedback-form')
|
12
|
+
this.toggleForms = this.$module.querySelectorAll('.js-toggle-form')
|
13
|
+
this.closeForms = this.$module.querySelectorAll('.js-close-form')
|
14
|
+
this.activeForm = false
|
15
|
+
this.pageIsUsefulButton = this.$module.querySelector('.js-page-is-useful')
|
16
|
+
this.pageIsNotUsefulButton = this.$module.querySelector('.js-page-is-not-useful')
|
17
|
+
this.somethingIsWrongButton = this.$module.querySelector('.js-something-is-wrong')
|
18
|
+
this.promptQuestions = this.$module.querySelectorAll('.js-prompt-questions')
|
19
|
+
this.promptSuccessMessage = this.$module.querySelector('.js-prompt-success')
|
20
|
+
this.surveyWrapper = this.$module.querySelector('#survey-wrapper')
|
21
|
+
this.jshiddenClass = 'js-hidden'
|
22
|
+
}
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
Feedback.prototype.init = function () {
|
25
|
+
this.setInitialAriaAttributes()
|
26
|
+
this.setHiddenValues()
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
for (var j = 0; j < this.toggleForms.length; j++) {
|
29
|
+
this.toggleForms[j].addEventListener('click', function (e) {
|
30
|
+
e.preventDefault()
|
31
|
+
var el = e.target
|
32
|
+
this.toggleForm(el.getAttribute('aria-controls'))
|
33
|
+
this.trackEvent(this.getTrackEventParams(el))
|
34
|
+
this.updateAriaAttributes(el)
|
35
|
+
}.bind(this))
|
36
|
+
}
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
for (var i = 0; i < this.closeForms.length; i++) {
|
39
|
+
this.closeForms[i].addEventListener('click', function (e) {
|
40
|
+
e.preventDefault()
|
41
|
+
var el = e.target
|
42
|
+
var formToToggle = el.getAttribute('aria-controls')
|
43
|
+
this.toggleForm(formToToggle)
|
44
|
+
this.trackEvent(this.getTrackEventParams(el))
|
45
|
+
this.setInitialAriaAttributes()
|
46
|
+
this.revealInitialPrompt()
|
47
|
+
var refocusClass = '.js-' + formToToggle
|
48
|
+
this.$module.querySelector(refocusClass).focus()
|
49
|
+
}.bind(this))
|
50
|
+
}
|
40
51
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
this.pageIsUsefulButton.addEventListener('click', function (e) {
|
53
|
+
e.preventDefault()
|
54
|
+
this.trackEvent(this.getTrackEventParams(this.pageIsUsefulButton))
|
55
|
+
this.showFormSuccess()
|
56
|
+
this.revealInitialPrompt()
|
57
|
+
}.bind(this))
|
58
|
+
|
59
|
+
this.pageIsNotUsefulButton.addEventListener('click', function (e) {
|
60
|
+
var gaClientId
|
61
|
+
var dummyGaClientId = '111111111.1111111111'
|
62
|
+
if (window.GOVUK.cookie('_ga') === null || window.GOVUK.cookie('_ga') === '') {
|
63
|
+
gaClientId = dummyGaClientId
|
64
|
+
} else {
|
65
|
+
gaClientId = window.GOVUK.cookie('_ga').split('.').slice(-2).join('.')
|
53
66
|
}
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
var params = new FormData($form)
|
84
|
-
params = new URLSearchParams(params).toString()
|
85
|
-
|
86
|
-
xhr.open('POST', url, true)
|
87
|
-
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
|
88
|
-
|
89
|
-
xhr.onreadystatechange = function () {
|
90
|
-
if (xhr.readyState === 4 && xhr.status === 200) {
|
91
|
-
trackEvent(getTrackEventParams($form))
|
92
|
-
showFormSuccess(xhr.message)
|
93
|
-
revealInitialPrompt()
|
94
|
-
setInitialAriaAttributes()
|
95
|
-
thisModule.activeForm.classList.toggle(jshiddenClass)
|
96
|
-
} else {
|
97
|
-
showError(xhr)
|
98
|
-
enableSubmitFormButton($form)
|
99
|
-
}
|
67
|
+
this.setHiddenValuesNotUsefulForm(gaClientId)
|
68
|
+
}.bind(this))
|
69
|
+
|
70
|
+
// much of the JS needed to support sending the form contents via this script is
|
71
|
+
// unsupported by IE, even IE11. This check causes IE to not intercept form submits
|
72
|
+
// and let them happen normally, which is handled already by the backend
|
73
|
+
if (typeof window.URLSearchParams === 'function') {
|
74
|
+
for (var f = 0; f < this.forms.length; f++) {
|
75
|
+
this.forms[f].addEventListener('submit', function (e) {
|
76
|
+
e.preventDefault()
|
77
|
+
var $form = e.target
|
78
|
+
var xhr = new XMLHttpRequest()
|
79
|
+
var url = $form.getAttribute('action')
|
80
|
+
var params = new FormData($form)
|
81
|
+
params = new URLSearchParams(params).toString()
|
82
|
+
|
83
|
+
xhr.open('POST', url, true)
|
84
|
+
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
|
85
|
+
|
86
|
+
xhr.onreadystatechange = function () {
|
87
|
+
if (xhr.readyState === 4 && xhr.status === 200) {
|
88
|
+
this.trackEvent(this.getTrackEventParams($form))
|
89
|
+
this.showFormSuccess(xhr.message)
|
90
|
+
this.revealInitialPrompt()
|
91
|
+
this.setInitialAriaAttributes()
|
92
|
+
this.activeForm.classList.toggle(this.jshiddenClass)
|
93
|
+
} else {
|
94
|
+
this.showError(xhr)
|
95
|
+
this.enableSubmitFormButton($form)
|
100
96
|
}
|
97
|
+
}.bind(this)
|
101
98
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
}
|
99
|
+
this.disableSubmitFormButton($form)
|
100
|
+
xhr.send(params)
|
101
|
+
}.bind(this))
|
106
102
|
}
|
103
|
+
}
|
104
|
+
}
|
107
105
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
Feedback.prototype.disableSubmitFormButton = function ($form) {
|
107
|
+
var formButton = $form.querySelector('[type="submit"]')
|
108
|
+
formButton.setAttribute('disabled', true)
|
109
|
+
}
|
112
110
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
Feedback.prototype.enableSubmitFormButton = function ($form) {
|
112
|
+
var formButton = $form.querySelector('[type="submit"]')
|
113
|
+
formButton.removeAttribute('disabled')
|
114
|
+
}
|
117
115
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
116
|
+
Feedback.prototype.setInitialAriaAttributes = function () {
|
117
|
+
for (var i = 0; i < this.forms.length; i++) {
|
118
|
+
this.forms[i].setAttribute('aria-hidden', true)
|
119
|
+
}
|
120
|
+
this.pageIsNotUsefulButton.setAttribute('aria-expanded', false)
|
121
|
+
this.somethingIsWrongButton.setAttribute('aria-expanded', false)
|
122
|
+
}
|
125
123
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
124
|
+
Feedback.prototype.setHiddenValues = function () {
|
125
|
+
var javascriptEnabled = document.createElement('input')
|
126
|
+
javascriptEnabled.setAttribute('type', 'hidden')
|
127
|
+
javascriptEnabled.setAttribute('name', 'javascript_enabled')
|
128
|
+
javascriptEnabled.setAttribute('value', true)
|
129
|
+
this.somethingIsWrongForm.appendChild(javascriptEnabled)
|
130
|
+
|
131
|
+
var referrer = document.createElement('input')
|
132
|
+
referrer.setAttribute('type', 'hidden')
|
133
|
+
referrer.setAttribute('name', 'referrer')
|
134
|
+
referrer.setAttribute('value', document.referrer || 'unknown')
|
135
|
+
this.somethingIsWrongForm.appendChild(referrer)
|
136
|
+
this.somethingIsWrongForm.invalidInfoError = [
|
137
|
+
'<h2>Sorry, we’re unable to send your message as you haven’t given us any information.</h2>',
|
138
|
+
' <p>Please tell us what you were doing or what went wrong</p>'
|
139
|
+
].join('')
|
140
|
+
}
|
143
141
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
if (document.querySelectorAll('.gem-c-feedback__email-link#take-survey').length === 0) {
|
160
|
-
var takeSurvey = document.createElement('a')
|
161
|
-
takeSurvey.setAttribute('href', 'https://www.smartsurvey.co.uk/s/gov-uk-banner/?c=' + finalPathName + '&gcl=' + gaClientId)
|
162
|
-
takeSurvey.setAttribute('class', 'gem-c-feedback__email-link govuk-link')
|
163
|
-
takeSurvey.setAttribute('id', 'take-survey')
|
164
|
-
takeSurvey.setAttribute('target', '_blank')
|
165
|
-
takeSurvey.setAttribute('rel', 'noopener noreferrer')
|
166
|
-
takeSurvey.innerHTML = 'Don’t have an email address?'
|
167
|
-
thisModule.surveyWrapper.appendChild(takeSurvey)
|
168
|
-
}
|
169
|
-
}
|
142
|
+
Feedback.prototype.setHiddenValuesNotUsefulForm = function (gaClientId) {
|
143
|
+
var currentPathName = window.location.pathname.replace(/[^\s=?&]+(?:@|%40)[^\s=?&]+/, '[email]')
|
144
|
+
var finalPathName = encodeURI(currentPathName)
|
145
|
+
this.surveyForm.invalidInfoError = [
|
146
|
+
'<h2>Sorry, we’re unable to send your message as you haven’t given us a valid email address.</h2>',
|
147
|
+
' <p>Enter an email address in the correct format, like name@example.com</p>'
|
148
|
+
].join('')
|
149
|
+
if (document.querySelectorAll('[name="email_survey_signup[ga_client_id]"]').length === 0) {
|
150
|
+
var hiddenInput = document.createElement('input')
|
151
|
+
hiddenInput.setAttribute('type', 'hidden')
|
152
|
+
hiddenInput.setAttribute('name', 'email_survey_signup[ga_client_id]')
|
153
|
+
hiddenInput.setAttribute('value', gaClientId || '0')
|
154
|
+
this.surveyForm.appendChild(hiddenInput)
|
155
|
+
}
|
170
156
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
157
|
+
if (document.querySelectorAll('.gem-c-feedback__email-link#take-survey').length === 0) {
|
158
|
+
var takeSurvey = document.createElement('a')
|
159
|
+
takeSurvey.setAttribute('href', 'https://www.smartsurvey.co.uk/s/gov-uk-banner/?c=' + finalPathName + '&gcl=' + gaClientId)
|
160
|
+
takeSurvey.setAttribute('class', 'gem-c-feedback__email-link govuk-link')
|
161
|
+
takeSurvey.setAttribute('id', 'take-survey')
|
162
|
+
takeSurvey.setAttribute('target', '_blank')
|
163
|
+
takeSurvey.setAttribute('rel', 'noopener noreferrer')
|
164
|
+
takeSurvey.innerHTML = 'Don’t have an email address?'
|
165
|
+
this.surveyWrapper.appendChild(takeSurvey)
|
166
|
+
}
|
167
|
+
}
|
177
168
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
169
|
+
Feedback.prototype.updateAriaAttributes = function (linkClicked) {
|
170
|
+
linkClicked.setAttribute('aria-expanded', true)
|
171
|
+
var controls = linkClicked.getAttribute('aria-controls')
|
172
|
+
var ariaControls = document.querySelector('#' + controls)
|
173
|
+
ariaControls.setAttribute('aria-hidden', false)
|
174
|
+
}
|
182
175
|
|
183
|
-
|
176
|
+
Feedback.prototype.toggleForm = function (formId) {
|
177
|
+
this.activeForm = this.$module.querySelector('#' + formId)
|
178
|
+
this.activeForm.classList.toggle(this.jshiddenClass)
|
179
|
+
this.prompt.classList.toggle(this.jshiddenClass)
|
184
180
|
|
185
|
-
|
186
|
-
thisModule.activeForm.querySelector('.gem-c-input').focus()
|
187
|
-
} else {
|
188
|
-
thisModule.activeForm = false
|
189
|
-
}
|
190
|
-
}
|
181
|
+
var formIsVisible = !this.activeForm.classList.contains(this.jshiddenClass)
|
191
182
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
183
|
+
if (formIsVisible) {
|
184
|
+
this.activeForm.querySelector('.gem-c-input').focus()
|
185
|
+
} else {
|
186
|
+
this.activeForm = false
|
187
|
+
}
|
188
|
+
}
|
198
189
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
190
|
+
Feedback.prototype.getTrackEventParams = function ($node) {
|
191
|
+
return {
|
192
|
+
category: $node.getAttribute('data-track-category'),
|
193
|
+
action: $node.getAttribute('data-track-action')
|
194
|
+
}
|
195
|
+
}
|
204
196
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
].join('')
|
211
|
-
// if the response is not a 404 or 500, show the error message if it exists
|
212
|
-
// otherwise show the generic message
|
213
|
-
if ('response' in error) {
|
214
|
-
if (typeof error.response === 'object' && error.response !== null) {
|
215
|
-
error = error.response.message === 'email survey sign up failure' ? genericError : error.response.message
|
216
|
-
} else {
|
217
|
-
error = genericError
|
218
|
-
}
|
219
|
-
} else if (error.status === 422) {
|
220
|
-
// there's clobbering by nginx on all 422 requests, which is why the response returns a rendered html page instead of the expected JSON
|
221
|
-
// this is a temporary workaround to ensure that we are displaying relevant error messages to the users
|
222
|
-
error = thisModule.activeForm.invalidInfoError || genericError
|
223
|
-
} else {
|
224
|
-
error = genericError
|
225
|
-
}
|
226
|
-
var $errors = thisModule.activeForm.querySelector('.js-errors')
|
227
|
-
$errors.innerHTML = error
|
228
|
-
$errors.classList.remove(jshiddenClass)
|
229
|
-
$errors.focus()
|
230
|
-
}
|
197
|
+
Feedback.prototype.trackEvent = function (trackEventParams) {
|
198
|
+
if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
|
199
|
+
window.GOVUK.analytics.trackEvent(trackEventParams.category, trackEventParams.action)
|
200
|
+
}
|
201
|
+
}
|
231
202
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
203
|
+
Feedback.prototype.showError = function (error) {
|
204
|
+
var genericError = [
|
205
|
+
'<h2>Sorry, we’re unable to receive your message right now.</h2>',
|
206
|
+
' <p>If the problem persists, we have other ways for you to provide',
|
207
|
+
' feedback on the <a href="/contact/govuk">contact page</a>.</p>'
|
208
|
+
].join('')
|
209
|
+
// if the response is not a 404 or 500, show the error message if it exists
|
210
|
+
// otherwise show the generic message
|
211
|
+
if ('response' in error) {
|
212
|
+
if (typeof error.response === 'object' && error.response !== null) {
|
213
|
+
error = error.response.message === 'email survey sign up failure' ? genericError : error.response.message
|
214
|
+
} else {
|
215
|
+
error = genericError
|
238
216
|
}
|
217
|
+
} else if (error.status === 422) {
|
218
|
+
// there's clobbering by nginx on all 422 requests, which is why the response returns a rendered html page instead of the expected JSON
|
219
|
+
// this is a temporary workaround to ensure that we are displaying relevant error messages to the users
|
220
|
+
error = this.activeForm.invalidInfoError || genericError
|
221
|
+
} else {
|
222
|
+
error = genericError
|
223
|
+
}
|
224
|
+
var $errors = this.activeForm.querySelector('.js-errors')
|
225
|
+
$errors.innerHTML = error
|
226
|
+
$errors.classList.remove(this.jshiddenClass)
|
227
|
+
$errors.focus()
|
228
|
+
}
|
239
229
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
}
|
230
|
+
Feedback.prototype.showFormSuccess = function () {
|
231
|
+
for (var i = 0; i < this.promptQuestions.length; i++) {
|
232
|
+
this.promptQuestions[i].classList.add(this.jshiddenClass)
|
244
233
|
}
|
234
|
+
this.promptSuccessMessage.classList.remove(this.jshiddenClass)
|
235
|
+
this.promptSuccessMessage.focus()
|
245
236
|
}
|
237
|
+
|
238
|
+
Feedback.prototype.revealInitialPrompt = function () {
|
239
|
+
this.prompt.classList.remove(this.jshiddenClass)
|
240
|
+
this.prompt.focus()
|
241
|
+
}
|
242
|
+
|
243
|
+
Modules.Feedback = Feedback
|
246
244
|
})(window.GOVUK.Modules)
|