diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..5bcfffd5c
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,29 @@
+name: Lint code
+
+on: [push, pull_request]
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Setup Node
+ uses: actions/setup-node@v4
+ with:
+ node-version: '18'
+
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install npm dependencies
+ run: npm install
+
+ - name: Lint code
+ run: npm run lint
+
+ - name: Auto-commit fixes
+ uses: EndBug/add-and-commit@v9
+ with:
+ default_author: github_actions
+ add: "['src/']"
diff --git a/src/content-handlers/iiif/BaseConfig.ts b/src/content-handlers/iiif/BaseConfig.ts
index 97fbc0356..38ec90c21 100644
--- a/src/content-handlers/iiif/BaseConfig.ts
+++ b/src/content-handlers/iiif/BaseConfig.ts
@@ -226,7 +226,7 @@ export type SettingsDialogueContent = DialogueContent & {
clickToZoomEnabled: string;
pagingEnabled: string;
reducedMotion: string;
- truncateThumbnailLabels: string;
+ truncateThumbnailLabels: string;
preserveViewport: string;
title: string;
website: string;
diff --git a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/DownloadDialogue.tsx b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/DownloadDialogue.tsx
index 470faccf4..93a0efc6c 100644
--- a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/DownloadDialogue.tsx
+++ b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/DownloadDialogue.tsx
@@ -325,7 +325,7 @@ const DownloadDialogue = ({
if (bodies.length == 0) {
return null;
}
-
+
return bodies[0];
}
@@ -342,7 +342,8 @@ const DownloadDialogue = ({
}
// presentation api version 3
- const annotationBody: AnnotationBody | null = getCanvasImageAnnotationBody(canvas);
+ const annotationBody: AnnotationBody | null =
+ getCanvasImageAnnotationBody(canvas);
if (annotationBody) {
const format: MediaType | null = annotationBody.getFormat();
diff --git a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/SettingsDialogue.ts b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/SettingsDialogue.ts
index 68298f08f..7a2ccee82 100644
--- a/src/content-handlers/iiif/extensions/uv-openseadragon-extension/SettingsDialogue.ts
+++ b/src/content-handlers/iiif/extensions/uv-openseadragon-extension/SettingsDialogue.ts
@@ -1,6 +1,6 @@
const $ = require("jquery");
import { SettingsDialogue as BaseSettingsDialogue } from "../../modules/uv-dialogues-module/SettingsDialogue";
-import config from "./config/config.json";
+import config from "./config/config.json";
export class SettingsDialogue extends BaseSettingsDialogue {
$clickToZoomEnabled: JQuery;
@@ -57,25 +57,35 @@ export class SettingsDialogue extends BaseSettingsDialogue {
);
this.$pagingEnabled.append(this.$pagingEnabledLabel);
- if (config.options.truncateThumbnailLabels) {
- this.$truncateThumbnailLabels = $('
');
+ if (config.options.truncateThumbnailLabels) {
+ this.$truncateThumbnailLabels = $(
+ ''
+ );
this.$scroll.append(this.$truncateThumbnailLabels);
this.$truncateThumbnailLabelsCheckbox = $(
''
);
- this.$truncateThumbnailLabels.append(this.$truncateThumbnailLabelsCheckbox);
+ this.$truncateThumbnailLabels.append(
+ this.$truncateThumbnailLabelsCheckbox
+ );
this.$truncateThumbnailLabelsLabel = $(
- '"
+ '"
);
this.$truncateThumbnailLabels.append(this.$truncateThumbnailLabelsLabel);
- this.$truncateThumbnailLabelsCheckbox.prop('checked', config.options.truncateThumbnailLabels);
+ this.$truncateThumbnailLabelsCheckbox.prop(
+ "checked",
+ config.options.truncateThumbnailLabels
+ );
this.$truncateThumbnailLabelsCheckbox.change(() => {
const settings: ISettings = {};
- settings.truncateThumbnailLabels = this.$truncateThumbnailLabelsCheckbox.is(":checked");
+ settings.truncateThumbnailLabels =
+ this.$truncateThumbnailLabelsCheckbox.is(":checked");
this.updateSettings(settings);
});
}
@@ -191,13 +201,13 @@ export class SettingsDialogue extends BaseSettingsDialogue {
} else {
this.$preserveViewportCheckbox.removeAttr("checked");
}
-
+
if (this.$truncateThumbnailLabelsCheckbox) {
if (settings.truncateThumbnailLabels) {
this.$truncateThumbnailLabelsCheckbox.prop("checked", true);
} else {
this.$truncateThumbnailLabelsCheckbox.prop("checked", false);
}
- }
+ }
}
}
diff --git a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ContentLeftPanel.ts b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ContentLeftPanel.ts
index 2e83a5aae..5f9e2f54d 100644
--- a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ContentLeftPanel.ts
+++ b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ContentLeftPanel.ts
@@ -514,7 +514,10 @@ export class ContentLeftPanel extends LeftPanel {
paged,
viewingDirection: viewingDirection || ViewingDirection.LEFT_TO_RIGHT,
selected: selectedIndices,
- truncateThumbnailLabels: settings.truncateThumbnailLabels !== undefined ? settings.truncateThumbnailLabels : true,
+ truncateThumbnailLabels:
+ settings.truncateThumbnailLabels !== undefined
+ ? settings.truncateThumbnailLabels
+ : true,
onClick: (thumb: Thumb) => {
this.extensionHost.publish(IIIFEvents.THUMB_SELECTED, thumb);
},
diff --git a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/GalleryView.ts b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/GalleryView.ts
index 3a282d0ae..044b679a4 100644
--- a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/GalleryView.ts
+++ b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/GalleryView.ts
@@ -85,7 +85,6 @@ export class GalleryView extends BaseView {
}
public applyExtendedLabelsStyles(): void {
- this.$gallery.addClass('label-extended');
+ this.$gallery.addClass("label-extended");
}
-
}
diff --git a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ThumbsView.tsx b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ThumbsView.tsx
index 5978915b6..b009c335b 100644
--- a/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ThumbsView.tsx
+++ b/src/content-handlers/iiif/modules/uv-contentleftpanel-module/ThumbsView.tsx
@@ -1,159 +1,159 @@
-import React, { useEffect, useRef } from "react";
-import { Thumb } from "manifesto.js";
-import { ViewingDirection, ViewingHint } from "@iiif/vocabulary";
-import { useInView } from "react-intersection-observer";
-import cx from "classnames";
-
-const ThumbImage = ({
- first,
- onClick,
- onKeyDown,
- paged,
- selected,
- thumb,
- truncateThumbnailLabels,
- viewingDirection,
-}: {
- first: boolean;
- onClick: (thumb: Thumb) => void;
- onKeyDown: (thumb: Thumb) => void;
- paged: boolean;
- selected: boolean;
- thumb: Thumb;
- truncateThumbnailLabels: boolean;
- viewingDirection: ViewingDirection;
-}) => {
- const [ref, inView] = useInView({
- threshold: 0,
- rootMargin: "0px 0px 0px 0px",
- triggerOnce: true,
- });
-
- var keydownHandler = (e) => {
- if (e.key === "Enter" || e.key === " ") {
- e.preventDefault();
- onKeyDown(thumb);
- }
- };
- return (
- onClick(thumb)}
- onKeyDown={keydownHandler}
- className={cx("thumb", {
- first: first,
- placeholder: !thumb.uri,
- twoCol:
- paged &&
- (viewingDirection === ViewingDirection.LEFT_TO_RIGHT ||
- viewingDirection === ViewingDirection.RIGHT_TO_LEFT),
- oneCol: !paged,
- selected: selected,
- "truncate-labels": truncateThumbnailLabels,
- })}
- tabIndex={0}
- >
-
- {inView &&
}
-
-
-
- {thumb.label}
-
- {thumb.data.searchResults && (
- {thumb.data.searchResults}
- )}
-
-
- );
-};
-
-const Thumbnails = ({
- onClick,
- onKeyDown,
- paged,
- selected,
- thumbs,
- viewingDirection,
- truncateThumbnailLabels,
-}: {
- onClick: (thumb: Thumb) => void;
- onKeyDown: (thumb: Thumb) => void;
- paged: boolean;
- selected: number[];
- thumbs: Thumb[];
- viewingDirection: ViewingDirection;
- truncateThumbnailLabels: boolean;
-}) => {
- const ref = useRef(null);
-
- useEffect(() => {
- const thumb: HTMLElement = ref.current?.querySelector(
- `#thumb-${selected[0]}`
- ) as HTMLElement;
- const y: number = thumb?.offsetTop;
- ref.current?.parentElement!.scrollTo({
- top: y,
- left: 0,
- behavior: "smooth",
- });
- }, [selected]);
-
- function showSeparator(
- paged: boolean,
- viewingHint: ViewingHint | null,
- index: number
- ) {
- if (viewingHint === ViewingHint.NON_PAGED) {
- return true;
- }
-
- if (paged) {
- // if paged, show separator after every 2 thumbs
- return !((index - 1) % 2 === 0);
- }
-
- return true;
- }
-
- const firstNonPagedIndex: number = thumbs.findIndex((t) => {
- return t.viewingHint !== ViewingHint.NON_PAGED;
- });
-
- return (
-
- {thumbs.map((thumb, index) => (
-
-
- {showSeparator(paged, thumb.viewingHint, index) && (
-
- )}
-
- ))}
-
- );
-};
-
-export default Thumbnails;
+import React, { useEffect, useRef } from "react";
+import { Thumb } from "manifesto.js";
+import { ViewingDirection, ViewingHint } from "@iiif/vocabulary";
+import { useInView } from "react-intersection-observer";
+import cx from "classnames";
+
+const ThumbImage = ({
+ first,
+ onClick,
+ onKeyDown,
+ paged,
+ selected,
+ thumb,
+ truncateThumbnailLabels,
+ viewingDirection,
+}: {
+ first: boolean;
+ onClick: (thumb: Thumb) => void;
+ onKeyDown: (thumb: Thumb) => void;
+ paged: boolean;
+ selected: boolean;
+ thumb: Thumb;
+ truncateThumbnailLabels: boolean;
+ viewingDirection: ViewingDirection;
+}) => {
+ const [ref, inView] = useInView({
+ threshold: 0,
+ rootMargin: "0px 0px 0px 0px",
+ triggerOnce: true,
+ });
+
+ var keydownHandler = (e) => {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ onKeyDown(thumb);
+ }
+ };
+ return (
+ onClick(thumb)}
+ onKeyDown={keydownHandler}
+ className={cx("thumb", {
+ first: first,
+ placeholder: !thumb.uri,
+ twoCol:
+ paged &&
+ (viewingDirection === ViewingDirection.LEFT_TO_RIGHT ||
+ viewingDirection === ViewingDirection.RIGHT_TO_LEFT),
+ oneCol: !paged,
+ selected: selected,
+ "truncate-labels": truncateThumbnailLabels,
+ })}
+ tabIndex={0}
+ >
+
+ {inView &&
}
+
+
+
+ {thumb.label}
+
+ {thumb.data.searchResults && (
+ {thumb.data.searchResults}
+ )}
+
+
+ );
+};
+
+const Thumbnails = ({
+ onClick,
+ onKeyDown,
+ paged,
+ selected,
+ thumbs,
+ viewingDirection,
+ truncateThumbnailLabels,
+}: {
+ onClick: (thumb: Thumb) => void;
+ onKeyDown: (thumb: Thumb) => void;
+ paged: boolean;
+ selected: number[];
+ thumbs: Thumb[];
+ viewingDirection: ViewingDirection;
+ truncateThumbnailLabels: boolean;
+}) => {
+ const ref = useRef(null);
+
+ useEffect(() => {
+ const thumb: HTMLElement = ref.current?.querySelector(
+ `#thumb-${selected[0]}`
+ ) as HTMLElement;
+ const y: number = thumb?.offsetTop;
+ ref.current?.parentElement!.scrollTo({
+ top: y,
+ left: 0,
+ behavior: "smooth",
+ });
+ }, [selected]);
+
+ function showSeparator(
+ paged: boolean,
+ viewingHint: ViewingHint | null,
+ index: number
+ ) {
+ if (viewingHint === ViewingHint.NON_PAGED) {
+ return true;
+ }
+
+ if (paged) {
+ // if paged, show separator after every 2 thumbs
+ return !((index - 1) % 2 === 0);
+ }
+
+ return true;
+ }
+
+ const firstNonPagedIndex: number = thumbs.findIndex((t) => {
+ return t.viewingHint !== ViewingHint.NON_PAGED;
+ });
+
+ return (
+
+ {thumbs.map((thumb, index) => (
+
+
+ {showSeparator(paged, thumb.viewingHint, index) && (
+
+ )}
+
+ ))}
+
+ );
+};
+
+export default Thumbnails;
diff --git a/src/content-handlers/iiif/modules/uv-dialogues-module/SettingsDialogue.ts b/src/content-handlers/iiif/modules/uv-dialogues-module/SettingsDialogue.ts
index 15165f553..e2541b3c2 100644
--- a/src/content-handlers/iiif/modules/uv-dialogues-module/SettingsDialogue.ts
+++ b/src/content-handlers/iiif/modules/uv-dialogues-module/SettingsDialogue.ts
@@ -4,7 +4,9 @@ import { IIIFEvents } from "../../IIIFEvents";
import { Dialogue } from "../uv-shared-module/Dialogue";
import { ILocale } from "../uv-shared-module/ILocale";
-export class SettingsDialogue extends Dialogue {
+export class SettingsDialogue extends Dialogue<
+ BaseConfig["modules"]["settingsDialogue"]
+> {
$locale: JQuery;
$localeDropDown: JQuery;
$localeLabel: JQuery;
diff --git a/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/MediaElementCenterPanel.ts b/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/MediaElementCenterPanel.ts
index a0b9e4881..78e933591 100644
--- a/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/MediaElementCenterPanel.ts
+++ b/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/MediaElementCenterPanel.ts
@@ -14,7 +14,7 @@ import {
Rendering,
} from "manifesto.js";
import "mediaelement/build/mediaelement-and-player";
-import 'mediaelement/build/mediaelementplayer.min.css';
+import "mediaelement/build/mediaelementplayer.min.css";
import "./js/source-chooser-fixed.js";
import "mediaelement-plugins/dist/source-chooser/source-chooser.css";
import { TFragment } from "../uv-shared-module/TFragment";
diff --git a/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/js/source-chooser-fixed.js b/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/js/source-chooser-fixed.js
index b90518477..bd234c948 100644
--- a/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/js/source-chooser-fixed.js
+++ b/src/content-handlers/iiif/modules/uv-mediaelementcenterpanel-module/js/source-chooser-fixed.js
@@ -26,280 +26,461 @@
* Copyright 2010-2017, John Dyer (http://j.hn/)
* License: MIT
*
- */(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i' + ('');
-
- t.addControlElement(player.sourcechooserButton, 'sourcechooser');
-
- for (var _i = 0, _total = sources.length; _i < _total; _i++) {
- var src = sources[_i];
- if (src.type !== undefined && typeof media.canPlayType === 'function') {
- player.addSourceButton(src.src, src.title, src.type, media.src === src.src);
- }
- }
-
- player.sourcechooserButton.addEventListener('mouseover', function () {
- clearTimeout(hoverTimeout);
- player.showSourcechooserSelector();
- });
- player.sourcechooserButton.addEventListener('mouseout', function () {
- hoverTimeout = setTimeout(function () {
- player.hideSourcechooserSelector();
- }, 0);
- });
-
- player.sourcechooserButton.addEventListener('keydown', function (e) {
-
- function focusNext(dir = 1) {
- let radioEls = Array.from(player.sourcechooserButton.querySelectorAll('input[type="radio"]'));
- let index = radioEls.indexOf(document.activeElement);
- let next = dir === 1 ? 1 : radioEls.length - 1;
- let nextIndex = (index + next) % radioEls.length;
- radioEls[nextIndex].focus();
- }
-
- if (t.options.keyActions.length) {
- var keyCode = e.which || e.keyCode || 0;
-
- let stopPropagation = false;
- switch (keyCode) {
- case 13: // Enter
- case 32: // Space Bar
- if (!player.isSourcechooserSelectorOpen()) {
- player.showSourcechooserSelector();
- player.sourcechooserButton.querySelector('input[type=radio]:checked').focus();
- stopPropagation = true;
- } else if (
- document.activeElement.matches('input[type="radio"]') &&
- player.sourcechooserButton.contains(document.activeElement)
- ) {
- // Handle keyboard selection of radio inputs
- document.activeElement.click();
- stopPropagation = true;
-
- // a slight delay before close
- // to show that the new source was selected
- setTimeout(() => {
- player.hideSourcechooserSelector();
- player.sourcechooserButton.querySelector('button').focus();
- }, 150);
- }
- break;
- case 27: // Escape
- player.hideSourcechooserSelector();
- player.sourcechooserButton.querySelector('button').focus();
- stopPropagation = true;
- break;
- case 9: // Tab
- if (player.isSourcechooserSelectorOpen()) {
- // Get focused element
- let checked = document.activeElement;
- // Focus next radio element
- if (
- checked.matches('input[type="radio"]') &&
- player.sourcechooserButton.contains(checked)
- ) {
- focusNext(e.shiftKey ? -1 : 1);
- stopPropagation = true;
- }
- }
- break;
-
- // Handle keyboard selection of radio inputs
- case 37: // Left Arrow
- case 38: // Up Arrow
- case 39: // Right Arrow
- case 40: // Down Arrow
- if (!player.isSourcechooserSelectorOpen()) {
- break;
- }
-
- if (
- document.activeElement.matches('input[type="radio"]') &&
- player.sourcechooserButton.contains(document.activeElement)
- ) {
- let dir = keyCode === 37 || keyCode === 38 ? -1 : 1;
- focusNext(dir);
- stopPropagation = true;
- }
- break;
- default:
- return true;
- }
-
- if (stopPropagation) {
- e.preventDefault();
- e.stopPropagation();
- return false;
- }
-
- return true;
- }
- });
-
- player.sourcechooserButton.addEventListener('focusout', mejs.Utils.debounce(function () {
- setTimeout(function () {
- var parent = document.activeElement.closest('.' + t.options.classPrefix + 'sourcechooser-selector');
- if (!parent) {
- player.hideSourcechooserSelector();
- }
- }, 0);
- }, 100));
-
- var radios = player.sourcechooserButton.querySelectorAll('input[type=radio]');
-
- for (var _i2 = 0, _total2 = radios.length; _i2 < _total2; _i2++) {
- radios[_i2].addEventListener('click', function () {
- this.setAttribute('aria-selected', true);
- this.checked = true;
-
- var otherRadios = this.closest('.' + t.options.classPrefix + 'sourcechooser-selector').querySelectorAll('input[type=radio]');
-
- for (var j = 0, radioTotal = otherRadios.length; j < radioTotal; j++) {
- if (otherRadios[j] !== this) {
- otherRadios[j].setAttribute('aria-selected', 'false');
- otherRadios[j].removeAttribute('checked');
- }
- }
-
- var src = this.value;
-
- if (media.getSrc() !== src) {
- var currentTime = media.currentTime;
-
- var paused = media.paused,
- canPlayAfterSourceSwitchHandler = function canPlayAfterSourceSwitchHandler() {
- if (!paused) {
- media.setCurrentTime(currentTime);
- media.play();
- }
- media.removeEventListener('canplay', canPlayAfterSourceSwitchHandler);
- };
-
- media.pause();
- media.setSrc(src);
- media.load();
- media.addEventListener('canplay', canPlayAfterSourceSwitchHandler);
- }
- });
- }
-
- player.sourcechooserButton.querySelector('button').addEventListener('click', function () {
-
- var t = this;
-
- if (t.sourcechooserButton === undefined || !t.sourcechooserButton.querySelector('input[type=radio]')) {
- return false;
- }
-
- if (!player.isSourcechooserSelectorOpen()) {
- player.showSourcechooserSelector();
- player.sourcechooserButton.querySelector('input[type=radio]:checked').focus();
- } else {
- player.hideSourcechooserSelector();
- }
- });
- },
- addSourceButton: function addSourceButton(src, label, type, isCurrent) {
- var t = this;
- if (label === '' || label === undefined) {
- label = src;
- }
- type = type.split('/')[1];
-
- t.sourcechooserButton.querySelector('ul').innerHTML += '' + ('') + ('') + '';
-
- t.adjustSourcechooserBox();
- },
- adjustSourcechooserBox: function adjustSourcechooserBox() {
- var t = this;
-
- t.sourcechooserButton.querySelector('.' + t.options.classPrefix + 'sourcechooser-selector').style.height = parseFloat(t.sourcechooserButton.querySelector('.' + t.options.classPrefix + 'sourcechooser-selector ul').offsetHeight) + 'px';
- },
- /**
- * @returns {boolean}
- */
- isSourcechooserSelectorOpen: function isSourcechooserSelectorOpen() {
-
- var t = this;
-
- if (t.sourcechooserButton === undefined || !t.sourcechooserButton.querySelector('input[type=radio]')) {
- return false;
- }
-
- var selectorEl = t.sourcechooserButton.querySelector('.' + t.options.classPrefix + 'sourcechooser-selector');
- return mejs.Utils.hasClass(selectorEl, t.options.classPrefix + 'offscreen') === false;
- },
- hideSourcechooserSelector: function hideSourcechooserSelector() {
-
- var t = this;
-
- if (t.sourcechooserButton === undefined || !t.sourcechooserButton.querySelector('input[type=radio]')) {
- return;
- }
-
- var selector = t.sourcechooserButton.querySelector('.' + t.options.classPrefix + 'sourcechooser-selector'),
- radios = selector.querySelectorAll('input[type=radio]');
- selector.setAttribute('aria-expanded', 'false');
- selector.setAttribute('aria-hidden', 'true');
- mejs.Utils.addClass(selector, t.options.classPrefix + 'offscreen');
-
- for (var i = 0, total = radios.length; i < total; i++) {
- radios[i].setAttribute('tabindex', '-1');
- }
- },
- showSourcechooserSelector: function showSourcechooserSelector() {
-
- var t = this;
-
- if (t.sourcechooserButton === undefined || !t.sourcechooserButton.querySelector('input[type=radio]')) {
- return;
- }
-
- var selector = t.sourcechooserButton.querySelector('.' + t.options.classPrefix + 'sourcechooser-selector'),
- radios = selector.querySelectorAll('input[type=radio]');
- selector.setAttribute('aria-expanded', 'true');
- selector.setAttribute('aria-hidden', 'false');
- mejs.Utils.removeClass(selector, t.options.classPrefix + 'offscreen');
-
- for (var i = 0, total = radios.length; i < total; i++) {
- radios[i].setAttribute('tabindex', '0');
- }
- }
- });
-
- },{}]},{},[1]);
+ */ (function () {
+ function r(e, n, t) {
+ function o(i, f) {
+ if (!n[i]) {
+ if (!e[i]) {
+ var c = "function" == typeof require && require;
+ if (!f && c) return c(i, !0);
+ if (u) return u(i, !0);
+ var a = new Error("Cannot find module '" + i + "'");
+ throw ((a.code = "MODULE_NOT_FOUND"), a);
+ }
+ var p = (n[i] = { exports: {} });
+ e[i][0].call(
+ p.exports,
+ function (r) {
+ var n = e[i][1][r];
+ return o(n || r);
+ },
+ p,
+ p.exports,
+ r,
+ e,
+ n,
+ t
+ );
+ }
+ return n[i].exports;
+ }
+ for (
+ var u = "function" == typeof require && require, i = 0;
+ i < t.length;
+ i++
+ )
+ o(t[i]);
+ return o;
+ }
+ return r;
+})()(
+ {
+ 1: [
+ function (_dereq_, module, exports) {
+ "use strict";
+
+ mejs.i18n.en["mejs.source-chooser"] = "Source Chooser";
+
+ Object.assign(mejs.MepDefaults, {
+ sourcechooserText: null,
+ });
+
+ Object.assign(MediaElementPlayer.prototype, {
+ buildsourcechooser: function buildsourcechooser(
+ player,
+ controls,
+ layers,
+ media
+ ) {
+ var t = this,
+ sourceTitle = mejs.Utils.isString(t.options.sourcechooserText)
+ ? t.options.sourcechooserText
+ : mejs.i18n.t("mejs.source-chooser"),
+ sources = [],
+ children = t.mediaFiles ? t.mediaFiles : t.node.children;
+
+ var hoverTimeout = void 0;
+
+ for (var i = 0, total = children.length; i < total; i++) {
+ var s = children[i];
+
+ if (t.mediaFiles) {
+ sources.push(s);
+ } else if (s.nodeName === "SOURCE") {
+ sources.push(s);
+ }
+ }
+
+ if (sources.length <= 1) {
+ return;
+ }
+
+ player.sourcechooserButton = document.createElement("div");
+ player.sourcechooserButton.className =
+ t.options.classPrefix +
+ "button " +
+ t.options.classPrefix +
+ "sourcechooser-button";
+ player.sourcechooserButton.innerHTML =
+ '' +
+ ('');
+
+ t.addControlElement(player.sourcechooserButton, "sourcechooser");
+
+ for (var _i = 0, _total = sources.length; _i < _total; _i++) {
+ var src = sources[_i];
+ if (
+ src.type !== undefined &&
+ typeof media.canPlayType === "function"
+ ) {
+ player.addSourceButton(
+ src.src,
+ src.title,
+ src.type,
+ media.src === src.src
+ );
+ }
+ }
+
+ player.sourcechooserButton.addEventListener(
+ "mouseover",
+ function () {
+ clearTimeout(hoverTimeout);
+ player.showSourcechooserSelector();
+ }
+ );
+ player.sourcechooserButton.addEventListener(
+ "mouseout",
+ function () {
+ hoverTimeout = setTimeout(function () {
+ player.hideSourcechooserSelector();
+ }, 0);
+ }
+ );
+
+ player.sourcechooserButton.addEventListener(
+ "keydown",
+ function (e) {
+ function focusNext(dir = 1) {
+ let radioEls = Array.from(
+ player.sourcechooserButton.querySelectorAll(
+ 'input[type="radio"]'
+ )
+ );
+ let index = radioEls.indexOf(document.activeElement);
+ let next = dir === 1 ? 1 : radioEls.length - 1;
+ let nextIndex = (index + next) % radioEls.length;
+ radioEls[nextIndex].focus();
+ }
+
+ if (t.options.keyActions.length) {
+ var keyCode = e.which || e.keyCode || 0;
+
+ let stopPropagation = false;
+ switch (keyCode) {
+ case 13: // Enter
+ case 32: // Space Bar
+ if (!player.isSourcechooserSelectorOpen()) {
+ player.showSourcechooserSelector();
+ player.sourcechooserButton
+ .querySelector("input[type=radio]:checked")
+ .focus();
+ stopPropagation = true;
+ } else if (
+ document.activeElement.matches('input[type="radio"]') &&
+ player.sourcechooserButton.contains(
+ document.activeElement
+ )
+ ) {
+ // Handle keyboard selection of radio inputs
+ document.activeElement.click();
+ stopPropagation = true;
+
+ // a slight delay before close
+ // to show that the new source was selected
+ setTimeout(() => {
+ player.hideSourcechooserSelector();
+ player.sourcechooserButton
+ .querySelector("button")
+ .focus();
+ }, 150);
+ }
+ break;
+ case 27: // Escape
+ player.hideSourcechooserSelector();
+ player.sourcechooserButton
+ .querySelector("button")
+ .focus();
+ stopPropagation = true;
+ break;
+ case 9: // Tab
+ if (player.isSourcechooserSelectorOpen()) {
+ // Get focused element
+ let checked = document.activeElement;
+ // Focus next radio element
+ if (
+ checked.matches('input[type="radio"]') &&
+ player.sourcechooserButton.contains(checked)
+ ) {
+ focusNext(e.shiftKey ? -1 : 1);
+ stopPropagation = true;
+ }
+ }
+ break;
+
+ // Handle keyboard selection of radio inputs
+ case 37: // Left Arrow
+ case 38: // Up Arrow
+ case 39: // Right Arrow
+ case 40: // Down Arrow
+ if (!player.isSourcechooserSelectorOpen()) {
+ break;
+ }
+
+ if (
+ document.activeElement.matches('input[type="radio"]') &&
+ player.sourcechooserButton.contains(
+ document.activeElement
+ )
+ ) {
+ let dir = keyCode === 37 || keyCode === 38 ? -1 : 1;
+ focusNext(dir);
+ stopPropagation = true;
+ }
+ break;
+ default:
+ return true;
+ }
+
+ if (stopPropagation) {
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+
+ return true;
+ }
+ }
+ );
+
+ player.sourcechooserButton.addEventListener(
+ "focusout",
+ mejs.Utils.debounce(function () {
+ setTimeout(function () {
+ var parent = document.activeElement.closest(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ );
+ if (!parent) {
+ player.hideSourcechooserSelector();
+ }
+ }, 0);
+ }, 100)
+ );
+
+ var radios =
+ player.sourcechooserButton.querySelectorAll("input[type=radio]");
+
+ for (var _i2 = 0, _total2 = radios.length; _i2 < _total2; _i2++) {
+ radios[_i2].addEventListener("click", function () {
+ this.setAttribute("aria-selected", true);
+ this.checked = true;
+
+ var otherRadios = this.closest(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ ).querySelectorAll("input[type=radio]");
+
+ for (
+ var j = 0, radioTotal = otherRadios.length;
+ j < radioTotal;
+ j++
+ ) {
+ if (otherRadios[j] !== this) {
+ otherRadios[j].setAttribute("aria-selected", "false");
+ otherRadios[j].removeAttribute("checked");
+ }
+ }
+
+ var src = this.value;
+
+ if (media.getSrc() !== src) {
+ var currentTime = media.currentTime;
+
+ var paused = media.paused,
+ canPlayAfterSourceSwitchHandler =
+ function canPlayAfterSourceSwitchHandler() {
+ if (!paused) {
+ media.setCurrentTime(currentTime);
+ media.play();
+ }
+ media.removeEventListener(
+ "canplay",
+ canPlayAfterSourceSwitchHandler
+ );
+ };
+
+ media.pause();
+ media.setSrc(src);
+ media.load();
+ media.addEventListener(
+ "canplay",
+ canPlayAfterSourceSwitchHandler
+ );
+ }
+ });
+ }
+
+ player.sourcechooserButton
+ .querySelector("button")
+ .addEventListener("click", function () {
+ var t = this;
+
+ if (
+ t.sourcechooserButton === undefined ||
+ !t.sourcechooserButton.querySelector("input[type=radio]")
+ ) {
+ return false;
+ }
+
+ if (!player.isSourcechooserSelectorOpen()) {
+ player.showSourcechooserSelector();
+ player.sourcechooserButton
+ .querySelector("input[type=radio]:checked")
+ .focus();
+ } else {
+ player.hideSourcechooserSelector();
+ }
+ });
+ },
+ addSourceButton: function addSourceButton(
+ src,
+ label,
+ type,
+ isCurrent
+ ) {
+ var t = this;
+ if (label === "" || label === undefined) {
+ label = src;
+ }
+ type = type.split("/")[1];
+
+ t.sourcechooserButton.querySelector("ul").innerHTML +=
+ "" +
+ ('') +
+ ('") +
+ "";
+
+ t.adjustSourcechooserBox();
+ },
+ adjustSourcechooserBox: function adjustSourcechooserBox() {
+ var t = this;
+
+ t.sourcechooserButton.querySelector(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ ).style.height =
+ parseFloat(
+ t.sourcechooserButton.querySelector(
+ "." + t.options.classPrefix + "sourcechooser-selector ul"
+ ).offsetHeight
+ ) + "px";
+ },
+ /**
+ * @returns {boolean}
+ */
+ isSourcechooserSelectorOpen: function isSourcechooserSelectorOpen() {
+ var t = this;
+
+ if (
+ t.sourcechooserButton === undefined ||
+ !t.sourcechooserButton.querySelector("input[type=radio]")
+ ) {
+ return false;
+ }
+
+ var selectorEl = t.sourcechooserButton.querySelector(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ );
+ return (
+ mejs.Utils.hasClass(
+ selectorEl,
+ t.options.classPrefix + "offscreen"
+ ) === false
+ );
+ },
+ hideSourcechooserSelector: function hideSourcechooserSelector() {
+ var t = this;
+
+ if (
+ t.sourcechooserButton === undefined ||
+ !t.sourcechooserButton.querySelector("input[type=radio]")
+ ) {
+ return;
+ }
+
+ var selector = t.sourcechooserButton.querySelector(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ ),
+ radios = selector.querySelectorAll("input[type=radio]");
+ selector.setAttribute("aria-expanded", "false");
+ selector.setAttribute("aria-hidden", "true");
+ mejs.Utils.addClass(selector, t.options.classPrefix + "offscreen");
+
+ for (var i = 0, total = radios.length; i < total; i++) {
+ radios[i].setAttribute("tabindex", "-1");
+ }
+ },
+ showSourcechooserSelector: function showSourcechooserSelector() {
+ var t = this;
+
+ if (
+ t.sourcechooserButton === undefined ||
+ !t.sourcechooserButton.querySelector("input[type=radio]")
+ ) {
+ return;
+ }
+
+ var selector = t.sourcechooserButton.querySelector(
+ "." + t.options.classPrefix + "sourcechooser-selector"
+ ),
+ radios = selector.querySelectorAll("input[type=radio]");
+ selector.setAttribute("aria-expanded", "true");
+ selector.setAttribute("aria-hidden", "false");
+ mejs.Utils.removeClass(
+ selector,
+ t.options.classPrefix + "offscreen"
+ );
+
+ for (var i = 0, total = radios.length; i < total; i++) {
+ radios[i].setAttribute("tabindex", "0");
+ }
+ },
+ });
+ },
+ {},
+ ],
+ },
+ {},
+ [1]
+);
diff --git a/src/content-handlers/iiif/modules/uv-openseadragoncenterpanel-module/OpenSeadragonCenterPanel.ts b/src/content-handlers/iiif/modules/uv-openseadragoncenterpanel-module/OpenSeadragonCenterPanel.ts
index e25a9270b..6cb9139fa 100644
--- a/src/content-handlers/iiif/modules/uv-openseadragoncenterpanel-module/OpenSeadragonCenterPanel.ts
+++ b/src/content-handlers/iiif/modules/uv-openseadragoncenterpanel-module/OpenSeadragonCenterPanel.ts
@@ -587,13 +587,13 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
if (this.extension.helper.isRightToLeft()) {
this.$prevButton
- .prop("title", this.content.nextImage)
- .attr("aria-label", this.content.nextImage);
- } else {
+ .prop("title", this.content.nextImage)
+ .attr("aria-label", this.content.nextImage);
+ } else {
this.$prevButton
- .prop("title", this.content.previousImage)
- .attr("aria-label", this.content.previousImage);
- }
+ .prop("title", this.content.previousImage)
+ .attr("aria-label", this.content.previousImage);
+ }
this.$nextButton = $(
`