Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/accessibility #56

Merged
merged 25 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
98c0d2c
Fixes aria-live, clicking outside of lightbox, and hides elements fro…
cayb0rg Jun 29, 2023
e0c5e1f
Reads next question title on next
cayb0rg Jun 29, 2023
93a64f9
Add focus directive to player and controls to select this or that
cayb0rg Jun 29, 2023
d73efe2
Forgot ng-keydown exists
cayb0rg Jun 29, 2023
ff74833
Moves keydown listener to html, seems to work now
cayb0rg Jun 29, 2023
d321d51
Fix auto-focusing, aria-labelling, tab order
cayb0rg Jul 3, 2023
26a0af2
Adds tab loop and removes extra alert at end
cayb0rg Jul 5, 2023
a55249c
Fix Next not focusing 100% of the time
cayb0rg Jul 6, 2023
474cbcc
Merge branch 'master' into issue/accessibility
cayb0rg Jul 6, 2023
8249df9
Fix Continue to Scores not focusing
cayb0rg Jul 6, 2023
18dbe86
Add splashText to gameState tests
cayb0rg Jul 6, 2023
53d28c6
Moves instructions to button, adds H key for keyboard controls, fixes…
cayb0rg Jul 17, 2023
a18d5b6
Add tests for coverage
cayb0rg Jul 18, 2023
74403d1
Adds instruction modal and feedback aria labels to correct and incorr…
cayb0rg Jul 25, 2023
36e24b6
Fix a few aria labels and modify instructions
cayb0rg Jul 26, 2023
3f1e316
Adds questions remaining button to top right
cayb0rg Jul 26, 2023
3d340d6
Meet test coverage
cayb0rg Jul 27, 2023
088efc3
Update install.yaml
cayb0rg Jul 31, 2023
ea0a67d
Fixes font, tab loop, controls keybind, updates question remaining el…
cayb0rg Aug 2, 2023
86ab5ce
Forgot to update instructions with keybinding
cayb0rg Aug 2, 2023
505f699
Adds instructions for audio and video
cayb0rg Aug 2, 2023
725947f
Set innertext
cayb0rg Aug 2, 2023
3651f03
Fixes for firefox
cayb0rg Aug 2, 2023
2d4bd20
Fixes aria-live regions for chrome
cayb0rg Aug 3, 2023
fc50e70
Adds assistive alert mock and test coverage
cayb0rg Aug 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 94 additions & 10 deletions src/controllers/ctl-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export const shuffleArray = array => {

// helper function to update the aria-live status region
// angular binding does not cooperate well with aria-live, so we update the DOM element directly instead
export const assistiveAlert = (alert) => {
if (document.getElementById('assistive-alert')) document.getElementById('assistive-alert').innerHTML = alert
export const assistiveAlert = ($scope, alert) => {
$scope.assistiveAlertText = alert
}

export const getAllAnswerChoices = ($sce, _qset) => {
Expand Down Expand Up @@ -79,6 +79,7 @@ export const showNextQuestion = $scope => {

$scope.question.selected = false
$scope.question.transition = false
$scope.selectedChoice = -1
} else {
endGame($scope)
}
Expand All @@ -89,6 +90,7 @@ export const endGame = $scope => {
$scope.gameState.endgame = true
Materia.Engine.end(false)
$scope.title = ''
$scope.continueToScores = true
$scope.$apply()
}

Expand All @@ -97,6 +99,9 @@ export const viewScores = () => {
}

export const checkChoice = ($scope, value) => {
if ($scope.question.selected)
return;

// value is 0 or 1
//get the id, value, and text of the chosen answer
const curItem = _qset.items[$scope.question.current]
Expand All @@ -109,13 +114,13 @@ export const checkChoice = ($scope, value) => {
case 0:
$scope.question.correct[value] = 'Incorrect'
$scope.answers[value].options.feedback = _feedback || (curItem.options && curItem.options.feedback ? curItem.options.feedback : '')
assistiveAlert("Your selection was incorrect.")
assistiveAlert($scope, "Your selection was incorrect. " + _feedback)
break

case 100:
$scope.question.correct[value] = 'Correct!'
$scope.answers[value].options.feedback = _feedback || ''
assistiveAlert("Your selection was correct.")
assistiveAlert($scope, "Your selection was correct. " + _feedback)
break
}

Expand Down Expand Up @@ -146,23 +151,31 @@ export const nextClicked = ($scope, $timeout) => {
$scope.question.transition = true
$scope.hands.thisRaised = false
$scope.hands.thatRaised = false
$scope.reachedFocusEnd = true

if (($scope.question.current + 1) < $scope.questionCount) assistiveAlert("Now on question " + ($scope.question.current + 1) + " of " + $scope.questionCount)
else assistiveAlert("You have completed every question")
if (($scope.question.current + 1) < $scope.questionCount) assistiveAlert($scope, "Now on question " + ($scope.question.current + 2) + " of " + $scope.questionCount + ": " + _qset.items[$scope.question.current + 1].questions[0].text)

$timeout(showNextQuestion.bind(null, $scope), 1000)
$timeout(showNextQuestion.bind(null, $scope), 1200)
}

export const closeIntro = $scope => {
$scope.gameState.ingame = true
$scope.resetFocus = true
assistiveAlert($scope, "Question " + ($scope.question.current + 1) + " of " + $scope.questionCount + ": " + _qset.items[$scope.question.current].questions[0].text)
}

export const toggleInstructions = $scope => {
// Since aria-live is only read if there's a change in text, there are two descriptions so that if H is pressed more than one time, it will still be read out.
$scope.instructionsOpen = !$scope.instructionsOpen
}

export const ControllerThisOrThatPlayer = function($scope, $timeout, $sce) {
$scope.gameState = {
ingame: false,
endgame: false,
score: 0,
showNext: false
showNext: false,
splashText: "This or That"
}

$scope.question = {
Expand All @@ -189,11 +202,53 @@ export const ControllerThisOrThatPlayer = function($scope, $timeout, $sce) {
$scope.checkChoice = checkChoice.bind(null, $scope)
$scope.nextClicked = nextClicked.bind(null, $scope, $timeout)
$scope.closeIntro = closeIntro.bind(null, $scope)
$scope.toggleInstructions = toggleInstructions.bind(null, $scope)
$scope.instructionsOpen = false
$scope.selectedChoice = -1

$scope.lightboxTarget = -1

$scope.focusThisExpand = false
$scope.focusThatExpand = false
$scope.resetFocus = false;

$scope.pressedQOnce = false
$scope.pressedH = false
$scope.assistiveAlertText = ""

// Opens or closes the image lightbox
// Values of val:
// ---- 0 : open image for "this" option
// ---- 1 : open image for "that" option
// ---- -1 : close image
$scope.setLightboxTarget = (val) => {
$scope.lightboxTarget = val
// Open the lightbox
if (val == 0 || val == 1)
{
assistiveAlert($scope, "Viewing image.")
$scope.lightboxTarget = val
}
// Close the lightbox
else
{
assistiveAlert($scope, "Closed image viewer.")
// If image for "this" option is currently open, focus "this" option's expand image button
if ($scope.lightboxTarget == 0)
{
$scope.focusThisExpand = true
setTimeout(() => {
$scope.focusThisExpand = false
}, 1000)
}
// Else focus "that" option's expand image button
else if ($scope.lightboxTarget == 1)
{
$scope.focusThatExpand = true
setTimeout(() => {
$scope.focusThatExpand = false
}, 1000)
}
$scope.lightboxTarget = -1
}
}

$scope.lightboxZoom = 0
Expand All @@ -202,6 +257,35 @@ export const ControllerThisOrThatPlayer = function($scope, $timeout, $sce) {
$scope.lightboxZoom = val
}

$scope.selectChoice = (event) => {
if ($scope.gameState.ingame)
{
// Focus this
if (event.key == 'a' || event.key == 'A') {
$scope.selectedChoice = 0;
}
// Focus that
else if (event.key == 'd' || event.key == 'D') {
$scope.selectedChoice = 1;
}
// Read question info, have two descriptions that are identical except for two colons in second one
// so that screenreader detects a change in the aria-live region
else if (event.key == 'q' || event.key == 'Q') {
if (!$scope.pressedQOnce)
{
assistiveAlert($scope, "Question " + ($scope.question.current + 1) + " of " + $scope.questionCount + ": " + _qset.items[$scope.question.current].questions[0].text)
$scope.pressedQOnce = true
}
else {
assistiveAlert($scope, "Question " + ($scope.question.current + 1) + " of " + $scope.questionCount + ":: " + _qset.items[$scope.question.current].questions[0].text)
$scope.pressedQOnce = false
}
} else if (event.key == 'Escape') {
toggleInstructions($scope);
}
} else if (event.key == 'Escape') toggleInstructions($scope);
}

$scope.getAdjustedTextSize = (text) => {
if (text.length < 140) return 28
else {
Expand Down
8 changes: 3 additions & 5 deletions src/demo.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,11 @@
"materiaType": "asset",
"value": "https://www.youtube.com/embed/dQw4w9WgXcQ",
"type": "video"
}
},
"feedback": "You are less likely to get rick rolled in a forest."
}
}
],
"options": {
"feedback": "You are less likely to get rick rolled in a forest."
}
]
},
{
"materiaType": "question",
Expand Down
5 changes: 5 additions & 0 deletions src/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ meta_data:
- Media
- Scorable
- Mobile Friendly
accessibility_keyboard: Full # values can be Full | Limited | None
accessibility_reader: Full # values can be Full | Limited | None
accessibility_description: >
Supports standard navigation. Includes custom controls to supplement standard navigation.
These controls are communicated visually and to screenreaders.
supported_data:
- Multiple Choice
about: >
Expand Down
Loading
Loading