Skip to content

Commit

Permalink
Merge branch 'master' into SDT-remove-component-library-template
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-leggett authored Jun 4, 2018
2 parents 7e6fae4 + 4dca734 commit 3674058
Show file tree
Hide file tree
Showing 10 changed files with 1,305 additions and 228 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Timeout documentation and examples [#949](https://github.com/hmrc/assets-frontend/pull/949)
- Page not found, service unavailable and there is a problem with the service examples [#947](https://github.com/hmrc/assets-frontend/pull/947)
- Markup example and tests for Account Menu and Account Header [#961](https://github.com/hmrc/assets-frontend/pull/961)
- The timeout dialog has been heavily refactored with full test coverage, a new preferred interface has been added as `govuk.timeoutDialog()` while still supporting `$.timeoutDialog()` with its current form [#957](https://github.com/hmrc/assets-frontend/pull/957)

### Added
- New pattern for asking users for their consent to meet GDPR and DPA standards [#962](https://github.com/hmrc/assets-frontend/pull/962)
Expand Down
1 change: 0 additions & 1 deletion assets/components/account-menu/account-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,6 @@ module.exports = function () {
})
setTimeout(function () {
subNav.focus()
console.log(document.activeElement)
}, 500)

showSubnavLink
Expand Down
4 changes: 3 additions & 1 deletion assets/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ var timeoutDialog = require('../patterns/help-users-when-we-time-them-out-of-a-s
;(function ($, window, document) {
accountMenu()
charCounter()
$.timeoutDialog = timeoutDialog
window.GOVUK = window.GOVUK || {}
window.GOVUK.timeoutDialog = timeoutDialog.timeoutDialog
$.timeoutDialog = timeoutDialog.legacyWrapper
})(window.jQuery, window, document)
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# Help users when we time them out of a service

This pattern warns someone before we are going to time them out of a service and what to tell them if we do.
This pattern warns someone before we are going to time them out of a service and what to tell them if we do time them out.

{{ example("timeout.html", true) }}

## When to use this pattern

Warn a user we are going to time them out when they do not do anything for 13 minutes. This gives them 2 minutes to decide to stay signed in.
Warn a user we are going to time them out when they do not do anything for 13 minutes. This gives them 2 minutes to decide to keep using the service.

The warning helps make a service more accessible.
The warning makes a service more accessible.

Automatically take them to a page that tells them what has happened after 15 minutes.

## How the pattern works

The pattern uses an accessible dialog box that appears on top of the page. They will not be able to use the screen with mouse or keyboard until they select an option or dismiss the dialog box.
The pattern uses an accessible dialog box that appears on top of the page. This stops them using the screen with a mouse or keyboard until they select an option or press the escape key.

The user can:

- select a button to stop being timed out
- select a link
- press the escape key to close the warning and stop being timed out without refreshing the page
- select a link to sign out or have their answers deleted
- press the escape key to close the warning and stop being timed out
- do nothing

### When they are signed in to the service
Expand All @@ -32,7 +32,7 @@ The warning should:
- have a “Stay signed in” button
- have a “Sign out” link that signs them out as normal

If they do nothing, take them to a page that uses content that complements the warning box.
If they do nothing, take them to a “We signed you out” page that uses similar content as the warning box.

#### Warning

Expand Down Expand Up @@ -78,25 +78,21 @@ Add the timeout-dialog.js file and call the timeoutDialog method on a service’

```
$.timeoutDialog({
timeout: 900,
countdown: 120,
keep_alive_url: '/keep-alive',
logout_url: '/sign-out',
keep_alive_button_text: 'Get another 15 minutes',
sign_out_button_text: 'Sign out'
timeout: 900,
countdown: 120,
keepAliveUrl: '/keep-alive',
signOutUrl: '/sign-out'
});
```

From timeout-dialog.js:

- timeout is the number of seconds before you are timed out 900 is the platform default
- timeout is the number of seconds before you are timed out and 900 is the platform default
- countdown is the number of seconds before the timeout the warning is displayed
- keep_alive_url is a call to the server that keeps them in the service without refreshing the page
- logout_url is the same URL as your service’s sign out page
- keep_alive_button_text is the default content for the button you will need to change
- sign_out_button_text is the default content for the button you may need to change

When the dialog box loads:
When the warning loads:

- set focus to the box
- read the paragraph of content
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
module.exports = {
displayDialog: function ($elementToDisplay) {
var $dialog = $('<div id="timeout-dialog" tabindex="-1" role="dialog" class="timeout-dialog">')
.append($elementToDisplay)
var $overlay = $('<div id="timeout-overlay" class="timeout-overlay">')
var resetElementsFunctionList = []
var closeCallbacks = []

if (!$('html').hasClass('noScroll')) {
$('html').addClass('noScroll')
resetElementsFunctionList.push(function () {
$('html').removeClass('noScroll')
})
}
$('body').append($dialog).append($overlay)

resetElementsFunctionList.push(function () {
$dialog.remove()
$overlay.remove()
})

// disable the non-dialog page to prevent confusion for VoiceOver users
$('#skiplink-container, body>header, #global-cookie-message, body>main, body>footer').each(function () {
var value = $(this).attr('aria-hidden')
var $elem = $(this)
resetElementsFunctionList.push(function () {
if (value) {
$elem.attr('aria-hidden', value)
} else {
$elem.removeAttr('aria-hidden')
}
})
}).attr('aria-hidden', 'true')

setupFocusHandlerAndFocusDialog()
setupKeydownHandler()
preventMobileScrollWhileAllowingPinchZoom()

function close() {
while (resetElementsFunctionList.length > 0) {
var fn = resetElementsFunctionList.shift()
fn()
}
}

function closeAndInform() {
$.each(closeCallbacks, function () {
var fn = this
fn()
})
close()
}

function setupFocusHandlerAndFocusDialog() {
function keepFocus(event) {
var modalFocus = document.getElementById('timeout-dialog')
if (modalFocus) {
if (event.target !== modalFocus && !modalFocus.contains(event.target)) {
event.stopPropagation()
modalFocus.focus()
}
}
}

var elemToFocusOnReset = document.activeElement
$dialog.focus()

$(document).on('focus', '*', keepFocus)

resetElementsFunctionList.push(function () {
$(document).off('focus', '*', keepFocus)
$(elemToFocusOnReset).focus()
})
}

function setupKeydownHandler() {
function keydownListener(e) {
if (e.keyCode === 27) {
closeAndInform()
}
}

$(document).on('keydown', keydownListener)

resetElementsFunctionList.push(function () {
$(document).off('keydown', keydownListener)
})
}

function preventMobileScrollWhileAllowingPinchZoom() {
function handleTouch(e) {
var touches = e.originalEvent.touches || e.originalEvent.changedTouches || []

if (touches.length === 1) {
e.preventDefault()
}
}

$(document).on('touchmove', handleTouch)

resetElementsFunctionList.push(function () {
$(document).off('touchmove', handleTouch)
})
}

function createSetterFunctionForAttributeOfDialog(attributeName) {
return function (value) {
if (value) {
$dialog.attr(attributeName, value)
} else {
$dialog.removeAttr(attributeName)
}
}
}

return {
closeDialog: function () {
close()
},
setAriaLive: createSetterFunctionForAttributeOfDialog('aria-live'),
setAriaLabelledBy: createSetterFunctionForAttributeOfDialog('aria-labelledby'),
addCloseHandler: function (closeHandler) {
closeCallbacks.push(closeHandler)
}
}
}
}
Loading

0 comments on commit 3674058

Please sign in to comment.