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

Accessibility edits #40

Merged
merged 23 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cbd478d
added modal and aria descriptions to flipping pages
DynieM Sep 1, 2023
1003556
audiocontrol changes, install.yaml, keyboard instructions, and screan…
DynieM Sep 5, 2023
3fa8449
dialog/modal instructions and screen reader for switching pages
DynieM Sep 5, 2023
bb8a955
aria live alerts/notifications & keyboard function for moving between…
DynieM Sep 5, 2023
a6e1753
made page navigation arrows into buttons
DynieM Sep 6, 2023
3d6b377
fixed finish button and edited screenreader feature for switching pages
DynieM Sep 8, 2023
89744e0
fixed page buttons and instructions dialog
DynieM Sep 20, 2023
5f19fbf
fixed tabindex issues
DynieM Nov 8, 2023
f4e9a8e
added back assistiveAlert
DynieM Nov 21, 2023
91d61d6
screenreader says how many matches are left after a match is made
DynieM Dec 6, 2023
2100782
fixed undefined bug and added alert of how many matches are made afte…
DynieM Jan 8, 2024
4e870e8
removed comments made for debugging
DynieM Jan 8, 2024
6b64b52
fixed duplication error and added instructions for keyboard
DynieM Mar 7, 2024
edd4cbf
ignored launch.json
DynieM Mar 7, 2024
0122769
fixed whitespace and indentation
DynieM Mar 7, 2024
8d87e86
deleted .vscode/launch.json
DynieM Mar 14, 2024
b7d568c
Resolves yarn.lock merge conflict
clpetersonucf Apr 17, 2024
72a0a44
Merge conflict resolution with dev/2.1.0 part 1
clpetersonucf Apr 17, 2024
986b40a
changed insert code to set and remove attribute, also added checks fo…
DynieM May 9, 2024
aa42133
player.html fixed
DynieM May 9, 2024
d207875
fixed last inert issue
DynieM May 14, 2024
0ce4715
Fix indentation of accessibility metadata in install.yaml
clpetersonucf May 14, 2024
49a3189
Adjusts test coverage thresholds in package json
clpetersonucf Jun 11, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.3.1, 12.x]
node-version: [12.3.1]

steps:
- name: Checkout code
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ node_modules
bower_components
*build
coverage
.vscode/
8 changes: 5 additions & 3 deletions src/audioControls.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<div class='audio-controls'>
<span class='play-btn'
<button class='play-btn'
aria-label="Play audio clue."
ng-class="{'paused' : audio.paused}"
ng-click='$event.stopPropagation(); play()'>
</span>
ng-click='$event.stopPropagation(); play()'
ng-keypress="$event.stopPropagation()">
</button>
<span class='time'>
<span class='seek-bar'>
<input type='range'
Expand Down
148 changes: 135 additions & 13 deletions src/controllers/player.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,25 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
$scope.totalItems = 0
$scope.setCreated = false
$scope.helpVisible = false
$scope.completePerPage = []

$scope.unfinishedPagesBefore = false
$scope.unfinishedPagesAfter = false
helpModal = document.getElementById("instructions");
clpetersonucf marked this conversation as resolved.
Show resolved Hide resolved
helpModal.inert = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines were not causing any sort of console of behavioral failure, so they got overlooked when I reviewed your changes previously, but FYI this is not how you assign attributes to DOM elements in JS. Even though helpModal is referencing a DOM element object, attributes must be set (or removed) via the setAttribute or removeAttribute methods, like so:

helpModal.setAttribute('inert', '')

Bear in mind that inert doesn't require a value, so the mere existence of the attribute means the inert behavior will be applied. Therefore, helpModal.setAttribute('inert', 'false') wouldn't work to disable it. The attribute has to be removed completely with removeAttribute. This change will need to be applied on all lines that are trying to set or remove the inert attribute.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is still improperly trying to set the inert property on the DOM object directly, instead of using setAttribute(). It's causing the test suite to fail. Always remember to run yarn test before committing!



_assistiveAlert = (msg) ->
alertEl = document.getElementById('assistive-alert')
if alertEl then alertEl.innerHTML = msg


$scope.qset = {}

$scope.circumference = Math.PI * 80

_boardElement = document.getElementById('gameboard')

# these are used for animation
$scope.pageAnimate = false
$scope.pageNext = false
Expand All @@ -42,18 +53,22 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
CIRCLE_OFFSET = 40
PROGRESS_BAR_LENGTH = 160


materiaCallbacks.start = (instance, qset) ->
$scope.qset = qset
$scope.title = instance.name
$scope.totalItems = qset.items[0].items.length
$scope.totalPages = Math.ceil $scope.totalItems/ITEMS_PER_PAGE

document.title = instance.name + ' Materia widget'

# set up the pages
for [1..$scope.totalPages]
$scope.pages.push {questions:[], answers:[]}
$scope.selectedQA.push {question:-1, answer:-1}
$scope.questionCircles.push []
$scope.answerCircles.push []
$scope.completePerPage.push 0

_itemIndex = 0
_pageIndex = 0
Expand Down Expand Up @@ -144,13 +159,12 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
return false if direction == 'previous' and $scope.currentPage <= 0
return false if direction == 'next' and $scope.currentPage >= $scope.totalPages - 1


_clearSelections()
$scope.pageAnimate = true

$scope.pageNext = (direction == 'next')
$timeout ->
$scope.currentPage-- if direction == 'previous'
$scope.currentPage++ if direction == 'next'
_checkUnfinishedPages()
, ANIMATION_DURATION/3

Expand All @@ -159,28 +173,73 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
$scope.pageAnimate = false
, ANIMATION_DURATION*1.1

if _boardElement then _boardElement.focus()
if direction == 'next'
($scope.currentPage = $scope.currentPage + 1)
_assistiveAlert 'Page incremented. You are on the next page. There are ' + ($scope.completePerPage[$scope.currentPage] ?= 0) + ' out of ' + $scope.pages[$scope.currentPage].questions.length + ' matches done.'
else if direction == 'previous'
($scope.currentPage = $scope.currentPage - 1)
_assistiveAlert 'Page decremented. You are on the previous page. There are ' + ($scope.completePerPage[$scope.currentPage] ?= 0) + " out of " + $scope.pages[$scope.currentPage].questions.length + ' matches done.'

$scope.checkForQuestionAudio = (index) ->
$scope.pages[$scope.currentPage].questions[index].asset != undefined


$scope.checkForAnswerAudio = (index) ->
$scope.pages[$scope.currentPage].answers[index].asset != undefined




_updateCompletionStatus = () ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function appears to be causing the "___ of 5 remaining" issue. It resets the completePerPage array before refilling it using the matches each time a match is made. It would need another loop that finds pages with no matches, and sets those pages' counts to 0 in the completePerPage array.

The more efficient method may be to just replace the call to _updateCompletionStatus with $scope.completePerPage[$scope.currentPage]++ inside _pushMatch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!


$scope.completePerPage = []
for match in $scope.matches
if !$scope.completePerPage[match.matchPageId] then $scope.completePerPage[match.matchPageId] = 1
else $scope.completePerPage[match.matchPageId]+=1


_pushMatch = () ->
$scope.matches.push {
questionId: $scope.selectedQuestion.id
questionIndex: $scope.selectedQA[$scope.currentPage].question
answerId: $scope.selectedAnswer.id
answerIndex: $scope.selectedQA[$scope.currentPage].answer
matchPageId: $scope.currentPage
color: _getColor()
}

newMatch = {
questionId: $scope.selectedQuestion.id,
questionIndex: $scope.selectedQA[$scope.currentPage].question,
answerId: $scope.selectedAnswer.id,
answerIndex: $scope.selectedQA[$scope.currentPage].answer,
matchPageId: $scope.currentPage,
color: _getColor()
}

duplicateFound = false


for existingMatch in $scope.matches
if existingMatch.questionId == newMatch.questionId and existingMatch.answerId == newMatch.answerId
duplicateFound = true
break


if not duplicateFound
$scope.matches.push newMatch

_updateCompletionStatus()

if($scope.totalItems == $scope.matches.length)
_assistiveAlert 'All matches have been made. You may now submit your answers.'
else
_assistiveAlert 'Match made. There are ' + ($scope.totalItems - $scope.matches.length) + ' matches left.'

_assistiveAlert $scope.pages[$scope.currentPage].questions[$scope.selectedQA[$scope.currentPage].question].text + ' matched with ' +
$scope.pages[$scope.currentPage].answers[$scope.selectedQA[$scope.currentPage].answer].text + '. ' +
($scope.pages[$scope.currentPage].questions.length - ($scope.completePerPage[$scope.currentPage])) + ' of ' + $scope.pages[$scope.currentPage].questions.length + ' matches left on current page '


_applyCircleColor = () ->
# find appropriate circle
$scope.questionCircles[$scope.currentPage][$scope.selectedQA[$scope.currentPage].question].color = _getColor()
$scope.answerCircles[$scope.currentPage][$scope.selectedQA[$scope.currentPage].answer].color = _getColor()


_getColor = () ->
'c' + colorNumber

Expand Down Expand Up @@ -238,6 +297,7 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
$scope.answerCircles[$scope.currentPage][match2_AIndex].color = 'c0'
$scope.matches.splice indexOfAnswer, 1


_pushMatch()

_applyCircleColor()
Expand All @@ -250,10 +310,14 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope

$scope.unapplyHoverSelections()

else if $scope.selectedQA[$scope.currentPage].question != -1 then _assistiveAlert $scope.selectedQuestion.text + ' selected.'
else if $scope.selectedQA[$scope.currentPage].answer != -1 then _assistiveAlert $scope.selectedAnswer.text + ' selected.'

_clearSelections = () ->
$scope.selectedQA[$scope.currentPage].question = -1
$scope.selectedQA[$scope.currentPage].answer = -1


_updateLines = () ->
$scope.lines = []
for [1..$scope.totalPages]
Expand Down Expand Up @@ -327,6 +391,15 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope

return false

$scope.getMatchWith = (item) ->
if item.type == 'question'
a = $scope.matches.find( (match) -> match.questionId == item.id)
if a then return $scope.pages[a.matchPageId].answers[a.answerIndex].text

else if item.type == 'answer'
q = $scope.matches.find( (match) -> match.answerId == item.id)
if q then return $scope.pages[q.matchPageId].questions[q.questionIndex].text

$scope.drawPrelineToRight = (hoverItem) ->
elementId = hoverItem.id
# get the index of the item in the current page by finding it with its id
Expand Down Expand Up @@ -407,8 +480,9 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
when "KeyT" then $scope.selectAnswer($scope.pages[$scope.currentPage].answers[4])
when "KeyY" then $scope.selectAnswer($scope.pages[$scope.currentPage].answers[5])
# left and right arrow keys will change the page
when "ArrowLeft" then $scope.changePage('previous')
when "ArrowRight" then $scope.changePage('next')
when "ArrowLeft" then document.getElementsByClassName('column1')[0].getElementsByClassName('word')[0].focus()
when "ArrowRight" then document.getElementsByClassName('column2')[0].getElementsByClassName('word')[0].focus()

# enter and space will function the same as clicking on the focused element
when "Enter", "Space"
switch window.document.activeElement.id
Expand All @@ -431,6 +505,7 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope

when "finish-button" then $scope.submit()


$scope.getItemLetter = (index) ->
# determines the letter that will be displayed next to each answer choice in the second column
switch index
Expand Down Expand Up @@ -463,6 +538,7 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
$scope.selectedQA[$scope.currentPage].answer = indexId
_checkForMatches()


$scope.submit = () ->
return if $scope.getPercentDone() < 1
qsetItems = $scope.qset.items[0].items
Expand All @@ -488,6 +564,18 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
randomIndex = Math.floor Math.random() * (index + 1)
[qsetItems[index], qsetItems[randomIndex]] = [qsetItems[randomIndex], qsetItems[index]]

$scope.setIsFirstPage = () ->
isFirstPage = false
if $scope.currentPage == 0
isFirstPage = true
return isFirstPage

$scope.setIsLastPage = () ->
isLastPage = false
if $scope.currentPage == $scope.pages.length - 1
isLastPage = true
return isLastPage

_checkUnfinishedPages = () ->
$scope.unfinishedPagesBefore = false
$scope.unfinishedPagesAfter = false
Expand All @@ -505,11 +593,45 @@ Matching.controller 'matchingPlayerCtrl', ['$scope', '$timeout', '$sce', ($scope
if matchesPerPage[page] < pairsPerPage[page]
if matchesPerPage[$scope.currentPage] == pairsPerPage[$scope.currentPage]
$scope.unfinishedPagesBefore = true

unless $scope.currentPage == $scope.pages.length - 1
for page in [$scope.currentPage..pairsPerPage.length]
if matchesPerPage[page] < pairsPerPage[page]
if matchesPerPage[$scope.currentPage] == pairsPerPage[$scope.currentPage]
$scope.unfinishedPagesAfter = true

$scope.unfocused = () ->
$scope.helpVisible = !$scope.helpVisible
helpButton = document.getElementById("help-button");
gameBoard = document.getElementById("gameboard");
panelButtons = document.getElementById("page-selector");
finishButton = document.getElementById("finish-button");


panelButtons.inert = true;
clpetersonucf marked this conversation as resolved.
Show resolved Hide resolved
helpButton.inert = true;
gameBoard.inert = true;
finishButton.inert = true;

helpModal.inert = false;

$scope.focused = () ->

$scope.helpVisible = false
helpButton = document.getElementById("help-button");
gameBoard = document.getElementById("gameboard");
panelButtons = document.getElementById("page-selector");
finishButton = document.getElementById("finish-button");


panelButtons.inert = false;
clpetersonucf marked this conversation as resolved.
Show resolved Hide resolved
helpButton.inert = false;
gameBoard.inert = false;
finishButton.inert = false;


helpModal.inert = true;


Materia.Engine.start materiaCallbacks
]
]
2 changes: 2 additions & 0 deletions src/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ meta_data:
Students must match one set of words or
phrases to a corresponding word, phrase,
or definition.
accessibility_keyboard: Full
accessibility_reader: Full
Loading