diff --git a/scripts/keyboard-nav.js b/scripts/keyboard-nav.js
index 17098c2..b712ebe 100644
--- a/scripts/keyboard-nav.js
+++ b/scripts/keyboard-nav.js
@@ -113,10 +113,6 @@ H5P.KeyboardNav = (function (EventDispatcher) {
* @public
*/
KeyboardNav.prototype.disableSelectability = function () {
- this.elements.forEach(function (el) {
- el.el.removeEventListener('keydown', el.keyDown);
- el.el.removeEventListener('click', el.onClick);
- }.bind(this));
this.selectability = false;
};
@@ -126,10 +122,6 @@ H5P.KeyboardNav = (function (EventDispatcher) {
* @public
*/
KeyboardNav.prototype.enableSelectability = function () {
- this.elements.forEach(function (el) {
- el.el.addEventListener('keydown', el.keyDown);
- el.el.addEventListener('click', el.onClick);
- }.bind(this));
this.selectability = true;
};
diff --git a/scripts/mark-the-words.js b/scripts/mark-the-words.js
index 1c1b102..e50340f 100644
--- a/scripts/mark-the-words.js
+++ b/scripts/mark-the-words.js
@@ -53,6 +53,8 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
a11yRetry: 'Retry the task. Reset all responses and start the task over again.',
}, params);
+ this.resetTask = this.resetTask.bind(this);
+
this.contentData = contentData;
if (this.contentData !== undefined && this.contentData.previousState !== undefined) {
this.previousState = this.contentData.previousState;
@@ -260,13 +262,6 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
text: ariaText,
}).appendTo($ariaTextWrapper);
- // A11y clickable list label
- this.$a11yClickableTextLabel = $('
', {
- 'class': 'hidden-but-read',
- html: self.params.a11yClickableTextLabel,
- tabIndex: '-1',
- }).appendTo($container);
-
$wordContainer.appendTo($container);
self.$wordContainer = $wordContainer;
};
@@ -295,13 +290,20 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
self.showButton('try-again');
}
}
- // Set focus to start of text
- self.$a11yClickableTextLabel.html(self.params.a11yCheckingHeader + ' - ' + self.params.a11yClickableTextLabel);
- self.$a11yClickableTextLabel.focus();
self.hideButton('check-answer');
self.trigger(self.XapiGenerator.generateAnsweredEvent());
+
self.toggleSelectable(true);
+
+ self.read(
+ self.params.a11yCheckingHeader + ' - ' +
+ self.params.a11yClickableTextLabel
+ );
+
+ window.setTimeout(() => {
+ self.focusOnFirstElement();
+ }, 1); // Read 'checking mode' before announcing focus of first answer
}, true, {
'aria-label': this.params.a11yCheck,
}, {
@@ -310,24 +312,31 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
});
}
- this.addButton('try-again', this.params.tryAgainButton, this.resetTask.bind(this), false, {
- 'aria-label': this.params.a11yRetry,
- });
+ this.addButton(
+ 'try-again',
+ this.params.tryAgainButton,
+ () => {
+ this.resetTask({ focusOnFirst: true })
+ },
+ false,
+ { 'aria-label': this.params.a11yRetry }
+ );
- this.addButton('show-solution', this.params.showSolutionButton, function () {
+ this.addButton('show-solution', this.params.showSolutionButton, () => {
self.setAllMarks();
- self.$a11yClickableTextLabel.html(self.params.a11ySolutionModeHeader + ' - ' + self.params.a11yClickableTextLabel);
- self.$a11yClickableTextLabel.focus();
-
if (self.params.behaviour.enableRetry) {
self.showButton('try-again');
}
self.hideButton('check-answer');
self.hideButton('show-solution');
- self.read(self.params.displaySolutionDescription);
self.toggleSelectable(true);
+
+ self.read(self.params.displaySolutionDescription);
+ window.setTimeout(() => {
+ self.focusOnFirstElement();
+ }, 10); // Read 'checking mode' before announcing focus of first answer
}, false, {
'aria-label': this.params.a11yShowSolution,
});
@@ -341,23 +350,34 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
this.keyboardNavigators.forEach(function (navigator) {
if (disable) {
navigator.disableSelectability();
- navigator.removeAllTabbable();
}
else {
navigator.enableSelectability();
- navigator.setTabbableAt((0));
}
});
if (disable) {
- this.$wordContainer.removeAttr('aria-multiselectable').removeAttr('role');
+ this.$wordContainer.removeAttr('aria-multiselectable');
}
else {
- this.$wordContainer.attr('aria-multiselectable', 'true')
- .attr('role', 'listbox');
+ this.$wordContainer.attr('aria-multiselectable', 'true');
}
};
+ /**
+ * Focus on first element.
+ */
+ MarkTheWords.prototype.focusOnFirstElement = function () {
+ this.keyboardNavigators.forEach((navigator, index) => {
+ if (index === 0) {
+ navigator.focusOnElementAt(0);
+ }
+ else {
+ navigator.setTabbableAt((0));
+ }
+ });
+ };
+
/**
* Get Xapi Data.
*
@@ -559,9 +579,12 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
this.hideButton('try-again');
this.hideButton('show-solution');
this.hideButton('check-answer');
- this.$a11yClickableTextLabel.html(this.params.a11ySolutionModeHeader + ' - ' + this.params.a11yClickableTextLabel);
this.toggleSelectable(true);
+ this.keyboardNavigators.forEach((navigator) => {
+ navigator.setTabbableAt((0));
+ });
+
this.trigger('resize');
};
@@ -569,18 +592,28 @@ H5P.MarkTheWords = (function ($, Question, Word, KeyboardNav, XapiGenerator) {
* Resets the task back to its' initial state.
*
* @fires MarkTheWords#resize
+ * @param {object} [params={}] Parameters.
+ * @param {boolean} [params.focusOnFirst] If true, set focus on first element.
* @see {@link https://h5p.org/documentation/developers/contracts|Needed for contracts.}
*/
- MarkTheWords.prototype.resetTask = function () {
+ MarkTheWords.prototype.resetTask = function (params={}) {
this.isAnswered = false;
this.clearAllMarks();
this.hideEvaluation();
this.hideButton('try-again');
this.hideButton('show-solution');
this.showButton('check-answer');
- this.$a11yClickableTextLabel.html(this.params.a11yClickableTextLabel);
this.toggleSelectable(false);
+
+ this.read(this.params.a11yClickableTextLabel);
+
+ if (params.focusOnFirst) {
+ window.setTimeout(() => {
+ this.focusOnFirstElement();
+ }, 10); // Read 'checking mode' before announcing focus of first answer
+ }
+
this.trigger('resize');
};