Skip to content

Commit

Permalink
Added extension which allows the end-user to toggle the timer element…
Browse files Browse the repository at this point in the history
… on and off.
  • Loading branch information
michaelsharman committed Mar 4, 2024
1 parent 1ec2616 commit 837da4f
Show file tree
Hide file tree
Showing 34 changed files with 781 additions and 31 deletions.
2 changes: 1 addition & 1 deletion docs/index.html

Large diffs are not rendered by default.

305 changes: 304 additions & 1 deletion docs/module-Assessment_Activity.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_App.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_Diagnostics.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_Items.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_Player.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_Questions.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Assessment_Sections.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Authoring_App.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Authoring_Diagnostics.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Authoring_Navigation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Authoring_Widgets.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-Utils_Logger.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_ariaCountOnNav.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_blockGrammarChecks.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_columnResizer.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_hideAlternatives.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_keyboardShortcuts.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_magnifier.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_mcqLabelPrefix.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_pageOverlay.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_renderPDF.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Assessment_resetResponse.html

Large diffs are not rendered by default.

319 changes: 319 additions & 0 deletions docs/module-_Extensions_Assessment_toggleTimer.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Authoring_contentTabs.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/module-_Extensions_Authoring_renderPDF.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@caspingus/lt",
"version": "2.5.0",
"version": "2.6.0",
"description": "A utility library of helpers and tools for working with Learnosity APIs.",
"main": "src/index.js",
"author": "michael@learnosity.com",
Expand Down
126 changes: 126 additions & 0 deletions src/assessment/extensions/accessibility/ux/toggleTimer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import * as app from '../../../core/app';
import * as activity from '../../../core/activity';
import logger from '../../../../utils/logger';

/**
* Extensions add specific functionality to Items API.
* They rely on modules within LT being available.
*
* --
*
* Allows the end-user to toggle visibility of the timer,
* leaving the clock icon only. This can reduce test anxiety.
*
* Note: this does not work on the smallest (mobile) breakpoint
* because that is a separate layout that doesn't include the
* clock icon. It's a future TODO to rectify this extension
* in the narrowest layout.
* <p><img src="https://raw.githubusercontent.com/michaelsharman/LT/main/src/assets/images/toggletimer.gif" alt="Animated gif showing the toggle timer feature" width="900"></p>
* @module _Extensions/Assessment/toggleTimer
*/

const state = {
forceRenderTimer: false,
renderedCss: false,
};

/**
* Wraps clock and timer elements inside a button. Adds a
* click event to toggle the timer.
*
* By passing `showTimerLimit`, you can force render the timer
* in the final moments. Will force render one time only, if
* the user hides the timer again we don't force render.
*
* @param {number} showTimerLimit The clock value to force render the timer element.
* @example
* import { LT } from '@caspingus/lt/src/assessment/index';
*
* LT.init(itemsApp); // Set up LT with the Items API application instance variable
* LT.extensions.toggleTimer.run();
* @since 2.6.0
*/
export function run(showTimerLimit = 60) {
const elLrnResponsiveWrapper = document.querySelector('.lrn-sm');
const elTimerWrapper = document.querySelector('.lrn-timer-wrapper');

if (elLrnResponsiveWrapper && elTimerWrapper) {
if (!state.renderedCss) injectCSS();

const childElements = Array.from(elTimerWrapper.children);
const elTimerButton = document.createElement('button');

elTimerButton.classList.add('lrn_btn', 'lt__timer-button');
elTimerButton.setAttribute('type', 'button');
elTimerButton.setAttribute('aria-label', `${elTimerWrapper.getAttribute('aria-label')}, click to toggle visibility of the timer.`);

elTimerWrapper.innerHTML = '';
elTimerWrapper.appendChild(elTimerButton);
childElements.forEach(child => {
elTimerButton.appendChild(child);
});

elTimerButton.addEventListener('click', () => {
toggleTimer(elTimerWrapper);
});

app.appInstance().on('time:change', () => {
const timeRemaining = activity.timeRemaining();
if (
!state.forceRenderTimer &&
typeof timeRemaining === 'number' &&
timeRemaining <= Number(showTimerLimit) &&
elTimerWrapper.classList.contains('lt__timer-hide')
) {
state.forceRenderTimer = true;
elTimerWrapper.classList.remove('lt__timer-hide');
logger.info(`Force show the timer limit (${showTimerLimit}) reached.`);
}
});
}
}

/**
* Adds a classname to toggle visibility of the timer.
* @param {object} elTimerWrapper DOM element of timer.
* @since 2.6.0
* @ignore
*/
function toggleTimer(elTimerWrapper) {
elTimerWrapper.classList.toggle('lt__timer-hide');
}

/**
* Injects the necessary CSS to the header
* @since 2.6.0
* @ignore
*/
function injectCSS() {
const elStyle = document.createElement('style');
const css = `
/* Learnosity toggle timer styles */
.lrn.lrn-assess .lrn-region:not(.lrn-items-region) .lrn_btn.lt__timer-button {
font-size: inherit;
}
.lrn-assess .lrn_btn.lt__timer-button .timer {
padding: 8px;
height: 29px;
position: relative;
top: -4px;
}
.lrn.lrn-assess .lt__timer-wrapper.lt__timer-hide .lrn_btn.lt__timer-button .timer .clock:before {
padding-right: 0;
}
.lrn-timer-wrapper.lt__timer-hide .lt__timer-button .timer > *:not(.clock) {
display: none;
}
`;

elStyle.textContent = css;
document.head.append(elStyle);

state.renderedCss = true;
}
2 changes: 2 additions & 0 deletions src/assessment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as mcqLabelPrefix from './extensions/accessibility/ux/mcqLabelPrefix';
import * as pageOverlay from './extensions/accessibility/ux/pageOverlay';
import * as renderPDF from './extensions/ui/renderPDF/index';
import * as resetResponse from './extensions/accessibility/ux/resetResponse';
import * as toggleTimer from './extensions/accessibility/ux/toggleTimer';

const extensions = {
extensions: {
Expand All @@ -32,6 +33,7 @@ const extensions = {
pageOverlay: { ...pageOverlay },
renderPDF: { ...renderPDF },
resetResponse: { ...resetResponse },
toggleTimer: { ...toggleTimer },
},
};

Expand Down
Binary file added src/assets/images/toggletimer.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 837da4f

Please sign in to comment.