govuk_tech_docs 1.8.3 → 1.9.0.pre.gfe
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.nvmrc +1 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +4 -0
- data/README.md +6 -0
- data/Rakefile +1 -0
- data/example/source/index.html.md.erb +2 -0
- data/govuk_tech_docs.gemspec +3 -3
- data/lib/assets/javascripts/_analytics.js +26 -26
- data/lib/assets/javascripts/_govuk/modules.js +31 -32
- data/lib/assets/javascripts/_modules/anchored-headings.js +14 -14
- data/lib/assets/javascripts/_modules/collapsible-navigation.js +54 -65
- data/lib/assets/javascripts/_modules/in-page-navigation.js +61 -61
- data/lib/assets/javascripts/_modules/navigation.js +20 -20
- data/lib/assets/javascripts/_modules/page-expiry.js +11 -11
- data/lib/assets/javascripts/_modules/search.js +144 -149
- data/lib/assets/javascripts/_modules/table-of-contents.js +52 -60
- data/lib/assets/javascripts/_start-modules.js +3 -4
- data/lib/assets/javascripts/govuk_tech_docs.js +3 -3
- data/lib/assets/stylesheets/_core.scss +0 -2
- data/lib/assets/stylesheets/_govuk_tech_docs.scss +8 -0
- data/lib/govuk_tech_docs.rb +0 -1
- data/lib/govuk_tech_docs/version.rb +1 -1
- data/lib/source/layouts/_header.erb +1 -1
- data/package-lock.json +1814 -0
- data/package.json +37 -0
- metadata +8 -7
- data/lib/assets/stylesheets/modules/_phase-banner.scss +0 -22
- data/lib/assets/stylesheets/modules/_warning-text.scss +0 -73
@@ -1,34 +1,34 @@
|
|
1
|
-
(function($, Modules) {
|
2
|
-
'use strict'
|
1
|
+
(function ($, Modules) {
|
2
|
+
'use strict'
|
3
3
|
|
4
4
|
Modules.Navigation = function () {
|
5
|
-
var $html = $('html')
|
5
|
+
var $html = $('html')
|
6
6
|
|
7
|
-
var $navToggle
|
8
|
-
var $nav
|
7
|
+
var $navToggle
|
8
|
+
var $nav
|
9
9
|
|
10
10
|
this.start = function ($element) {
|
11
|
-
$navToggle = $('.js-nav-toggle', $element)
|
12
|
-
$nav = $('.js-nav', $element)
|
11
|
+
$navToggle = $('.js-nav-toggle', $element)
|
12
|
+
$nav = $('.js-nav', $element)
|
13
13
|
|
14
|
-
updateAriaAttributes()
|
14
|
+
updateAriaAttributes()
|
15
15
|
|
16
|
-
$navToggle.on('click', toggleNavigation)
|
17
|
-
$(window).on('resize', updateAriaAttributes)
|
16
|
+
$navToggle.on('click', toggleNavigation)
|
17
|
+
$(window).on('resize', updateAriaAttributes)
|
18
18
|
}
|
19
19
|
|
20
|
-
function updateAriaAttributes() {
|
21
|
-
var navIsVisible = $nav.is(':visible')
|
20
|
+
function updateAriaAttributes () {
|
21
|
+
var navIsVisible = $nav.is(':visible')
|
22
22
|
|
23
|
-
$navToggle.attr('aria-expanded', navIsVisible ? 'true' : 'false')
|
24
|
-
$nav.attr('aria-hidden', navIsVisible ? 'false' : 'true')
|
23
|
+
$navToggle.attr('aria-expanded', navIsVisible ? 'true' : 'false')
|
24
|
+
$nav.attr('aria-hidden', navIsVisible ? 'false' : 'true')
|
25
25
|
}
|
26
26
|
|
27
|
-
function toggleNavigation() {
|
28
|
-
var navIsVisible = !$html.hasClass('nav-open')
|
27
|
+
function toggleNavigation () {
|
28
|
+
var navIsVisible = !$html.hasClass('nav-open')
|
29
29
|
|
30
|
-
$html.toggleClass('nav-open', navIsVisible)
|
31
|
-
updateAriaAttributes()
|
30
|
+
$html.toggleClass('nav-open', navIsVisible)
|
31
|
+
updateAriaAttributes()
|
32
32
|
}
|
33
|
-
}
|
34
|
-
})(jQuery, window.GOVUK.Modules)
|
33
|
+
}
|
34
|
+
})(jQuery, window.GOVUK.Modules)
|
@@ -1,15 +1,15 @@
|
|
1
|
-
(function($, Modules) {
|
2
|
-
'use strict'
|
1
|
+
(function ($, Modules) {
|
2
|
+
'use strict'
|
3
3
|
|
4
|
-
Modules.PageExpiry = function PageExpiry() {
|
5
|
-
this.start = function start($element) {
|
6
|
-
var rawDate = $element.data('last-reviewed-on')
|
7
|
-
var isExpired = Date.parse(rawDate) < new Date()
|
4
|
+
Modules.PageExpiry = function PageExpiry () {
|
5
|
+
this.start = function start ($element) {
|
6
|
+
var rawDate = $element.data('last-reviewed-on')
|
7
|
+
var isExpired = Date.parse(rawDate) < new Date()
|
8
8
|
|
9
9
|
if (isExpired) {
|
10
|
-
$element.find('.page-expiry--not-expired').hide(0)
|
11
|
-
$element.find('.page-expiry--expired').show(0)
|
10
|
+
$element.find('.page-expiry--not-expired').hide(0)
|
11
|
+
$element.find('.page-expiry--expired').show(0)
|
12
12
|
}
|
13
|
-
}
|
14
|
-
}
|
15
|
-
})(jQuery, window.GOVUK.Modules)
|
13
|
+
}
|
14
|
+
}
|
15
|
+
})(jQuery, window.GOVUK.Modules)
|
@@ -1,210 +1,208 @@
|
|
1
1
|
//= require lunr.min
|
2
2
|
//= require _vendor/jquery.mark.js
|
3
|
-
(function($, Modules) {
|
4
|
-
'use strict'
|
3
|
+
(function ($, Modules) {
|
4
|
+
'use strict'
|
5
5
|
|
6
|
-
Modules.Search = function Search() {
|
7
|
-
var s = this
|
8
|
-
var $html = $('html')
|
9
|
-
|
10
|
-
|
11
|
-
var $
|
12
|
-
var $
|
13
|
-
var $
|
14
|
-
var $
|
15
|
-
var $
|
16
|
-
var
|
17
|
-
var
|
18
|
-
var
|
19
|
-
var
|
20
|
-
var queryTimer;
|
21
|
-
var maxSearchEntries = 20;
|
6
|
+
Modules.Search = function Search () {
|
7
|
+
var s = this
|
8
|
+
var $html = $('html')
|
9
|
+
var $searchForm
|
10
|
+
var $searchLabel
|
11
|
+
var $searchInput
|
12
|
+
var $searchResults
|
13
|
+
var $searchResultsTitle
|
14
|
+
var $searchResultsWrapper
|
15
|
+
var $searchResultsClose
|
16
|
+
var results
|
17
|
+
var query
|
18
|
+
var queryTimer
|
19
|
+
var maxSearchEntries = 20
|
22
20
|
|
23
|
-
this.start = function start($element) {
|
24
|
-
$searchForm = $element.find('form')
|
25
|
-
$searchInput = $element.find('#search')
|
26
|
-
$searchLabel = $element.find('.search__label')
|
21
|
+
this.start = function start ($element) {
|
22
|
+
$searchForm = $element.find('form')
|
23
|
+
$searchInput = $element.find('#search')
|
24
|
+
$searchLabel = $element.find('.search__label')
|
27
25
|
$searchResultsWrapper = $element.find('.search-results')
|
28
|
-
$searchResults = $searchResultsWrapper.find('.search-results__content')
|
29
|
-
$searchResultsTitle = $searchResultsWrapper.find('.search-results__title')
|
30
|
-
$searchResultsClose = $searchResultsWrapper.find('.search-results__close')
|
31
|
-
s.downloadSearchIndex()
|
32
|
-
attach()
|
33
|
-
changeSearchLabel()
|
34
|
-
}
|
26
|
+
$searchResults = $searchResultsWrapper.find('.search-results__content')
|
27
|
+
$searchResultsTitle = $searchResultsWrapper.find('.search-results__title')
|
28
|
+
$searchResultsClose = $searchResultsWrapper.find('.search-results__close')
|
29
|
+
s.downloadSearchIndex()
|
30
|
+
attach()
|
31
|
+
changeSearchLabel()
|
32
|
+
}
|
35
33
|
|
36
|
-
this.downloadSearchIndex = function downloadSearchIndex() {
|
34
|
+
this.downloadSearchIndex = function downloadSearchIndex () {
|
37
35
|
updateTitle('Loading search index')
|
38
36
|
$.ajax({
|
39
37
|
url: '/search.json',
|
40
38
|
cache: true,
|
41
39
|
method: 'GET',
|
42
|
-
success: function(data) {
|
43
|
-
s.lunrData = data
|
44
|
-
s.lunrIndex = lunr.Index.load(s.lunrData.index)
|
45
|
-
replaceStopWordFilter()
|
46
|
-
$(document).trigger('lunrIndexLoaded')
|
40
|
+
success: function (data) {
|
41
|
+
s.lunrData = data
|
42
|
+
s.lunrIndex = lunr.Index.load(s.lunrData.index)
|
43
|
+
replaceStopWordFilter()
|
44
|
+
$(document).trigger('lunrIndexLoaded')
|
47
45
|
}
|
48
|
-
})
|
46
|
+
})
|
49
47
|
}
|
50
48
|
|
51
|
-
function attach() {
|
49
|
+
function attach () {
|
52
50
|
// Search functionality on search text input
|
53
51
|
$searchInput.on('input', function (e) {
|
54
|
-
e.preventDefault()
|
55
|
-
query = $(this).val()
|
56
|
-
s.search(query, function(r) {
|
57
|
-
results = r
|
58
|
-
renderResults(query)
|
59
|
-
updateTitle()
|
60
|
-
})
|
61
|
-
if(window.ga) {
|
62
|
-
window.clearTimeout(queryTimer)
|
63
|
-
queryTimer = window.setTimeout(sendQueryToAnalytics, 1000)
|
52
|
+
e.preventDefault()
|
53
|
+
query = $(this).val()
|
54
|
+
s.search(query, function (r) {
|
55
|
+
results = r
|
56
|
+
renderResults(query)
|
57
|
+
updateTitle()
|
58
|
+
})
|
59
|
+
if (window.ga) {
|
60
|
+
window.clearTimeout(queryTimer)
|
61
|
+
queryTimer = window.setTimeout(sendQueryToAnalytics, 1000)
|
64
62
|
}
|
65
|
-
})
|
63
|
+
})
|
66
64
|
|
67
65
|
// Set focus on the first search result instead of submiting the search
|
68
66
|
// form to Google
|
69
|
-
$searchForm.on('submit', function(e) {
|
70
|
-
e.preventDefault()
|
71
|
-
showResults()
|
72
|
-
$searchResults.find('.search-result__title a').first().focus()
|
73
|
-
})
|
67
|
+
$searchForm.on('submit', function (e) {
|
68
|
+
e.preventDefault()
|
69
|
+
showResults()
|
70
|
+
$searchResults.find('.search-result__title a').first().focus()
|
71
|
+
})
|
74
72
|
|
75
73
|
// Closing the search results, move focus back to the search input
|
76
|
-
$searchResultsClose.on('click', function(e) {
|
77
|
-
e.preventDefault()
|
78
|
-
$searchInput.focus()
|
79
|
-
hideResults()
|
80
|
-
})
|
74
|
+
$searchResultsClose.on('click', function (e) {
|
75
|
+
e.preventDefault()
|
76
|
+
$searchInput.focus()
|
77
|
+
hideResults()
|
78
|
+
})
|
81
79
|
|
82
80
|
// Attach analytics events to search result clicks
|
83
|
-
if(window.ga) {
|
84
|
-
$searchResults.on('click', '.search-result__title a', function() {
|
85
|
-
var href = $(this).attr('href')
|
81
|
+
if (window.ga) {
|
82
|
+
$searchResults.on('click', '.search-result__title a', function () {
|
83
|
+
var href = $(this).attr('href')
|
86
84
|
ga('send', {
|
87
85
|
hitType: 'event',
|
88
86
|
eventCategory: 'Search result',
|
89
87
|
eventAction: 'click',
|
90
88
|
eventLabel: href,
|
91
89
|
transport: 'beacon'
|
92
|
-
})
|
93
|
-
})
|
90
|
+
})
|
91
|
+
})
|
94
92
|
}
|
95
93
|
|
96
94
|
// When selecting navigation link, close the search results.
|
97
|
-
$('#toc').on('click','a', function(e) {
|
98
|
-
hideResults()
|
95
|
+
$('#toc').on('click', 'a', function (e) {
|
96
|
+
hideResults()
|
99
97
|
})
|
100
98
|
}
|
101
99
|
|
102
|
-
function changeSearchLabel() {
|
103
|
-
$searchLabel.text('Search')
|
100
|
+
function changeSearchLabel () {
|
101
|
+
$searchLabel.text('Search')
|
104
102
|
}
|
105
103
|
|
106
|
-
function getResults(query) {
|
107
|
-
var results = []
|
108
|
-
s.lunrIndex.search(query).forEach(
|
109
|
-
if (
|
110
|
-
results.push(s.lunrData.docs[item.ref])
|
104
|
+
function getResults (query) {
|
105
|
+
var results = []
|
106
|
+
s.lunrIndex.search(query).forEach(function (item, index) {
|
107
|
+
if (index < maxSearchEntries) {
|
108
|
+
results.push(s.lunrData.docs[item.ref])
|
111
109
|
}
|
112
|
-
})
|
113
|
-
return results
|
110
|
+
})
|
111
|
+
return results
|
114
112
|
}
|
115
113
|
|
116
|
-
this.search = function search(query, callback) {
|
117
|
-
if(query === '') {
|
118
|
-
hideResults()
|
119
|
-
return
|
114
|
+
this.search = function search (query, callback) {
|
115
|
+
if (query === '') {
|
116
|
+
hideResults()
|
117
|
+
return
|
120
118
|
}
|
121
|
-
showResults()
|
119
|
+
showResults()
|
122
120
|
// The index has not been downloaded yet, exit early and wait.
|
123
|
-
if(!s.lunrIndex) {
|
124
|
-
$(document).on('lunrIndexLoaded', function() {
|
125
|
-
s.search(query, callback)
|
126
|
-
})
|
127
|
-
return
|
121
|
+
if (!s.lunrIndex) {
|
122
|
+
$(document).on('lunrIndexLoaded', function () {
|
123
|
+
s.search(query, callback)
|
124
|
+
})
|
125
|
+
return
|
128
126
|
}
|
129
|
-
callback(getResults(query))
|
127
|
+
callback(getResults(query))
|
130
128
|
}
|
131
129
|
|
132
|
-
function renderResults(query) {
|
133
|
-
var output = ''
|
134
|
-
if (results.length
|
135
|
-
output += '<p>Nothing found</p>'
|
130
|
+
function renderResults (query) {
|
131
|
+
var output = ''
|
132
|
+
if (results.length === 0) {
|
133
|
+
output += '<p>Nothing found</p>'
|
136
134
|
}
|
137
|
-
output += '<ul>'
|
138
|
-
for(var index in results) {
|
139
|
-
var result = results[index]
|
140
|
-
var content = s.processContent(result.content, query)
|
141
|
-
output += '<li class="search-result">'
|
142
|
-
output += '<h3 class="search-result__title">'
|
143
|
-
output += '<a href="' + result.url + '">'
|
144
|
-
output += result.title
|
145
|
-
output += '</a>'
|
146
|
-
output += '</h3>'
|
147
|
-
if(typeof content !== 'undefined') {
|
148
|
-
output += '<p>' + content + '</p>'
|
135
|
+
output += '<ul>'
|
136
|
+
for (var index in results) {
|
137
|
+
var result = results[index]
|
138
|
+
var content = s.processContent(result.content, query)
|
139
|
+
output += '<li class="search-result">'
|
140
|
+
output += '<h3 class="search-result__title">'
|
141
|
+
output += '<a href="' + result.url + '">'
|
142
|
+
output += result.title
|
143
|
+
output += '</a>'
|
144
|
+
output += '</h3>'
|
145
|
+
if (typeof content !== 'undefined') {
|
146
|
+
output += '<p>' + content + '</p>'
|
149
147
|
}
|
150
|
-
output += '</li>'
|
148
|
+
output += '</li>'
|
151
149
|
}
|
152
|
-
output += '</ul>'
|
150
|
+
output += '</ul>'
|
153
151
|
|
154
|
-
$searchResults.html(
|
152
|
+
$searchResults.html(output)
|
155
153
|
}
|
156
154
|
|
157
|
-
this.processContent = function processContent(content, query) {
|
158
|
-
var output
|
159
|
-
content = '<div>'+
|
160
|
-
content = $(content).mark(query)
|
155
|
+
this.processContent = function processContent (content, query) {
|
156
|
+
var output
|
157
|
+
content = '<div>' + content + '</div>'
|
158
|
+
content = $(content).mark(query)
|
161
159
|
|
162
160
|
// Split content by sentence.
|
163
|
-
var sentences = content.html().replace(/(
|
161
|
+
var sentences = content.html().replace(/(\.+|:|!|\?|\r|\n)("*|'*|\)*|}*|]*)/gm, '|').split('|')
|
164
162
|
|
165
163
|
// Select the first five sentences that contain a <mark>
|
166
|
-
var selectedSentences = []
|
164
|
+
var selectedSentences = []
|
167
165
|
for (var i = 0; i < sentences.length; i++) {
|
168
|
-
if(selectedSentences.length === 5) {
|
169
|
-
break
|
166
|
+
if (selectedSentences.length === 5) {
|
167
|
+
break
|
170
168
|
}
|
171
169
|
|
172
|
-
var sentence = sentences[i].trim()
|
173
|
-
var containsMark = sentence.includes('mark>')
|
174
|
-
if (containsMark && (selectedSentences.indexOf(sentence)
|
175
|
-
selectedSentences.push(sentence)
|
170
|
+
var sentence = sentences[i].trim()
|
171
|
+
var containsMark = sentence.includes('mark>')
|
172
|
+
if (containsMark && (selectedSentences.indexOf(sentence) === -1)) {
|
173
|
+
selectedSentences.push(sentence)
|
176
174
|
}
|
177
175
|
}
|
178
|
-
if(selectedSentences.length > 0) {
|
179
|
-
output = ' … ' + selectedSentences.join(' … ') + ' … '
|
176
|
+
if (selectedSentences.length > 0) {
|
177
|
+
output = ' … ' + selectedSentences.join(' … ') + ' … '
|
180
178
|
}
|
181
|
-
return output
|
179
|
+
return output
|
182
180
|
}
|
183
181
|
|
184
182
|
// Default text is to display the number of search results
|
185
|
-
function updateTitle(text) {
|
186
|
-
if(typeof text
|
187
|
-
var count = results.length
|
188
|
-
var
|
183
|
+
function updateTitle (text) {
|
184
|
+
if (typeof text === 'undefined') {
|
185
|
+
var count = results.length
|
186
|
+
var resultsText = count + ' results'
|
189
187
|
}
|
190
|
-
$searchResultsTitle.text(text)
|
188
|
+
$searchResultsTitle.text(text || resultsText)
|
191
189
|
}
|
192
190
|
|
193
|
-
function showResults() {
|
191
|
+
function showResults () {
|
194
192
|
$searchResultsWrapper.addClass('is-open')
|
195
|
-
|
196
|
-
$html.addClass('has-search-results-open')
|
193
|
+
.attr('aria-hidden', 'false')
|
194
|
+
$html.addClass('has-search-results-open')
|
197
195
|
}
|
198
196
|
|
199
|
-
function hideResults() {
|
197
|
+
function hideResults () {
|
200
198
|
$searchResultsWrapper.removeClass('is-open')
|
201
|
-
|
202
|
-
$html.removeClass('has-search-results-open')
|
199
|
+
.attr('aria-hidden', 'true')
|
200
|
+
$html.removeClass('has-search-results-open')
|
203
201
|
}
|
204
202
|
|
205
|
-
function sendQueryToAnalytics() {
|
206
|
-
if(query === '') {
|
207
|
-
return
|
203
|
+
function sendQueryToAnalytics () {
|
204
|
+
if (query === '') {
|
205
|
+
return
|
208
206
|
}
|
209
207
|
var stripped = window.stripPIIFromString(query)
|
210
208
|
ga('send', {
|
@@ -213,18 +211,18 @@
|
|
213
211
|
eventAction: 'type',
|
214
212
|
eventLabel: stripped,
|
215
213
|
transport: 'beacon'
|
216
|
-
})
|
214
|
+
})
|
217
215
|
}
|
218
216
|
|
219
|
-
function replaceStopWordFilter() {
|
217
|
+
function replaceStopWordFilter () {
|
220
218
|
// Replace the default stopWordFilter as it excludes useful words like
|
221
219
|
// 'get'
|
222
220
|
// See: https://lunrjs.com/docs/stop_word_filter.js.html#line43
|
223
|
-
s.lunrIndex.pipeline.remove(lunr.stopWordFilter)
|
224
|
-
s.lunrIndex.pipeline.add(s.govukStopWorldFilter)
|
221
|
+
s.lunrIndex.pipeline.remove(lunr.stopWordFilter)
|
222
|
+
s.lunrIndex.pipeline.add(s.govukStopWorldFilter)
|
225
223
|
}
|
226
224
|
|
227
|
-
|
225
|
+
this.govukStopWorldFilter = lunr.generateStopWordFilter([
|
228
226
|
'a',
|
229
227
|
'able',
|
230
228
|
'about',
|
@@ -344,24 +342,21 @@
|
|
344
342
|
'you',
|
345
343
|
'your'
|
346
344
|
])
|
347
|
-
}
|
345
|
+
}
|
348
346
|
|
349
347
|
// Polyfill includes
|
350
348
|
if (!String.prototype.includes) {
|
351
|
-
String.prototype.includes = function(search, start) {
|
352
|
-
'use strict'
|
349
|
+
String.prototype.includes = function (search, start) { // eslint-disable-line no-extend-native
|
350
|
+
'use strict'
|
353
351
|
if (typeof start !== 'number') {
|
354
|
-
start = 0
|
352
|
+
start = 0
|
355
353
|
}
|
356
354
|
|
357
355
|
if (start + search.length > this.length) {
|
358
|
-
return false
|
356
|
+
return false
|
359
357
|
} else {
|
360
|
-
return this.indexOf(search, start) !== -1
|
358
|
+
return this.indexOf(search, start) !== -1
|
361
359
|
}
|
362
|
-
}
|
360
|
+
}
|
363
361
|
}
|
364
|
-
})(jQuery, window.GOVUK.Modules)
|
365
|
-
|
366
|
-
|
367
|
-
|
362
|
+
})(jQuery, window.GOVUK.Modules)
|