hof 20.3.8-beta-gtm → 20.3.8-timeout-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.nyc_output/2194bc4f-7454-4356-80e2-e52a7dc798aa.json +1 -0
- package/.nyc_output/processinfo/{c84e394d-abf7-4aea-99aa-36427e671442.json → 2194bc4f-7454-4356-80e2-e52a7dc798aa.json} +1 -1
- package/.nyc_output/processinfo/index.json +1 -1
- package/README.md +12 -12
- package/config/hof-defaults.js +2 -8
- package/frontend/template-partials/translations/src/en/buttons.json +1 -0
- package/frontend/template-partials/translations/src/en/errors.json +4 -0
- package/frontend/template-partials/views/layout.html +2 -1
- package/frontend/template-partials/views/partials/session-timeout-warning.html +27 -0
- package/frontend/themes/gov-uk/client-js/dialog/index.js +361 -0
- package/frontend/themes/gov-uk/client-js/dialog/utils.js +114 -0
- package/frontend/themes/gov-uk/client-js/index.js +1 -0
- package/frontend/themes/gov-uk/styles/govuk.scss +1 -0
- package/frontend/themes/gov-uk/styles/modules/_dialogs.scss +113 -0
- package/frontend/toolkit/assets/stylesheets/app.scss +1 -0
- package/frontend/toolkit/assets/stylesheets/modules/_dialogs.scss +113 -0
- package/middleware/session-timeout.js +23 -0
- package/package.json +1 -1
- package/sandbox/apps/sandbox/behaviours/extend-session.js +9 -0
- package/sandbox/assets/scss/app.scss +1 -1
- package/sandbox/package.json +1 -1
- package/sandbox/public/css/app.css +109 -0
- package/sandbox/public/js/bundle.js +12347 -1149
- package/sandbox/yarn.lock +6 -1
- package/.nyc_output/c84e394d-abf7-4aea-99aa-36427e671442.json +0 -1
- package/frontend/template-partials/views/partials/warn.html +0 -7
@@ -0,0 +1,114 @@
|
|
1
|
+
'use strict';
|
2
|
+
/**
|
3
|
+
* @namespace aria
|
4
|
+
*/
|
5
|
+
|
6
|
+
window.aria = window.aria || {};
|
7
|
+
|
8
|
+
(function () {
|
9
|
+
// eslint-disable-next-line no-console
|
10
|
+
// console.log('TEST UTILS.js', aria);
|
11
|
+
})();
|
12
|
+
|
13
|
+
window.aria.Utils = window.aria.Utils || {};
|
14
|
+
|
15
|
+
// Polyfill src https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
|
16
|
+
window.aria.Utils.matches = function (element, selector) {
|
17
|
+
if (!Element.prototype.matches) {
|
18
|
+
Element.prototype.matches =
|
19
|
+
Element.prototype.matchesSelector ||
|
20
|
+
Element.prototype.mozMatchesSelector ||
|
21
|
+
Element.prototype.msMatchesSelector ||
|
22
|
+
Element.prototype.oMatchesSelector ||
|
23
|
+
Element.prototype.webkitMatchesSelector ||
|
24
|
+
function (s) {
|
25
|
+
const matches = element.parentNode.querySelectorAll(s);
|
26
|
+
let i = matches.length;
|
27
|
+
while (--i >= 0 && matches.item(i) !== this) {
|
28
|
+
// empty
|
29
|
+
}
|
30
|
+
return i > -1;
|
31
|
+
};
|
32
|
+
}
|
33
|
+
|
34
|
+
return element.matches(selector);
|
35
|
+
};
|
36
|
+
|
37
|
+
window.aria.Utils.remove = function (item) {
|
38
|
+
if (item.remove && typeof item.remove === 'function') {
|
39
|
+
return item.remove();
|
40
|
+
}
|
41
|
+
if (
|
42
|
+
item.parentNode &&
|
43
|
+
item.parentNode.removeChild &&
|
44
|
+
typeof item.parentNode.removeChild === 'function'
|
45
|
+
) {
|
46
|
+
return item.parentNode.removeChild(item);
|
47
|
+
}
|
48
|
+
return false;
|
49
|
+
};
|
50
|
+
|
51
|
+
window.aria.Utils.isFocusable = function (element) {
|
52
|
+
if (element.tabIndex < 0) {
|
53
|
+
return false;
|
54
|
+
}
|
55
|
+
|
56
|
+
if (element.disabled) {
|
57
|
+
return false;
|
58
|
+
}
|
59
|
+
|
60
|
+
switch (element.nodeName) {
|
61
|
+
case 'A':
|
62
|
+
return !!element.href && element.rel !== 'ignore';
|
63
|
+
case 'INPUT':
|
64
|
+
return element.type !== 'hidden';
|
65
|
+
case 'BUTTON':
|
66
|
+
case 'SELECT':
|
67
|
+
case 'TEXTAREA':
|
68
|
+
return true;
|
69
|
+
default:
|
70
|
+
return false;
|
71
|
+
}
|
72
|
+
};
|
73
|
+
|
74
|
+
window.aria.Utils.getAncestorBySelector = function (element, selector) {
|
75
|
+
if (!window.aria.Utils.matches(element, selector + ' ' + element.tagName)) {
|
76
|
+
// Element is not inside an element that matches selector
|
77
|
+
return null;
|
78
|
+
}
|
79
|
+
|
80
|
+
// Move up the DOM tree until a parent matching the selector is found
|
81
|
+
let currentNode = element;
|
82
|
+
let ancestor = null;
|
83
|
+
while (ancestor === null) {
|
84
|
+
if (window.aria.Utils.matches(currentNode.parentNode, selector)) {
|
85
|
+
ancestor = currentNode.parentNode;
|
86
|
+
} else {
|
87
|
+
currentNode = currentNode.parentNode;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
return ancestor;
|
92
|
+
};
|
93
|
+
|
94
|
+
window.aria.Utils.hasClass = function (element, className) {
|
95
|
+
return new RegExp('(\\s|^)' + className + '(\\s|$)').test(element.className);
|
96
|
+
};
|
97
|
+
|
98
|
+
window.aria.Utils.addClass = function (element, className) {
|
99
|
+
if (!window.aria.Utils.hasClass(element, className)) {
|
100
|
+
element.className += ' ' + className;
|
101
|
+
}
|
102
|
+
};
|
103
|
+
|
104
|
+
window.aria.Utils.removeClass = function (element, className) {
|
105
|
+
const classRegex = new RegExp('(\\s|^)' + className + '(\\s|$)');
|
106
|
+
element.className = element.className.replace(classRegex, ' ').trim();
|
107
|
+
};
|
108
|
+
|
109
|
+
window.aria.Utils.bindMethods = function (object /* , ...methodNames */) {
|
110
|
+
const methodNames = Array.prototype.slice.call(arguments, 1);
|
111
|
+
methodNames.forEach(function (method) {
|
112
|
+
object[method] = object[method].bind(object);
|
113
|
+
});
|
114
|
+
};
|
@@ -11,6 +11,7 @@ var validation = toolkit.validation;
|
|
11
11
|
var GOVUK = require('govuk-frontend');
|
12
12
|
GOVUK.initAll();
|
13
13
|
window.GOVUK = GOVUK;
|
14
|
+
var dialog = require('./dialog');
|
14
15
|
var skipToMain = require('./skip-to-main');
|
15
16
|
var cookie = require('./govuk-cookies');
|
16
17
|
var cookieSettings = require('./cookieSettings');
|
@@ -0,0 +1,113 @@
|
|
1
|
+
.hidden {
|
2
|
+
display: none;
|
3
|
+
}
|
4
|
+
|
5
|
+
[role="dialog"] {
|
6
|
+
box-sizing: border-box;
|
7
|
+
padding: 15px;
|
8
|
+
border: 1px solid #000;
|
9
|
+
background-color: #fff;
|
10
|
+
min-height: 100vh;
|
11
|
+
}
|
12
|
+
|
13
|
+
@media screen and (min-width: 640px) {
|
14
|
+
[role="dialog"] {
|
15
|
+
position: absolute;
|
16
|
+
top: 25vh;
|
17
|
+
left: 50vw; /* move to the middle of the screen (assumes relative parent is the body/viewport) */
|
18
|
+
transform: translateX(
|
19
|
+
-50%
|
20
|
+
); /* move backwards 50% of this element's width */
|
21
|
+
min-width: calc(640px - (15px * 2)); /* == breakpoint - left+right margin */
|
22
|
+
min-height: auto;
|
23
|
+
box-shadow: 0 19px 38px rgb(0 0 0 / 12%), 0 15px 12px rgb(0 0 0 / 22%);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
.dialog_form {
|
28
|
+
margin: 15px;
|
29
|
+
}
|
30
|
+
|
31
|
+
.dialog_form .label_text {
|
32
|
+
box-sizing: border-box;
|
33
|
+
padding-right: 0.5em;
|
34
|
+
display: inline-block;
|
35
|
+
font-size: 16px;
|
36
|
+
font-weight: bold;
|
37
|
+
width: 30%;
|
38
|
+
text-align: right;
|
39
|
+
}
|
40
|
+
|
41
|
+
.dialog_form .label_info {
|
42
|
+
box-sizing: border-box;
|
43
|
+
padding-right: 0.5em;
|
44
|
+
font-size: 12px;
|
45
|
+
width: 30%;
|
46
|
+
text-align: right;
|
47
|
+
display: inline-block;
|
48
|
+
}
|
49
|
+
|
50
|
+
.dialog_form_item {
|
51
|
+
margin: 10px 0;
|
52
|
+
font-size: 0;
|
53
|
+
}
|
54
|
+
|
55
|
+
.dialog_form_item .wide_input {
|
56
|
+
box-sizing: border-box;
|
57
|
+
max-width: 70%;
|
58
|
+
width: 27em;
|
59
|
+
}
|
60
|
+
|
61
|
+
.dialog_form_actions {
|
62
|
+
text-align: right;
|
63
|
+
padding: 0 20px 20px;
|
64
|
+
}
|
65
|
+
|
66
|
+
.dialog_close_button {
|
67
|
+
float: right;
|
68
|
+
position: absolute;
|
69
|
+
top: 10px;
|
70
|
+
left: 92%;
|
71
|
+
height: 25px;
|
72
|
+
}
|
73
|
+
|
74
|
+
.dialog_close_button img {
|
75
|
+
border: 0;
|
76
|
+
}
|
77
|
+
|
78
|
+
.dialog_desc {
|
79
|
+
padding: 10px 20px;
|
80
|
+
}
|
81
|
+
|
82
|
+
/* native <dialog> element uses the ::backdrop pseudo-element */
|
83
|
+
|
84
|
+
/* dialog::backdrop, */
|
85
|
+
.dialog-backdrop {
|
86
|
+
display: none;
|
87
|
+
position: fixed;
|
88
|
+
overflow-y: auto;
|
89
|
+
top: 0;
|
90
|
+
right: 0;
|
91
|
+
bottom: 0;
|
92
|
+
left: 0;
|
93
|
+
z-index: 1;
|
94
|
+
}
|
95
|
+
|
96
|
+
@media screen and (min-width: 640px) {
|
97
|
+
.dialog-backdrop {
|
98
|
+
background: rgb(0 0 0 / 30%);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
.dialog-backdrop.active {
|
103
|
+
display: block;
|
104
|
+
}
|
105
|
+
|
106
|
+
.no-scroll {
|
107
|
+
overflow-y: auto !important;
|
108
|
+
}
|
109
|
+
|
110
|
+
/* this is added to the body when a dialog is open */
|
111
|
+
.has-dialog {
|
112
|
+
overflow: hidden;
|
113
|
+
}
|
@@ -0,0 +1,113 @@
|
|
1
|
+
.hidden {
|
2
|
+
display: none;
|
3
|
+
}
|
4
|
+
|
5
|
+
[role="dialog"] {
|
6
|
+
box-sizing: border-box;
|
7
|
+
padding: 15px;
|
8
|
+
border: 1px solid #000;
|
9
|
+
background-color: #fff;
|
10
|
+
min-height: 100vh;
|
11
|
+
}
|
12
|
+
|
13
|
+
@media screen and (min-width: 640px) {
|
14
|
+
[role="dialog"] {
|
15
|
+
position: absolute;
|
16
|
+
top: 25vh;
|
17
|
+
left: 50vw; /* move to the middle of the screen (assumes relative parent is the body/viewport) */
|
18
|
+
transform: translateX(
|
19
|
+
-50%
|
20
|
+
); /* move backwards 50% of this element's width */
|
21
|
+
min-width: calc(640px - (15px * 2)); /* == breakpoint - left+right margin */
|
22
|
+
min-height: auto;
|
23
|
+
box-shadow: 0 19px 38px rgb(0 0 0 / 12%), 0 15px 12px rgb(0 0 0 / 22%);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
.dialog_form {
|
28
|
+
margin: 15px;
|
29
|
+
}
|
30
|
+
|
31
|
+
.dialog_form .label_text {
|
32
|
+
box-sizing: border-box;
|
33
|
+
padding-right: 0.5em;
|
34
|
+
display: inline-block;
|
35
|
+
font-size: 16px;
|
36
|
+
font-weight: bold;
|
37
|
+
width: 30%;
|
38
|
+
text-align: right;
|
39
|
+
}
|
40
|
+
|
41
|
+
.dialog_form .label_info {
|
42
|
+
box-sizing: border-box;
|
43
|
+
padding-right: 0.5em;
|
44
|
+
font-size: 12px;
|
45
|
+
width: 30%;
|
46
|
+
text-align: right;
|
47
|
+
display: inline-block;
|
48
|
+
}
|
49
|
+
|
50
|
+
.dialog_form_item {
|
51
|
+
margin: 10px 0;
|
52
|
+
font-size: 0;
|
53
|
+
}
|
54
|
+
|
55
|
+
.dialog_form_item .wide_input {
|
56
|
+
box-sizing: border-box;
|
57
|
+
max-width: 70%;
|
58
|
+
width: 27em;
|
59
|
+
}
|
60
|
+
|
61
|
+
.dialog_form_actions {
|
62
|
+
text-align: right;
|
63
|
+
padding: 0 20px 20px;
|
64
|
+
}
|
65
|
+
|
66
|
+
.dialog_close_button {
|
67
|
+
float: right;
|
68
|
+
position: absolute;
|
69
|
+
top: 10px;
|
70
|
+
left: 92%;
|
71
|
+
height: 25px;
|
72
|
+
}
|
73
|
+
|
74
|
+
.dialog_close_button img {
|
75
|
+
border: 0;
|
76
|
+
}
|
77
|
+
|
78
|
+
.dialog_desc {
|
79
|
+
padding: 10px 20px;
|
80
|
+
}
|
81
|
+
|
82
|
+
/* native <dialog> element uses the ::backdrop pseudo-element */
|
83
|
+
|
84
|
+
/* dialog::backdrop, */
|
85
|
+
.dialog-backdrop {
|
86
|
+
display: none;
|
87
|
+
position: fixed;
|
88
|
+
overflow-y: auto;
|
89
|
+
top: 0;
|
90
|
+
right: 0;
|
91
|
+
bottom: 0;
|
92
|
+
left: 0;
|
93
|
+
z-index: 1;
|
94
|
+
}
|
95
|
+
|
96
|
+
@media screen and (min-width: 640px) {
|
97
|
+
.dialog-backdrop {
|
98
|
+
background: rgb(0 0 0 / 30%);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
.dialog-backdrop.active {
|
103
|
+
display: block;
|
104
|
+
}
|
105
|
+
|
106
|
+
.no-scroll {
|
107
|
+
overflow-y: auto !important;
|
108
|
+
}
|
109
|
+
|
110
|
+
/* this is added to the body when a dialog is open */
|
111
|
+
.has-dialog {
|
112
|
+
overflow: hidden;
|
113
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
module.exports = (options, timers) => {
|
4
|
+
return (req, res, next) => {
|
5
|
+
// eslint-disable-next-line no-console
|
6
|
+
console.log(req.url, 'SESSION TIMOUT:', options.session);
|
7
|
+
if (timers.length >= 2) {
|
8
|
+
// eslint-disable-next-line no-console
|
9
|
+
console.log(timers);
|
10
|
+
for (const t of timers) {
|
11
|
+
clearTimeout(t);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
timers.push(setTimeout(() => {
|
15
|
+
// eslint-disable-next-line no-console,no-alert
|
16
|
+
console.log(req.originalUrl);
|
17
|
+
const err = new Error('Session will expire soon');
|
18
|
+
err.code = 'SESSION_TIMEOUT_WARNING';
|
19
|
+
return next(err);
|
20
|
+
}, 1000 * 10));
|
21
|
+
next();
|
22
|
+
};
|
23
|
+
};
|
package/package.json
CHANGED
package/sandbox/package.json
CHANGED
@@ -9318,6 +9318,115 @@ fieldset + .reveal {
|
|
9318
9318
|
margin-top: 0;
|
9319
9319
|
}
|
9320
9320
|
|
9321
|
+
.hidden {
|
9322
|
+
display: none;
|
9323
|
+
}
|
9324
|
+
|
9325
|
+
[role=dialog] {
|
9326
|
+
box-sizing: border-box;
|
9327
|
+
padding: 15px;
|
9328
|
+
border: 1px solid #000;
|
9329
|
+
background-color: #fff;
|
9330
|
+
min-height: 100vh;
|
9331
|
+
}
|
9332
|
+
|
9333
|
+
@media screen and (min-width: 640px) {
|
9334
|
+
[role=dialog] {
|
9335
|
+
position: absolute;
|
9336
|
+
top: 25vh;
|
9337
|
+
left: 50vw; /* move to the middle of the screen (assumes relative parent is the body/viewport) */
|
9338
|
+
transform: translateX(-50%); /* move backwards 50% of this element's width */
|
9339
|
+
min-width: 610px; /* == breakpoint - left+right margin */
|
9340
|
+
min-height: auto;
|
9341
|
+
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.12), 0 15px 12px rgba(0, 0, 0, 0.22);
|
9342
|
+
}
|
9343
|
+
}
|
9344
|
+
.dialog_form {
|
9345
|
+
margin: 15px;
|
9346
|
+
}
|
9347
|
+
|
9348
|
+
.dialog_form .label_text {
|
9349
|
+
box-sizing: border-box;
|
9350
|
+
padding-right: 0.5em;
|
9351
|
+
display: inline-block;
|
9352
|
+
font-size: 16px;
|
9353
|
+
font-weight: bold;
|
9354
|
+
width: 30%;
|
9355
|
+
text-align: right;
|
9356
|
+
}
|
9357
|
+
|
9358
|
+
.dialog_form .label_info {
|
9359
|
+
box-sizing: border-box;
|
9360
|
+
padding-right: 0.5em;
|
9361
|
+
font-size: 12px;
|
9362
|
+
width: 30%;
|
9363
|
+
text-align: right;
|
9364
|
+
display: inline-block;
|
9365
|
+
}
|
9366
|
+
|
9367
|
+
.dialog_form_item {
|
9368
|
+
margin: 10px 0;
|
9369
|
+
font-size: 0;
|
9370
|
+
}
|
9371
|
+
|
9372
|
+
.dialog_form_item .wide_input {
|
9373
|
+
box-sizing: border-box;
|
9374
|
+
max-width: 70%;
|
9375
|
+
width: 27em;
|
9376
|
+
}
|
9377
|
+
|
9378
|
+
.dialog_form_actions {
|
9379
|
+
text-align: right;
|
9380
|
+
padding: 0 20px 20px;
|
9381
|
+
}
|
9382
|
+
|
9383
|
+
.dialog_close_button {
|
9384
|
+
float: right;
|
9385
|
+
position: absolute;
|
9386
|
+
top: 10px;
|
9387
|
+
left: 92%;
|
9388
|
+
height: 25px;
|
9389
|
+
}
|
9390
|
+
|
9391
|
+
.dialog_close_button img {
|
9392
|
+
border: 0;
|
9393
|
+
}
|
9394
|
+
|
9395
|
+
.dialog_desc {
|
9396
|
+
padding: 10px 20px;
|
9397
|
+
}
|
9398
|
+
|
9399
|
+
/* native <dialog> element uses the ::backdrop pseudo-element */
|
9400
|
+
/* dialog::backdrop, */
|
9401
|
+
.dialog-backdrop {
|
9402
|
+
display: none;
|
9403
|
+
position: fixed;
|
9404
|
+
overflow-y: auto;
|
9405
|
+
top: 0;
|
9406
|
+
right: 0;
|
9407
|
+
bottom: 0;
|
9408
|
+
left: 0;
|
9409
|
+
z-index: 1;
|
9410
|
+
}
|
9411
|
+
|
9412
|
+
@media screen and (min-width: 640px) {
|
9413
|
+
.dialog-backdrop {
|
9414
|
+
background: rgba(0, 0, 0, 0.3);
|
9415
|
+
}
|
9416
|
+
}
|
9417
|
+
.dialog-backdrop.active {
|
9418
|
+
display: block;
|
9419
|
+
}
|
9420
|
+
|
9421
|
+
.no-scroll {
|
9422
|
+
overflow-y: auto !important;
|
9423
|
+
}
|
9424
|
+
|
9425
|
+
/* this is added to the body when a dialog is open */
|
9426
|
+
.has-dialog {
|
9427
|
+
overflow: hidden;
|
9428
|
+
}
|
9429
|
+
|
9321
9430
|
.maxlength-hint {
|
9322
9431
|
margin-top: 2px;
|
9323
9432
|
padding-top: 2px;
|