Skip to content

Commit

Permalink
Merge pull request #388 from qld-gov-au/QOLOE-421-Video-duration-desc…
Browse files Browse the repository at this point in the history
…ription

[QOLOE-421] Accessibility: print out descriptive format for duration
  • Loading branch information
elvishu authored Aug 1, 2024
2 parents c375b19 + 9400b57 commit 1524266
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 9 deletions.
6 changes: 3 additions & 3 deletions src/components/bs5/video/video.functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
* @returns {void}
*/
export function videoEmbedPlay(event) {
event.preventDefault()
event.preventDefault();

const thumbnail = event.target,
component = thumbnail.closest(".video"),
iframe = component.querySelector(".video-embed iframe")

component.classList.remove("not-ready")
component.classList.remove("not-ready");

// Parse iFrame URL and set the 'autoplay' parameter to 1.
if (!iframe.classList.contains("video-custom")) {
Expand All @@ -22,7 +22,7 @@ export function videoEmbedPlay(event) {
iframe.src = url.toString();
}

iframe.focus()
iframe.focus();

}

Expand Down
18 changes: 12 additions & 6 deletions src/components/bs5/video/video.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@
<section class="video not-ready {{#unless thumbnail}}empty-thumbnail{{/unless}} {{videoSize}}">
<div class="video-player ratio ratio-{{aspectRatio}}">

<a href="#" class="video-thumbnail video-controls">
<a href="#" class="video-thumbnail video-controls" title="Play Video"
aria-label="Watch video {{#if duration}}- duration {{formatDuration duration "long"}}{{/if}}">

<div class="video-thumbnail-image" style="--thumbnail:url({{thumbnail}})"></div>

<div class="video-nav">
<div class="video-watch"><span class="icon"></span><span>Watch</span></div>

{{#if duration}}
<div title="Video duration" class="video-duration"><span class="icon"></span><span>{{duration}}</span></div>
{{/if}}
<div class="video-watch">
<span class="icon"></span><span>Watch</span>
</div>

{{#if duration}}
<div title="Video duration" class="video-duration">
<span class="icon"></span><span>{{formatDuration duration}}</span>
</div>
{{/if}}
</div>
</a>

Expand Down
79 changes: 79 additions & 0 deletions src/js/handlebars.helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,85 @@ export default function handlebarsHelpers(handlebars) {
// Call the formatDate helper with the determined date and format
return handlebars.helpers.formatDate(dateString, dateToFormat, format);
});

/**
* Format time duration into a string.
*
* Supports two formats: "short" and "long".
* - Short format: Display the duration in simplified format of "HH:MM:SS". It is the default format.
* - Long format: Display the duration in descriptive format of "X hours Y minutes Z seconds".
*
* @param {Object | String} duration - Duration object with properties: 'hours', 'minutes', and 'seconds'. Duration string: "HH:MM:SS".
* @param {String} format - Option for format type 'short' or 'long'. If none provided, 'short' is the defaut value.
*
* @returns {String} Formatted duration
* Examples:
* - 03:00:00 - 3 hours
* - 03:15:00 - 3 hours 15 minutes
* - 01:30:45 - 1 hour 30 minutes 45 seconds
* - 02:00:45 - 2 hours 45 seconds
* - 07:12 - 7 minutes 12 seconds
* - 00:45 - 45 seconds
*
* Usage:
* {{formatDuration duration}}
* {{formatDuration duration "long"}}
*/
handlebars.registerHelper('formatDuration', function(duration, format) {
// Return empty string when there is no duration.
if (!duration) {
return "";
}

// Nothing to process here when the duration is already in short format string
// (to support existing CMS metadata).
if (typeof(duration) === 'string' && format !== "long") {
return duration;
}

let durationString = "";
let parts = [];
let hours, minutes, seconds;

// Support for string type 'duration'.
if (typeof(duration) === 'string') {
const durationSplit = duration.split(":");
seconds = durationSplit[0];
if (durationSplit.length == 2) {
[minutes = "", seconds = ""] = durationSplit;
} else if (durationSplit.length == 3) {
[hours = "", minutes = "", seconds = ""] = durationSplit;
}
} else {
// Support for object type 'duration'.
[hours = "", minutes = "", seconds = ""] = duration;
}

// Long format: "X hours Y minutes Z seconds"
if (format === "long") {
if (hours > 0) {
parts.push(`${hours} hour${hours > 1 ? 's' : ''}`);
}
if (minutes > 0) {
parts.push(`${minutes} minute${minutes > 1 ? 's' : ''}`);
}
if (seconds > 0) {
parts.push(`${seconds} second${seconds > 1 ? 's' : ''}`);
}
durationString = parts.join(" ");

// Short format: "HH:MM:SS"
} else {
// Omitting hours when zero
if (hours > 0) {
parts.push(hours.toString().padStart(2, 0));
}
parts.push(minutes.toString().padStart(2, 0));
parts.push(seconds.toString().padStart(2, 0));
durationString = parts.join(":");
}
return durationString;
});
}

if(typeof(Handlebars) !== 'undefined') {
Expand Down

0 comments on commit 1524266

Please sign in to comment.