Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 9 additions & 9 deletions js/TrickleButtonModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,18 @@ export default class TrickleButtonModel extends ComponentModel {
const text = (isDisabled && trickleConfig._button.disabledText) ?
trickleConfig._button.disabledText :
(isStart && trickleConfig._button.startText) ?
trickleConfig._button.startText :
(isFinal && trickleConfig._button.finalText) ?
trickleConfig._button.finalText :
trickleConfig._button.text;
trickleConfig._button.startText :
(isFinal && trickleConfig._button.finalText) ?
trickleConfig._button.finalText :
trickleConfig._button.text;

const ariaLabel = (isDisabled && trickleConfig._button.disabledAriaLabel) ?
trickleConfig._button.disabledAriaLabel :
trickleConfig._button.disabledAriaLabel :
(isStart && trickleConfig._button.startAriaLabel) ?
trickleConfig._button.startAriaLabel :
(isFinal && trickleConfig._button.finalAriaLabel) ?
trickleConfig._button.finalAriaLabel :
trickleConfig._button.ariaLabel;
trickleConfig._button.startAriaLabel :
(isFinal && trickleConfig._button.finalAriaLabel) ?
trickleConfig._button.finalAriaLabel :
trickleConfig._button.ariaLabel;

this.set({
buttonText: text,
Expand Down
29 changes: 26 additions & 3 deletions js/TrickleButtonView.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Adapt from 'core/js/adapt';
import a11y from 'core/js/a11y';
import notify from 'core/js/notify';
import ComponentView from 'core/js/views/componentView';
import controller from './controller';
import {
getModelConfig,
getCompletionAttribute
} from './models';
import wait from 'core/js/wait';

/** @typedef {import('core/js/modelEvent').default} ModelEvent */

Expand Down Expand Up @@ -72,7 +74,7 @@ class TrickleButtonView extends ComponentView {
this.$el.on('onscreen', this.tryButtonAutoHide);
this.listenTo(Adapt, {
'popup:opened': this.onPopupOpened,
'popup:closed': this.onPopupClosed
'popup:closing': this.onPopupClosed
});
const parentModel = this.model.getParent();
const completionAttribute = getCompletionAttribute(parentModel);
Expand Down Expand Up @@ -100,6 +102,8 @@ class TrickleButtonView extends ComponentView {
this.openPopupCount--;
if (this.openPopupCount) return;
if (this.isAwaitingPopupClose) {
this._isWaiting = true;
wait.begin();
// Had completed with an open popup, perform final part of finishing
return this.finish();
}
Expand Down Expand Up @@ -187,7 +191,7 @@ class TrickleButtonView extends ComponentView {
async finish() {
this.stopListening(Adapt, {
'popup:opened': this.onPopupOpened,
'popup:closed': this.onPopupClosed
'popup:closing': this.onPopupClosed
});
this.updateButtonState();
const isStepLockingCompletionRequired = this.model.isStepLockingCompletionRequired();
Expand All @@ -202,10 +206,29 @@ class TrickleButtonView extends ComponentView {
*/
async continue() {
const parent = this.model.getParent();
await controller.continue();
const childrenAdded = await controller.continue();
if (childrenAdded.length) {
await this.announceContentLoaded();
}
if (this._isWaiting) {
this._isWaiting = false;
a11y.setPopupCloseTo(childrenAdded[0]?.$el);
wait.end();
}
await controller.scroll(parent);
}

/**
* Announce a message to screenreaders letting them know that additional
* content has been loaded on the page.
*/
async announceContentLoaded() {
const globals = Adapt.course.get('_globals');
const message = globals?._extensions?._trickle?.additionalContentLoaded;
if (!message) return;
await notify.read(message);
}

tryButtonAutoHide() {
if (!this.model.get('_isButtonVisible')) return;
const trickleConfig = getModelConfig(this.model.getParent());
Expand Down
9 changes: 6 additions & 3 deletions js/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,11 @@ class TrickleController extends Backbone.Controller {
*/
async continue() {
applyLocks();
await Adapt.parentView.addChildren();
const addedChildren = await Adapt.parentView.addChildren({
returnNewDescendants: true
});
await Adapt.parentView.whenReady();
return addedChildren;
}

/**
Expand Down Expand Up @@ -160,8 +163,8 @@ class TrickleController extends Backbone.Controller {

let scrollToId = getScrollToId();
if (!scrollToId) {
logging.error(`Cannot scroll to the next id as none was found at id: "${fromModel.get('_id')}" with _scrollTo: "${trickleConfig._scrollTo}". Suggestion: Set _showEndOfPage to false.`)
return
logging.error(`Cannot scroll to the next id as none was found at id: "${fromModel.get('_id')}" with _scrollTo: "${trickleConfig._scrollTo}". Suggestion: Set _showEndOfPage to false.`);
return;
}

const isDescendant = Adapt.parentView.model.getAllDescendantModels().some(model => {
Expand Down
10 changes: 10 additions & 0 deletions properties.schema
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@
"inputType": "Text",
"validators": [],
"translatable": true
},
"additionalContentLoaded": {
"type": "string",
"required": true,
"title": "Additional content loaded.",
"default": "Loading.",
"inputType": "Text",
"help": "Announced to screen readers when additional content is loaded. Recommend keeping this short.",
"validators": [],
"translatable": true
}
},
"properties": {
Expand Down
9 changes: 9 additions & 0 deletions schema/course.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
"_adapt": {
"translatable": true
}
},
"additionalContentLoaded": {
"type": "string",
"title": "Additional content loaded",
"default": "Loading.",
"description": "Announced to screen readers when additional content is loaded. Recommend keeping this short.",
"_adapt": {
"translatable": true
}
}
}
}
Expand Down