diff --git a/eslint.config.js b/eslint.config.js index 55e792b2..e4da029a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -76,7 +76,6 @@ export default tseslint.config( }, ], "@typescript-eslint/no-import-type-side-effects": "error", - "@typescript-eslint/no-non-null-assertion": "off", "@typescript-eslint/no-shadow": "error", "@typescript-eslint/no-unnecessary-parameter-property-assignment": "error", diff --git a/src/index.ts b/src/index.ts index f0056ada..4a6fd248 100644 --- a/src/index.ts +++ b/src/index.ts @@ -75,8 +75,8 @@ const manualOpenGallery = new ImageLightbox( ); document .getElementsByClassName("trigger_lightbox") - .item(0)! - .addEventListener("click", () => { + .item(0) + ?.addEventListener("click", () => { manualOpenGallery.open(); }); @@ -89,13 +89,13 @@ const dynamicAddingGallery = new ImageLightbox( ); document .getElementsByClassName("add_image") - .item(0)! - .addEventListener("click", () => { + .item(0) + ?.addEventListener("click", () => { const linkContainer = document .getElementsByClassName("demo_dynamic") - .item(0)!; + .item(0); const newLi = document.createElement("li"); - linkContainer.appendChild(newLi); + linkContainer?.appendChild(newLi); const newAnchor = document.createElement("a"); newAnchor.dataset["imagelightbox"] = "i"; diff --git a/src/lib/ImageView.ts b/src/lib/ImageView.ts index edecf768..4ef881cf 100644 --- a/src/lib/ImageView.ts +++ b/src/lib/ImageView.ts @@ -38,11 +38,17 @@ export function ImageView( containerElement.classList.add("ilb-image-container"); let isVideoPreloaded: boolean | undefined = undefined; - const isVideo = image.dataset["ilb2Video"] !== undefined; + const videoId = image.dataset["ilb2VideoId"]; + let isVideo = + image.dataset["ilb2Video"] !== undefined && videoId !== undefined; if (isVideo) { - [imageElement, isVideoPreloaded] = videoCache.element( - image.dataset["ilb2VideoId"]!, - ); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Checked by the if above + const videoElement = videoCache.element(videoId!); + if (videoElement !== undefined) { + [imageElement, isVideoPreloaded] = videoElement; + } else { + isVideo = false; + } } containerElement.appendChild(imageElement); diff --git a/src/lib/PreloadedVideo.ts b/src/lib/PreloadedVideo.ts index e5ff0081..4743bf63 100644 --- a/src/lib/PreloadedVideo.ts +++ b/src/lib/PreloadedVideo.ts @@ -1,7 +1,6 @@ import type { VideoOptions } from "./interfaces/VideoOptions"; export interface PreloadedVideo { - dimensions(): [number, number]; element(): [HTMLVideoElement, boolean]; id(): string; } @@ -24,8 +23,6 @@ export function PreloadedVideo( videoElement.dataset["ilb2VideoId"] = videoId; let isLoaded = false; let autoplay = false; - let height: number | undefined = undefined; - let width: number | undefined = undefined; for (const [key, value] of Object.entries(videoOptions)) { switch (key) { @@ -40,12 +37,6 @@ export function PreloadedVideo( case "src": videoElement.setAttribute(key, (value as number | string).toString()); break; - case "height": - height = value as number; - break; - case "width": - width = value as number; - break; default: } } @@ -66,10 +57,6 @@ export function PreloadedVideo( return videoId; } - function dimensions(): [number, number] { - return [width ?? videoElement.width, height ?? videoElement.height]; - } - function element(): [HTMLVideoElement, boolean] { if (autoplay) { if (isLoaded) { @@ -82,7 +69,6 @@ export function PreloadedVideo( } return { - dimensions, element, id, }; diff --git a/src/lib/State.ts b/src/lib/State.ts index 639a81cf..2a580c82 100644 --- a/src/lib/State.ts +++ b/src/lib/State.ts @@ -87,7 +87,10 @@ export function State( transitionDirection: TransitionDirection, callback?: () => void, ): void { - const oldImageView = currentImageView!; + if (currentImageView === null) { + return; + } + const oldImageView = currentImageView; oldImageView.transitionOut(transitionDirection, () => { oldImageView.removeFromDOM(); callback?.(); @@ -107,7 +110,10 @@ export function State( function addNewImage(transitionDirection: TransitionDirection): void { currentImageView?.addToDOM(transitionDirection, () => { - const image = targetImages[currentImage!]; + if (currentImage === null) { + return; + } + const image = targetImages[currentImage]; if (options.caption) { setCaption( image.dataset["ilb2Caption"] ?? @@ -117,8 +123,8 @@ export function State( ); } transitionInNewImage(); - if (options.preloadNext && currentImage! + 1 < targetImages.length) { - const nextImage = targetImages[currentImage! + 1]; + if (options.preloadNext && currentImage + 1 < targetImages.length) { + const nextImage = targetImages[currentImage + 1]; const nextImageElement = document.createElement("img"); nextImageElement.setAttribute( "src", diff --git a/src/lib/VideoCache.ts b/src/lib/VideoCache.ts index 368f822f..ee9ebe6c 100644 --- a/src/lib/VideoCache.ts +++ b/src/lib/VideoCache.ts @@ -4,8 +4,7 @@ import { PreloadedVideo } from "./PreloadedVideo"; export interface VideoCache { add(elements: Array): void; - dimensions(videoId: string): [number, number] | undefined; - element(videoId: string): [HTMLVideoElement, boolean]; + element(videoId: string): [HTMLVideoElement, boolean] | undefined; } export function VideoCache(): VideoCache { @@ -23,22 +22,13 @@ export function VideoCache(): VideoCache { } } - function dimensions(videoId: string): [number, number] | undefined { + function element(videoId: string): [HTMLVideoElement, boolean] | undefined { const video = videos.find((x) => x.id() === videoId); - if (video === undefined) { - return undefined; - } - return video.dimensions(); - } - - function element(videoId: string): [HTMLVideoElement, boolean] { - const video = videos.find((x) => x.id() === videoId)!; - return video.element(); + return video?.element(); } return { add, - dimensions, element, }; } diff --git a/src/lib/navigation.ts b/src/lib/navigation.ts index 054dc36b..4b8aa4a7 100644 --- a/src/lib/navigation.ts +++ b/src/lib/navigation.ts @@ -7,7 +7,7 @@ navigation.classList.add("ilb-navigation"); export function addNavigationItems( images: Array, - currentIndex: () => number | null, + currentIndexFn: () => number | null, change: (index: number, transitionDirection: TransitionDirection) => void, animationSpeed: number, ): void { @@ -16,15 +16,20 @@ export function addNavigationItems( const button = document.createElement("button"); button.style.transition = `background-color ${animationSpeed.toString()}ms ease`; const buttonClick = (): void => { - if (button.classList.contains("ilb-navigation-active")) { + const currentIndex = currentIndexFn(); + if ( + button.classList.contains("ilb-navigation-active") || + currentIndex === null || + button.parentNode === null + ) { return; } const buttonIndex = Array.prototype.indexOf.call( - button.parentNode!.childNodes, + button.parentNode.childNodes, button, ); const loadDirection = - buttonIndex < currentIndex()! + buttonIndex < currentIndex ? TransitionDirection.Left : TransitionDirection.Right; change(buttonIndex, loadDirection); @@ -46,13 +51,16 @@ export function changeNavigationCurrent(currentIndex: number): void { export function addNavigationToDOM( images: Array, - currentIndex: () => number | null, + currentIndexFn: () => number | null, change: (index: number, transitionDirection: TransitionDirection) => void, animationSpeed: number, ): void { navigation.textContent = ""; - addNavigationItems(images, currentIndex, change, animationSpeed); - changeNavigationCurrent(currentIndex()!); + addNavigationItems(images, currentIndexFn, change, animationSpeed); + const currentIndex = currentIndexFn(); + if (currentIndex !== null) { + changeNavigationCurrent(currentIndex); + } getContainer().appendChild(navigation); navigation.addEventListener("click", (e) => {