Skip to content

Commit

Permalink
Merge pull request #2 from UniversalViewer/dev
Browse files Browse the repository at this point in the history
Update 917 fix branch with latest dev
  • Loading branch information
LlGC-jop authored Oct 29, 2024
2 parents 6ab0817 + 549db51 commit 44e19d0
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 61 deletions.
3 changes: 3 additions & 0 deletions src/content-handlers/iiif/BaseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ export type Options = {

/** Determines if zoom to bounds is enabled */
zoomToBoundsEnabled?: boolean;

/** Controls whether to have animations or not */
reducedAnimation?: boolean;
};

type Locale = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ const DownloadDialogue = ({
triggerButton: HTMLElement;
}) => {
const ref = useRef<HTMLDivElement>(null);

const [position, setPosition] = useState({ top: "0px", left: "0px" });
const [arrowPosition, setArrowPosition] = useState("0px 0px");
const [selectedPage, setSelectedPage] = useState<"left" | "right">("left");
Expand Down Expand Up @@ -109,12 +108,59 @@ const DownloadDialogue = ({

setPosition({ top: `${top}px`, left: `${left}px` });
setArrowPosition(`${arrowLeft}px 0px`);

// Focus on the first element when opened
const focusableElements = getFocusableElements();
if (focusableElements && focusableElements.length > 0) {
focusableElements[0]?.focus();
}
}
}, [open]);

if (!open) {
return null;
}
// Method to get focusable elements inside the component
const getFocusableElements = (): NodeListOf<HTMLElement> | null => {
return ref.current?.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
) as NodeListOf<HTMLElement>;
};


// Focus trapping logic
const handleTabKey = (e: KeyboardEvent) => {
if (e.key === "Tab") {
const focusableElements = getFocusableElements();
if (!focusableElements) return;

const firstFocusableElement = focusableElements[0] as HTMLElement;
const lastFocusableElement = focusableElements[focusableElements.length - 1] as HTMLElement;

if (e.shiftKey) {
// If Shift + Tab is pressed and the focus is on the first element, go to the last
if (document.activeElement === firstFocusableElement) {
e.preventDefault();
lastFocusableElement.focus();
}
} else {
// If Tab is pressed and the focus is on the last element, go to the first
if (document.activeElement === lastFocusableElement) {
e.preventDefault();
firstFocusableElement.focus();
}
}
}
};

useEffect(() => {
if (open) {
document.addEventListener("keydown", handleTabKey);
}

return () => {
document.removeEventListener("keydown", handleTabKey);
};
}, [open]);

if (!open) return null;

function getCanvasDimensions(canvas: Canvas): Size | null {
// externalResource may not have loaded yet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,6 @@ export default class OpenSeadragonExtension extends BaseExtension<Config> {
IIIFEvents.CANVAS_INDEX_CHANGE,
this.helper.canvasIndex
);
const settings: ISettings = this.getSettings();
this.extensionHost.publish(IIIFEvents.SETTINGS_CHANGE, settings);
});

this.extensionHost.subscribe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ export class ContentLeftPanel extends LeftPanel<ContentLeftPanelConfig> {
$treeViewOptions: JQuery;
$treeSelect: JQuery;
$views: JQuery;
$keyElement: JQuery
expandFullEnabled: boolean = false;
galleryView: GalleryView;
isThumbsViewOpen: boolean = false;
isTreeViewOpen: boolean = false;
keyPress:boolean = false;
treeData: TreeNode;
treeSortType: TreeSortType = TreeSortType.NONE;
treeView: TreeView;
Expand Down Expand Up @@ -211,11 +213,11 @@ export class ContentLeftPanel extends LeftPanel<ContentLeftPanelConfig> {

this.onAccessibleClick(this.$treeButton, () => {
this.openTreeView();
});
}, true, true);

this.onAccessibleClick(this.$thumbsButton, () => {
this.openThumbsView();
});
}, true, true);

this.setTitle(this.content.title);

Expand Down Expand Up @@ -505,10 +507,12 @@ export class ContentLeftPanel extends LeftPanel<ContentLeftPanelConfig> {
onClick: (thumb: Thumb) => {
this.extensionHost.publish(IIIFEvents.THUMB_SELECTED, thumb);
},
onKeyDown: (thumb: Thumb) => {
this.extensionHost.publish(IIIFEvents.THUMB_SELECTED, thumb);
},
})
);
}

createGalleryView(): void {
this.galleryView = new GalleryView(this.$galleryView);
this.galleryView.galleryData = this.getGalleryData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import cx from "classnames";
const ThumbImage = ({
first,
onClick,
onKeyDown,
paged,
selected,
thumb,
viewingDirection,
}: {
first: boolean;
onClick: (thumb: Thumb) => void;
onKeyDown: (thumb: Thumb) => void;
paged: boolean;
selected: boolean;
thumb: Thumb;
Expand All @@ -25,9 +27,15 @@ const ThumbImage = ({
triggerOnce: true,
});

var keydownHandler = (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault(); onKeyDown(thumb)
}
};
return (
<div
onClick={() => onClick(thumb)}
onKeyDown= {keydownHandler}
className={cx("thumb", {
first: first,
placeholder: !thumb.uri,
Expand Down Expand Up @@ -64,12 +72,14 @@ const ThumbImage = ({

const Thumbnails = ({
onClick,
onKeyDown,
paged,
selected,
thumbs,
viewingDirection,
}: {
onClick: (thumb: Thumb) => void;
onKeyDown: (thumb: Thumb) => void;
paged: boolean;
selected: number[];
thumbs: Thumb[];
Expand Down Expand Up @@ -122,6 +132,7 @@ const Thumbnails = ({
<ThumbImage
first={index === firstNonPagedIndex}
onClick={onClick}
onKeyDown={onKeyDown}
paged={paged}
selected={selected.includes(index)}
thumb={thumb}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ export class AdjustImageDialogue extends Dialogue<
}
this.shell.$overlays.css('background', '');
super.close();

// put focus back on the button when the dialogue is closed
(<OpenSeadragonExtension>(this.extension)).centerPanel.$adjustImageButton.focus();
}

resize(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ export class SettingsDialogue extends Dialogue<

this.$reducedAnimation.append(this.$reducedAnimationLabel);

const settings: ISettings = this.getSettings();

if (settings.reducedAnimation) {
this.$reducedAnimationCheckbox.prop("checked", true);
} else {
this.$reducedAnimationCheckbox.removeAttr("checked");
}

this.$reducedAnimationCheckbox.change(() => {
const settings: ISettings = {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,11 @@ export class ShareDialogue<

this.onAccessibleClick(this.$shareButton, () => {
this.openShareView();
});
}, true, true);

this.onAccessibleClick(this.$embedButton, () => {
this.openEmbedView();
});
}, true, true);

this.$customSizeDropDown.change(() => {
this.update();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
IIIFEvents.SETTINGS_CHANGE,
(args: ISettings) => {
this.viewer.gestureSettingsMouse.clickToZoom = args.clickToZoomEnabled;
this.viewer.controlsFadeLength = this.getControlsFadeLength();
}
);

Expand Down Expand Up @@ -249,7 +250,7 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
defaultZoomLevel: this.config.options.defaultZoomLevel || 0,
maxZoomPixelRatio: this.config.options.maxZoomPixelRatio || 2,
controlsFadeDelay: this.config.options.controlsFadeDelay || 250,
controlsFadeLength: this.config.options.controlsFadeLength || 250,
controlsFadeLength: this.getControlsFadeLength(),
navigatorPosition:
this.config.options.navigatorPosition || "BOTTOM_RIGHT",
navigatorHeight: "100px",
Expand Down Expand Up @@ -365,24 +366,40 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
this.$zoomInButton.prop("aria-label", this.content.zoomIn);
this.$zoomInButton.addClass("zoomIn viewportNavButton");

this.onAccessibleClick(this.$zoomInButton, () => {
this.zoomIn();
});

this.$zoomOutButton = this.$viewer.find('div[title="Zoom out"]');
this.$zoomOutButton.attr("tabindex", 0);
this.$zoomOutButton.prop("title", this.content.zoomOut);
this.$zoomOutButton.prop("aria-label", this.content.zoomOut);
this.$zoomOutButton.addClass("zoomOut viewportNavButton");

this.onAccessibleClick(this.$zoomOutButton, () => {
this.zoomOut();
});

this.$goHomeButton = this.$viewer.find('div[title="Go home"]');
this.$goHomeButton.attr("tabindex", 0);
this.$goHomeButton.prop("title", this.content.goHome);
this.$goHomeButton.prop("aria-label", this.content.goHome);
this.$goHomeButton.addClass("goHome viewportNavButton");

this.onAccessibleClick(this.$goHomeButton, () => {
this.goHome();
});

this.$rotateButton = this.$viewer.find('div[title="Rotate right"]');
this.$rotateButton.attr("tabindex", 0);
this.$rotateButton.prop("title", this.content.rotateRight);
this.$rotateButton.prop("aria-label", this.content.rotateRight);
this.$rotateButton.addClass("rotate viewportNavButton");

this.onAccessibleClick(this.$rotateButton, () => {
this.rotateRight();
});

if (this.showAdjustImageButton) {
this.$adjustImageButton = this.$rotateButton.clone();
this.$adjustImageButton.prop('title', this.content.adjustImage);
Expand All @@ -391,6 +408,10 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
this.extensionHost.publish(IIIFEvents.SHOW_ADJUSTIMAGE_DIALOGUE);
});
this.$adjustImageButton.insertAfter(this.$rotateButton);

this.onAccessibleClick(this.$adjustImageButton, () => {
this.extensionHost.publish(IIIFEvents.SHOW_ADJUSTIMAGE_DIALOGUE);
});
}

this.$viewportNavButtonsContainer = this.$viewer.find(
Expand Down Expand Up @@ -1473,4 +1494,8 @@ export class OpenSeadragonCenterPanel extends CenterPanel<
}
}
}

getControlsFadeLength(): number {
return (<ISettings>this.extension.getSettings()).reducedAnimation ? 0 : this.config.options.controlsFadeLength || 250;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ export class PagingHeaderPanel extends HeaderPanel<
this.$search.append(this.$total);

this.$searchButton = $(
`<a class="go btn btn-primary" tabindex="0">${this.content.go}</a>`
`<button class="go btn btn-primary" tabindex="0">${this.content.go}</button>`
);
this.$search.append(this.$searchButton);

Expand Down Expand Up @@ -407,7 +407,7 @@ export class PagingHeaderPanel extends HeaderPanel<
$(this).select();
});

this.$searchButton.onPressed(() => {
this.onAccessibleClick(this.$searchButton, () => {
if (this.options.autoCompleteBoxEnabled) {
this.search(this.$autoCompleteBox.val());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export class PDFCenterPanel extends CenterPanel<
<span class="sr-only">${this.content.next}</span>
</button>`
);
this._$zoomInButton = $('<div class="btn zoomIn" tabindex="0"></div>');
this._$zoomOutButton = $('<div class="btn zoomOut" tabindex="0"></div>');
this._$zoomInButton = $('<button class="btn zoomIn" tabindex="0"></button>');
this._$zoomOutButton = $('<button class="btn zoomOut" tabindex="0"></button>');

// Only attach PDF controls if we're using PDF.js; they have no meaning in
// PDFObject. However, we still create the objects above so that references
Expand Down Expand Up @@ -185,9 +185,7 @@ export class PDFCenterPanel extends CenterPanel<

this.disableNextButton();

this._$zoomInButton.onPressed((e: any) => {
e.preventDefault();

this.onAccessibleClick(this._$zoomInButton, () => {
const newScale: number = this._scale + 0.5;

if (newScale < this._maxScale) {
Expand All @@ -199,9 +197,7 @@ export class PDFCenterPanel extends CenterPanel<
this._render(this._pageIndex);
});

this._$zoomOutButton.onPressed((e: any) => {
e.preventDefault();

this.onAccessibleClick(this._$zoomOutButton, () => {
const newScale: number = this._scale - 0.5;

if (newScale > this._minScale) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class PDFHeaderPanel extends HeaderPanel<
this.$search.append(this.$total);

this.$searchButton = $(
'<a class="go btn btn-primary" tabindex="0">' + this.content.go + "</a>"
'<button class="go btn btn-primary" tabindex="0">' + this.content.go + "</button>"
);
this.$search.append(this.$searchButton);
this.$searchButton.disable();
Expand Down Expand Up @@ -138,7 +138,7 @@ export class PDFHeaderPanel extends HeaderPanel<
$(this).select();
});

this.$searchButton.onPressed(() => {
this.onAccessibleClick(this.$searchButton, () => {
this.search(this.$searchText.val());
});
}
Expand Down
Loading

0 comments on commit 44e19d0

Please sign in to comment.