Start improving accessibility
parent
aead8728d8
commit
196c112243
76
card.js
76
card.js
|
@ -7,10 +7,11 @@
|
|||
* @extends H5P.EventDispatcher
|
||||
* @param {Object} image
|
||||
* @param {number} id
|
||||
* @param {string} alt
|
||||
* @param {string} [description]
|
||||
* @param {Object} [styles]
|
||||
*/
|
||||
MemoryGame.Card = function (image, id, description, styles) {
|
||||
MemoryGame.Card = function (image, id, alt, description, styles) {
|
||||
/** @alias H5P.MemoryGame.Card# */
|
||||
var self = this;
|
||||
|
||||
|
@ -18,7 +19,7 @@
|
|||
EventDispatcher.call(self);
|
||||
|
||||
var path = H5P.getPath(image.path, id);
|
||||
var width, height, margin, $card;
|
||||
var width, height, margin, $card, $wrapper, removedState, flippedState;
|
||||
|
||||
if (image.width !== undefined && image.height !== undefined) {
|
||||
if (image.width > image.height) {
|
||||
|
@ -40,6 +41,7 @@
|
|||
self.flip = function () {
|
||||
$card.addClass('h5p-flipped');
|
||||
self.trigger('flip');
|
||||
flippedState = true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -47,6 +49,7 @@
|
|||
*/
|
||||
self.flipBack = function () {
|
||||
$card.removeClass('h5p-flipped');
|
||||
flippedState = false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -54,6 +57,7 @@
|
|||
*/
|
||||
self.remove = function () {
|
||||
$card.addClass('h5p-matched');
|
||||
removedState = true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,14 +92,37 @@
|
|||
*/
|
||||
self.appendTo = function ($container) {
|
||||
// TODO: Translate alt attr
|
||||
$card = $('<li class="h5p-memory-wrap"><div class="h5p-memory-card" role="button" tabindex="1">' +
|
||||
$wrapper = $('<li class="h5p-memory-wrap" tabindex="-1" role="button"><div class="h5p-memory-card">' +
|
||||
'<div class="h5p-front"' + (styles && styles.front ? styles.front : '') + '>' + (styles && styles.backImage ? '' : '<span></span>') + '</div>' +
|
||||
'<div class="h5p-back"' + (styles && styles.back ? styles.back : '') + '>' +
|
||||
'<img src="' + path + '" alt="Memory Card" style="width:' + width + ';height:' + height + '"/>' +
|
||||
'<img src="' + path + '" alt="' + (alt || 'Memory Image') + '" style="width:' + width + ';height:' + height + '"/>' +
|
||||
'</div>' +
|
||||
'</div></li>')
|
||||
.appendTo($container)
|
||||
.children('.h5p-memory-card')
|
||||
.on('keydown', function (event) {
|
||||
switch (event.which) {
|
||||
case 13: // Enter
|
||||
case 32: // Space
|
||||
if (!flippedState) {
|
||||
self.flip();
|
||||
event.preventDefault();
|
||||
}
|
||||
return;
|
||||
case 39: // Right
|
||||
case 40: // Down
|
||||
// Move focus forward
|
||||
self.trigger('next');
|
||||
event.preventDefault();
|
||||
return;
|
||||
case 37: // Left
|
||||
case 38: // Up
|
||||
// Move focus back
|
||||
self.trigger('prev');
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
});
|
||||
$card = $wrapper.children('.h5p-memory-card')
|
||||
.children('.h5p-front')
|
||||
.click(function () {
|
||||
self.flip();
|
||||
|
@ -107,8 +134,43 @@
|
|||
* Re-append to parent container
|
||||
*/
|
||||
self.reAppend = function () {
|
||||
var parent = $card[0].parentElement.parentElement;
|
||||
parent.appendChild($card[0].parentElement);
|
||||
var parent = $wrapper[0].parentElement;
|
||||
parent.appendChild($wrapper[0]);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
self.makeTabbable = function () {
|
||||
if ($wrapper) {
|
||||
$wrapper.attr('tabindex', '0');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
self.makeUntabbable = function () {
|
||||
if ($wrapper) {
|
||||
$wrapper.attr('tabindex', '-1');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
self.setFocus = function () {
|
||||
self.makeTabbable();
|
||||
if ($wrapper) {
|
||||
$wrapper.focus();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
self.isFlipped = function () {
|
||||
return flippedState;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -220,6 +220,38 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
|
|||
counter.increment();
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} direction
|
||||
*/
|
||||
var createCardChangeFocusHandler = function (direction) {
|
||||
return function () {
|
||||
// Locate next card
|
||||
for (var i = 0; i < cards.length; i++) {
|
||||
if (cards[i] === card) {
|
||||
// Found current card
|
||||
|
||||
var nextCard, fails = 0;
|
||||
do {
|
||||
fails++;
|
||||
nextCard = cards[i + (direction * fails)];
|
||||
if (!nextCard) {
|
||||
return; // No more cards
|
||||
}
|
||||
}
|
||||
while (nextCard.isFlipped());
|
||||
|
||||
card.makeUntabbable();
|
||||
nextCard.setFocus();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
card.on('next', createCardChangeFocusHandler(1));
|
||||
card.on('prev', createCardChangeFocusHandler(-1));
|
||||
cards.push(card);
|
||||
};
|
||||
|
||||
|
@ -277,16 +309,16 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
|
|||
var cardParams = cardsToUse[i];
|
||||
if (MemoryGame.Card.isValid(cardParams)) {
|
||||
// Create first card
|
||||
var cardTwo, cardOne = new MemoryGame.Card(cardParams.image, id, cardParams.description, cardStyles);
|
||||
var cardTwo, cardOne = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, cardParams.description, cardStyles);
|
||||
|
||||
if (MemoryGame.Card.hasTwoImages(cardParams)) {
|
||||
// Use matching image for card two
|
||||
cardTwo = new MemoryGame.Card(cardParams.match, id, cardParams.description, cardStyles);
|
||||
cardTwo = new MemoryGame.Card(cardParams.match, id, cardParams.matchAlt, cardParams.description, cardStyles);
|
||||
cardOne.hasTwoImages = cardTwo.hasTwoImages = true;
|
||||
}
|
||||
else {
|
||||
// Add two cards with the same image
|
||||
cardTwo = new MemoryGame.Card(cardParams.image, id, cardParams.description, cardStyles);
|
||||
cardTwo = new MemoryGame.Card(cardParams.image, id, cardParams.imageAlt, cardParams.description, cardStyles);
|
||||
}
|
||||
|
||||
// Add cards to card list for shuffeling
|
||||
|
@ -314,6 +346,7 @@ H5P.MemoryGame = (function (EventDispatcher, $) {
|
|||
for (var i = 0; i < cards.length; i++) {
|
||||
cards[i].appendTo($list);
|
||||
}
|
||||
cards[0].makeTabbable();
|
||||
|
||||
if ($list.children().length) {
|
||||
$list.appendTo($container);
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
"importance": "high",
|
||||
"ratio": 1
|
||||
},
|
||||
{
|
||||
"name": "imageAlt",
|
||||
"type": "text",
|
||||
"label": "Alternative text for Image",
|
||||
"importance": "high",
|
||||
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
||||
},
|
||||
{
|
||||
"name": "match",
|
||||
"type": "image",
|
||||
|
@ -35,6 +42,14 @@
|
|||
"description": "An optional image to match against instead of using two cards with the same image.",
|
||||
"ratio": 1
|
||||
},
|
||||
{
|
||||
"name": "matchAlt",
|
||||
"type": "text",
|
||||
"label": "Alternative text for Matching Image",
|
||||
"importance": "low",
|
||||
"optional": true,
|
||||
"description": "Describe what can be seen in the photo. The text is read by text-to-speech tools needed by visually impaired users."
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
|
@ -146,7 +161,7 @@
|
|||
"importance": "low",
|
||||
"name": "tryAgain",
|
||||
"type": "text",
|
||||
"default": "Try again?"
|
||||
"default": "Reset"
|
||||
},
|
||||
{
|
||||
"label": "Close button label",
|
||||
|
|
Loading…
Reference in New Issue