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.
Files changed (26) hide show
  1. package/.nyc_output/2194bc4f-7454-4356-80e2-e52a7dc798aa.json +1 -0
  2. package/.nyc_output/processinfo/{c84e394d-abf7-4aea-99aa-36427e671442.json → 2194bc4f-7454-4356-80e2-e52a7dc798aa.json} +1 -1
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/README.md +12 -12
  5. package/config/hof-defaults.js +2 -8
  6. package/frontend/template-partials/translations/src/en/buttons.json +1 -0
  7. package/frontend/template-partials/translations/src/en/errors.json +4 -0
  8. package/frontend/template-partials/views/layout.html +2 -1
  9. package/frontend/template-partials/views/partials/session-timeout-warning.html +27 -0
  10. package/frontend/themes/gov-uk/client-js/dialog/index.js +361 -0
  11. package/frontend/themes/gov-uk/client-js/dialog/utils.js +114 -0
  12. package/frontend/themes/gov-uk/client-js/index.js +1 -0
  13. package/frontend/themes/gov-uk/styles/govuk.scss +1 -0
  14. package/frontend/themes/gov-uk/styles/modules/_dialogs.scss +113 -0
  15. package/frontend/toolkit/assets/stylesheets/app.scss +1 -0
  16. package/frontend/toolkit/assets/stylesheets/modules/_dialogs.scss +113 -0
  17. package/middleware/session-timeout.js +23 -0
  18. package/package.json +1 -1
  19. package/sandbox/apps/sandbox/behaviours/extend-session.js +9 -0
  20. package/sandbox/assets/scss/app.scss +1 -1
  21. package/sandbox/package.json +1 -1
  22. package/sandbox/public/css/app.css +109 -0
  23. package/sandbox/public/js/bundle.js +12347 -1149
  24. package/sandbox/yarn.lock +6 -1
  25. package/.nyc_output/c84e394d-abf7-4aea-99aa-36427e671442.json +0 -1
  26. 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');
@@ -33,6 +33,7 @@ $path: "/public/images/" !default;
33
33
  @import "modules/buttons";
34
34
  @import "modules/lists";
35
35
  @import "modules/alerts";
36
+ @import "modules/dialogs";
36
37
  @import "modules/character-count";
37
38
 
38
39
  // Pages
@@ -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
+ }
@@ -25,6 +25,7 @@
25
25
  @import "modules/buttons";
26
26
  @import "modules/lists";
27
27
  @import "modules/alerts";
28
+ @import "modules/dialogs";
28
29
 
29
30
  // Pages
30
31
  @import "modules/confirm-page";
@@ -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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hof",
3
3
  "description": "A bootstrap for HOF projects",
4
- "version": "20.3.8-beta-gtm",
4
+ "version": "20.3.8-timeout-beta",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
7
7
  "author": "HomeOffice",
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ module.exports = SuperClass => class extends SuperClass {
4
+ getValues(req, res, next) {
5
+ // eslint-disable-next-line no-console
6
+ console.log(req.sessionModel);
7
+ next();
8
+ }
9
+ };
@@ -7,7 +7,7 @@
7
7
  border: 1px solid #ccc;
8
8
  width: 65%;
9
9
  }
10
-
10
+
11
11
  .tt-suggestion {
12
12
  padding: 0.5em;
13
13
 
@@ -16,7 +16,7 @@
16
16
  "author": "",
17
17
  "dependencies": {
18
18
  "govuk-frontend": "3.14",
19
- "jquery": "^3.6.0",
19
+ "jquery": "^3.6.1",
20
20
  "sass": "^1.53.0",
21
21
  "typeahead-aria": "^1.0.4"
22
22
  },
@@ -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;