From 196c112243c81ead6a7c7c7013424d8c774cc8e1 Mon Sep 17 00:00:00 2001 From: Frode Petterson Date: Tue, 20 Jun 2017 16:47:07 +0200 Subject: [PATCH] Start improving accessibility --- card.js | 86 +++++++++++++++++++++++++++++++++++++++++++------- memory-game.js | 39 +++++++++++++++++++++-- semantics.json | 17 +++++++++- 3 files changed, 126 insertions(+), 16 deletions(-) diff --git a/card.js b/card.js index 660a9bf..76a1c73 100644 --- a/card.js +++ b/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,27 +92,85 @@ */ self.appendTo = function ($container) { // TODO: Translate alt attr - $card = $('
  • ' + + $wrapper = $('
  • ' + '
    ' + (styles && styles.backImage ? '' : '') + '
    ' + '
    ' + - 'Memory Card' + + '' + (alt || 'Memory Image') + '' + '
    ' + '
  • ') .appendTo($container) - .children('.h5p-memory-card') - .children('.h5p-front') - .click(function () { - self.flip(); - }) - .end(); + .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(); + }) + .end(); }; /** * 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; }; }; diff --git a/memory-game.js b/memory-game.js index a0029f6..894f512 100644 --- a/memory-game.js +++ b/memory-game.js @@ -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); diff --git a/semantics.json b/semantics.json index fd274e2..52a1f10 100644 --- a/semantics.json +++ b/semantics.json @@ -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",