govuk_publishing_components 27.1.0 → 27.2.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/auto-scroll-tracker.js +197 -0
- data/app/assets/javascripts/govuk_publishing_components/analytics.js +1 -0
- data/app/views/govuk_publishing_components/components/_step_by_step_nav_header.html.erb +5 -5
- data/app/views/govuk_publishing_components/components/docs/inverse_header.yml +3 -4
- data/app/views/govuk_publishing_components/components/layout_header/_header_logo.html.erb +5 -2
- data/lib/govuk_publishing_components/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9f597f228597fe521d156fd1e23b79623d4df60196700196c04a9a53740f0e2
|
4
|
+
data.tar.gz: e224f01d29805ef734e0f89cbb6b6184e32c5fd0ed5b93675553af5016ee7d31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75262a07437872acef9278a928d494bb8a18eab1104a8020dccd9174f3e15f1c7a3396fcd18c7510b342a42efe604f22a48f1cb125f72095668dd7605e1a07a9
|
7
|
+
data.tar.gz: f0303f076da669ee166fab9fc85054d665a3b447b0b4447465fe080492b3460072dc6eaa84e46b4f32f70c72ff616c5229c2373f04a7102795a40d5502ad2d85
|
@@ -0,0 +1,197 @@
|
|
1
|
+
window.GOVUK = window.GOVUK || {}
|
2
|
+
window.GOVUK.Modules = window.GOVUK.Modules || {};
|
3
|
+
|
4
|
+
(function (Modules) {
|
5
|
+
function AutoScrollTracker ($module) {
|
6
|
+
this.$module = $module
|
7
|
+
this.pageHeight = document.querySelector('body').clientHeight
|
8
|
+
this.trackedNodes = []
|
9
|
+
this.config = {
|
10
|
+
allowHeadingsInside: ['main'],
|
11
|
+
percentages: [20, 40, 60, 80, 100],
|
12
|
+
scrollTimeoutDelay: 20,
|
13
|
+
resizeTimeoutDelay: 100,
|
14
|
+
pageHeightTimeoutDelay: 500
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
AutoScrollTracker.prototype.init = function () {
|
19
|
+
var consentCookie = window.GOVUK.getConsentCookie()
|
20
|
+
|
21
|
+
if (consentCookie && consentCookie.settings) {
|
22
|
+
this.startModule()
|
23
|
+
} else {
|
24
|
+
this.startModule = this.startModule.bind(this)
|
25
|
+
window.addEventListener('cookie-consent', this.startModule)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
AutoScrollTracker.prototype.startModule = function () {
|
30
|
+
if (window.GOVUK.analyticsVars.scrollTrackerStarted) {
|
31
|
+
return
|
32
|
+
}
|
33
|
+
|
34
|
+
window.GOVUK.analyticsVars.scrollTrackerStarted = true
|
35
|
+
|
36
|
+
this.trackType = this.$module.getAttribute('data-track-type')
|
37
|
+
if (this.trackType === 'headings') {
|
38
|
+
this.track = new AutoScrollTracker.Heading(this.config)
|
39
|
+
} else {
|
40
|
+
this.track = new AutoScrollTracker.Percentage(this.config)
|
41
|
+
}
|
42
|
+
|
43
|
+
this.getWindowDetails()
|
44
|
+
// if the URL has a hash we want to prevent tracking on initial page load
|
45
|
+
// until the browser jumps down the page, at which point a scroll event
|
46
|
+
// will happen and tracking will continue normally
|
47
|
+
var windowHash = window.location.hash
|
48
|
+
var dontTrackOnLoad = windowHash && document.getElementById(windowHash.substring(1))
|
49
|
+
if (!dontTrackOnLoad) {
|
50
|
+
this.trackVisibleNodes()
|
51
|
+
}
|
52
|
+
|
53
|
+
if (this.trackedNodes.length) {
|
54
|
+
// store event listener functions as variables so they can be removed if needed
|
55
|
+
this.scrollEvent = this.onScroll.bind(this)
|
56
|
+
window.addEventListener('scroll', this.scrollEvent)
|
57
|
+
this.resizeEvent = this.onResize.bind(this)
|
58
|
+
window.addEventListener('resize', this.resizeEvent)
|
59
|
+
|
60
|
+
// check if the page height changes e.g. accordion opened
|
61
|
+
this.interval = window.setInterval(function () {
|
62
|
+
var pageHeight = document.querySelector('body').clientHeight
|
63
|
+
if (pageHeight !== this.pageHeight) {
|
64
|
+
this.pageHeight = pageHeight
|
65
|
+
this.getWindowDetails()
|
66
|
+
this.trackVisibleNodes()
|
67
|
+
}
|
68
|
+
}.bind(this), this.config.pageHeightTimeoutDelay)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
AutoScrollTracker.prototype.onScroll = function () {
|
73
|
+
clearTimeout(this.scrollTimeout)
|
74
|
+
this.scrollTimeout = setTimeout(function () {
|
75
|
+
this.trackVisibleNodes()
|
76
|
+
}.bind(this), this.config.scrollTimeoutDelay)
|
77
|
+
}
|
78
|
+
|
79
|
+
AutoScrollTracker.prototype.onResize = function () {
|
80
|
+
clearTimeout(this.resizeTimeout)
|
81
|
+
this.resizeTimeout = setTimeout(function () {
|
82
|
+
this.getWindowDetails()
|
83
|
+
this.trackVisibleNodes()
|
84
|
+
}.bind(this), this.config.resizeTimeoutDelay)
|
85
|
+
}
|
86
|
+
|
87
|
+
AutoScrollTracker.prototype.getWindowDetails = function () {
|
88
|
+
this.pageHeight = document.querySelector('body').clientHeight
|
89
|
+
this.windowHeight = window.innerHeight
|
90
|
+
this.trackedNodes = this.track.getTrackingNodes(this.trackedNodes)
|
91
|
+
}
|
92
|
+
|
93
|
+
AutoScrollTracker.prototype.trackVisibleNodes = function () {
|
94
|
+
for (var i = 0; i < this.trackedNodes.length; i++) {
|
95
|
+
var node = this.trackedNodes[i]
|
96
|
+
if (this.isVisible(node.top, node.bottom) && !node.alreadySeen) {
|
97
|
+
node.alreadySeen = true
|
98
|
+
// we store whether a heading has been tracked or not on the heading
|
99
|
+
// because if headings appear/disapper (e.g. inside an accordion)
|
100
|
+
// the order changes, so we can't refer to the previous trackedNodes
|
101
|
+
// as we do with percentages
|
102
|
+
if (node.node) {
|
103
|
+
node.node.setAttribute('data-autoscrolltracker-already-seen', true)
|
104
|
+
}
|
105
|
+
|
106
|
+
var action = node.eventData.action
|
107
|
+
var label = node.eventData.label
|
108
|
+
|
109
|
+
if (window.GOVUK.analytics && window.GOVUK.analytics.trackEvent) {
|
110
|
+
window.GOVUK.analytics.trackEvent('ScrollTo', action, { label: label, nonInteraction: true })
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
AutoScrollTracker.prototype.isVisible = function (top, bottom) {
|
117
|
+
var scroll = window.scrollY || document.documentElement.scrollTop // IE fallback
|
118
|
+
return scroll <= top && (scroll + this.windowHeight) >= bottom
|
119
|
+
}
|
120
|
+
|
121
|
+
AutoScrollTracker.Heading = function (config) {
|
122
|
+
this.config = config
|
123
|
+
}
|
124
|
+
|
125
|
+
AutoScrollTracker.Heading.prototype.getTrackingNodes = function () {
|
126
|
+
var headingsDetails = []
|
127
|
+
var headingsFound = this.findAllowedHeadings()
|
128
|
+
|
129
|
+
for (var i = 0; i < headingsFound.length; i++) {
|
130
|
+
var heading = headingsFound[i]
|
131
|
+
// only track headings that are visible i.e. not inside display: none
|
132
|
+
if (this.visible(heading)) {
|
133
|
+
var pos = heading.getBoundingClientRect()
|
134
|
+
headingsDetails.push({
|
135
|
+
node: heading,
|
136
|
+
alreadySeen: heading.getAttribute('data-autoscrolltracker-already-seen'),
|
137
|
+
top: pos.top + document.documentElement.scrollTop,
|
138
|
+
bottom: pos.bottom + document.documentElement.scrollTop,
|
139
|
+
eventData: { action: 'Heading', label: heading.textContent.replace(/\s+/g, ' ').trim() }
|
140
|
+
})
|
141
|
+
}
|
142
|
+
}
|
143
|
+
return headingsDetails
|
144
|
+
}
|
145
|
+
|
146
|
+
// check heading is inside allowed elements, generally ignores everything outside of page content
|
147
|
+
AutoScrollTracker.Heading.prototype.findAllowedHeadings = function () {
|
148
|
+
var headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
|
149
|
+
var headingsFound = []
|
150
|
+
|
151
|
+
for (var h = 0; h < this.config.allowHeadingsInside.length; h++) {
|
152
|
+
var insideElements = document.querySelectorAll(this.config.allowHeadingsInside[h])
|
153
|
+
for (var e = 0; e < insideElements.length; e++) {
|
154
|
+
var found = insideElements[e].querySelectorAll(headings)
|
155
|
+
for (var f = 0; f < found.length; f++) {
|
156
|
+
headingsFound.push(found[f])
|
157
|
+
}
|
158
|
+
}
|
159
|
+
}
|
160
|
+
return headingsFound
|
161
|
+
}
|
162
|
+
|
163
|
+
// this is bit more verbose than checking offsetParent !== null but more reliable for IE10+
|
164
|
+
AutoScrollTracker.Heading.prototype.visible = function (el) {
|
165
|
+
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
|
166
|
+
}
|
167
|
+
|
168
|
+
AutoScrollTracker.Percentage = function (config) {
|
169
|
+
this.config = config
|
170
|
+
}
|
171
|
+
|
172
|
+
AutoScrollTracker.Percentage.prototype.getTrackingNodes = function (trackedNodes) {
|
173
|
+
var body = document.body
|
174
|
+
var html = document.documentElement
|
175
|
+
var pageHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight)
|
176
|
+
|
177
|
+
var percentDetails = []
|
178
|
+
|
179
|
+
for (var i = 0; i < this.config.percentages.length; i++) {
|
180
|
+
var percent = this.config.percentages[i]
|
181
|
+
var pos = (pageHeight / 100) * percent
|
182
|
+
var alreadySeen = false
|
183
|
+
if (trackedNodes.length) {
|
184
|
+
alreadySeen = trackedNodes[i].alreadySeen
|
185
|
+
}
|
186
|
+
percentDetails.push({
|
187
|
+
alreadySeen: alreadySeen,
|
188
|
+
top: pos,
|
189
|
+
bottom: pos,
|
190
|
+
eventData: { action: 'Percent', label: String(percent) }
|
191
|
+
})
|
192
|
+
}
|
193
|
+
return percentDetails
|
194
|
+
}
|
195
|
+
|
196
|
+
Modules.AutoScrollTracker = AutoScrollTracker
|
197
|
+
})(window.GOVUK.Modules)
|
@@ -14,6 +14,7 @@
|
|
14
14
|
//= require ./analytics/ecommerce
|
15
15
|
//= require ./analytics/init
|
16
16
|
//= require ./analytics/scroll-tracker
|
17
|
+
//= require ./analytics/auto-scroll-tracker
|
17
18
|
//= require ./analytics/explicit-cross-domain-links
|
18
19
|
//= require ./analytics/track-click
|
19
20
|
//= require ./analytics/track-select-change
|
@@ -19,17 +19,17 @@
|
|
19
19
|
tracking_options ||= ({ dimension96: tracking_id }).to_json
|
20
20
|
end
|
21
21
|
|
22
|
-
local_assigns[:margin_bottom] ||= 0
|
23
22
|
shared_helper = GovukPublishingComponents::Presenters::SharedHelper.new(local_assigns)
|
24
|
-
classes =
|
23
|
+
classes = %w(gem-c-step-nav-header)
|
24
|
+
classes << shared_helper.get_margin_bottom if local_assigns[:margin_bottom]
|
25
25
|
%>
|
26
26
|
<% if title %>
|
27
27
|
<script type="application/ld+json">
|
28
28
|
<%= raw JSON.pretty_generate(breadcrumb_presenter.structured_data) %>
|
29
29
|
</script>
|
30
30
|
|
31
|
-
|
32
|
-
<
|
31
|
+
<%= tag.div class: classes, data: { module: "gem-track-click" } do %>
|
32
|
+
<strong class="gem-c-step-nav-header__part-of">Part of</strong>
|
33
33
|
<% if path %>
|
34
34
|
<a href="<%= path %>"
|
35
35
|
class="gem-c-step-nav-header__title govuk-link"
|
@@ -51,5 +51,5 @@
|
|
51
51
|
<%= title %>
|
52
52
|
</span>
|
53
53
|
<% end %>
|
54
|
-
|
54
|
+
<% end %>
|
55
55
|
<% end %>
|
@@ -1,15 +1,14 @@
|
|
1
1
|
name: Inverse header
|
2
2
|
description: A wrapper to contain header content in white text
|
3
3
|
body: |
|
4
|
-
This component can be passed a block of template code and will wrap it in a blue header. This is as light-touch as possible and doesn't attempt to deal with the margins and paddings of its content. White text is enforced on content and would need to be
|
4
|
+
This component can be passed a block of template code and will wrap it in a blue header. This is as light-touch as possible and doesn't attempt to deal with the margins and paddings of its content. White text is enforced on content and would need to be overridden where unwanted. Implemented to accommodate topic and list page headings and breadcrumbs but unopinionated about its contents.
|
5
5
|
|
6
6
|
If passing links to the block make sure to add [the inverse modifier](https://design-system.service.gov.uk/styles/typography/#links-on-dark-backgrounds).
|
7
7
|
|
8
8
|
accessibility_criteria: |
|
9
9
|
The component must:
|
10
10
|
|
11
|
-
* be used in conjunction with content that renders a text contrast ratio higher than 4.5:1
|
12
|
-
against the header colour to meet WCAG AA.
|
11
|
+
* be used in conjunction with content that renders a text contrast ratio higher than 4.5:1 against the header colour to meet WCAG AA.
|
13
12
|
|
14
13
|
accessibility_excluded_rules:
|
15
14
|
- skip-link # Examples of this component contain breadcrumbs, creating a reference to #content which is part of the layout
|
@@ -33,7 +32,7 @@ examples:
|
|
33
32
|
</h1>
|
34
33
|
</div>
|
35
34
|
html_publication_header:
|
36
|
-
description: "The inverse header component is used on
|
35
|
+
description: "The inverse header component is used on HTML publications. [See example on GOV.UK here](https://www.gov.uk/government/publications/ln5-0at-jackson-homes-scopwick-ltd-environmental-permit-application-advertisement/ln5-0at-jackson-homes-scopwick-ltd-environmental-permit-application)"
|
37
36
|
data:
|
38
37
|
block: |
|
39
38
|
<div class="gem-c-title gem-c-title--inverse gem-c-title--bottom-margin">
|
@@ -1,11 +1,14 @@
|
|
1
1
|
<div class="govuk-header__logo gem-c-header__logo">
|
2
2
|
<a href="<%= logo_link %>" class="govuk-header__link govuk-header__link--homepage" data-module="gem-track-click" data-track-category="homeLinkClicked" data-track-action="homeHeader">
|
3
3
|
<span class="govuk-header__logotype gem-c-header__logotype">
|
4
|
+
<!--[if gt IE 8]><!-->
|
4
5
|
<svg aria-hidden="true" focusable="false" class="govuk-header__logotype-crown" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 97" height="30" width="36">
|
5
6
|
<path fill="currentColor" fill-rule="evenodd" d="M25 30.2c3.5 1.5 7.7-.2 9.1-3.7 1.5-3.6-.2-7.8-3.9-9.2-3.6-1.4-7.6.3-9.1 3.9-1.4 3.5.3 7.5 3.9 9zM9 39.5c3.6 1.5 7.8-.2 9.2-3.7 1.5-3.6-.2-7.8-3.9-9.1-3.6-1.5-7.6.2-9.1 3.8-1.4 3.5.3 7.5 3.8 9zM4.4 57.2c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.5-1.5-7.6.3-9.1 3.8-1.4 3.5.3 7.6 3.9 9.1zm38.3-21.4c3.5 1.5 7.7-.2 9.1-3.8 1.5-3.6-.2-7.7-3.9-9.1-3.6-1.5-7.6.3-9.1 3.8-1.3 3.6.4 7.7 3.9 9.1zm64.4-5.6c-3.6 1.5-7.8-.2-9.1-3.7-1.5-3.6.2-7.8 3.8-9.2 3.6-1.4 7.7.3 9.2 3.9 1.3 3.5-.4 7.5-3.9 9zm15.9 9.3c-3.6 1.5-7.7-.2-9.1-3.7-1.5-3.6.2-7.8 3.7-9.1 3.6-1.5 7.7.2 9.2 3.8 1.5 3.5-.3 7.5-3.8 9zm4.7 17.7c-3.6 1.5-7.8-.2-9.2-3.8-1.5-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.3 3.5-.4 7.6-3.9 9.1zM89.3 35.8c-3.6 1.5-7.8-.2-9.2-3.8-1.4-3.6.2-7.7 3.9-9.1 3.6-1.5 7.7.3 9.2 3.8 1.4 3.6-.3 7.7-3.9 9.1zM69.7 17.7l8.9 4.7V9.3l-8.9 2.8c-.2-.3-.5-.6-.9-.9L72.4 0H59.6l3.5 11.2c-.3.3-.6.5-.9.9l-8.8-2.8v13.1l8.8-4.7c.3.3.6.7.9.9l-5 15.4v.1c-.2.8-.4 1.6-.4 2.4 0 4.1 3.1 7.5 7 8.1h.2c.3 0 .7.1 1 .1.4 0 .7 0 1-.1h.2c4-.6 7.1-4.1 7.1-8.1 0-.8-.1-1.7-.4-2.4V34l-5.1-15.4c.4-.2.7-.6 1-.9zM66 92.8c16.9 0 32.8 1.1 47.1 3.2 4-16.9 8.9-26.7 14-33.5l-9.6-3.4c1 4.9 1.1 7.2 0 10.2-1.5-1.4-3-4.3-4.2-8.7L108.6 76c2.8-2 5-3.2 7.5-3.3-4.4 9.4-10 11.9-13.6 11.2-4.3-.8-6.3-4.6-5.6-7.9 1-4.7 5.7-5.9 8-.5 4.3-8.7-3-11.4-7.6-8.8 7.1-7.2 7.9-13.5 2.1-21.1-8 6.1-8.1 12.3-4.5 20.8-4.7-5.4-12.1-2.5-9.5 6.2 3.4-5.2 7.9-2 7.2 3.1-.6 4.3-6.4 7.8-13.5 7.2-10.3-.9-10.9-8-11.2-13.8 2.5-.5 7.1 1.8 11 7.3L80.2 60c-4.1 4.4-8 5.3-12.3 5.4 1.4-4.4 8-11.6 8-11.6H55.5s6.4 7.2 7.9 11.6c-4.2-.1-8-1-12.3-5.4l1.4 16.4c3.9-5.5 8.5-7.7 10.9-7.3-.3 5.8-.9 12.8-11.1 13.8-7.2.6-12.9-2.9-13.5-7.2-.7-5 3.8-8.3 7.1-3.1 2.7-8.7-4.6-11.6-9.4-6.2 3.7-8.5 3.6-14.7-4.6-20.8-5.8 7.6-5 13.9 2.2 21.1-4.7-2.6-11.9.1-7.7 8.8 2.3-5.5 7.1-4.2 8.1.5.7 3.3-1.3 7.1-5.7 7.9-3.5.7-9-1.8-13.5-11.2 2.5.1 4.7 1.3 7.5 3.3l-4.7-15.4c-1.2 4.4-2.7 7.2-4.3 8.7-1.1-3-.9-5.3 0-10.2l-9.5 3.4c5 6.9 9.9 16.7 14 33.5 14.8-2.1 30.8-3.2 47.7-3.2z"></path>
|
6
|
-
<%# Deliberate use of image tag as a fallback method https://lynn.ru/examples/svg/en.html %>
|
7
|
-
<image src="<%= asset_path('govuk-logotype-crown.png') %>" xlink:href="" display="none" class="govuk-header__logotype-crown-fallback-image" width="36" height="30"></image>
|
8
7
|
</svg>
|
8
|
+
<!--<![endif]-->
|
9
|
+
<!--[if IE 8]>
|
10
|
+
<img src="<%= asset_path('govuk-logotype-crown.png') %>" alt="" class="govuk-header__logotype-crown-fallback-image" width="36" height="32">
|
11
|
+
<![endif]-->
|
9
12
|
<span class="govuk-header__logotype-text">
|
10
13
|
GOV.UK
|
11
14
|
</span>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: govuk_publishing_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 27.
|
4
|
+
version: 27.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GOV.UK Dev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: govuk_app_config
|
@@ -462,6 +462,7 @@ files:
|
|
462
462
|
- app/assets/javascripts/govuk_publishing_components/all_components.js
|
463
463
|
- app/assets/javascripts/govuk_publishing_components/analytics.js
|
464
464
|
- app/assets/javascripts/govuk_publishing_components/analytics/analytics.js
|
465
|
+
- app/assets/javascripts/govuk_publishing_components/analytics/auto-scroll-tracker.js
|
465
466
|
- app/assets/javascripts/govuk_publishing_components/analytics/auto-track-event.js
|
466
467
|
- app/assets/javascripts/govuk_publishing_components/analytics/custom-dimensions.js
|
467
468
|
- app/assets/javascripts/govuk_publishing_components/analytics/download-link-tracker.js
|