From 5aad62cc4901cde9f5e986a6b855ebcf480f18fb Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Wed, 10 Jan 2024 21:25:36 +0900 Subject: [PATCH] Add explicit type-safe methods to bind for GIF events. --- image/parsers/gif.js | 90 +++++++++++++++++++++++++++++---- index.js | 2 +- tests/image-parsers-gif.spec.js | 10 ++-- 3 files changed, 86 insertions(+), 16 deletions(-) diff --git a/image/parsers/gif.js b/image/parsers/gif.js index 81f202c..2f0cb40 100644 --- a/image/parsers/gif.js +++ b/image/parsers/gif.js @@ -29,7 +29,7 @@ export const GifParseEventType = { * @property {string} version */ -export class GifHeaderParseEvent extends Event { +export class GifHeaderEvent extends Event { /** @param {GifHeader} header */ constructor(header) { super(GifParseEventType.HEADER); @@ -58,7 +58,7 @@ export class GifHeaderParseEvent extends Event { * @property {GifColor[]=} globalColorTable Only if globalColorTableFlag is true. */ -export class GifLogicalScreenParseEvent extends Event { +export class GifLogicalScreenEvent extends Event { /** @param {GifLogicalScreen} */ constructor(logicalScreen) { super(GifParseEventType.LOGICAL_SCREEN); @@ -204,13 +204,83 @@ export class GifParser extends EventTarget { } /** - * Overridden so that the type hints for eventType are specific. - * @param {'application_extension'|'comment_extension'|'graphical_control_extension'|'header'|'logical_screen'|'plain_text_extension'|'table_based_image'|'trailer'} eventType - * @param {EventListenerOrEventListenerObject} listener - * @override + * Type-safe way to bind a listener for a GifApplicationExtensionEvent. + * @param {function(GifApplicationExtensionEvent): void} listener + * @returns {GifParser} for chaining */ - addEventListener(eventType, listener) { - super.addEventListener(eventType, listener); + onApplicationExtension(listener) { + super.addEventListener(GifParseEventType.APPLICATION_EXTENSION, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifCommentExtensionEvent. + * @param {function(GifCommentExtensionEvent): void} listener + * @returns {GifParser} for chaining + */ + onCommentExtension(listener) { + super.addEventListener(GifParseEventType.COMMENT_EXTENSION, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifGraphicControlExtensionEvent. + * @param {function(GifGraphicControlExtensionEvent): void} listener + * @returns {GifParser} for chaining + */ + onGraphicControlExtension(listener) { + super.addEventListener(GifParseEventType.GRAPHIC_CONTROL_EXTENSION, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifHeaderEvent. + * @param {function(GifHeaderEvent): void} listener + * @returns {GifParser} for chaining + */ + onHeader(listener) { + super.addEventListener(GifParseEventType.HEADER, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifLogicalScreenEvent. + * @param {function(GifLogicalScreenEvent): void} listener + * @returns {GifParser} for chaining + */ + onLogicalScreen(listener) { + super.addEventListener(GifParseEventType.LOGICAL_SCREEN, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifPlainTextExtensionEvent. + * @param {function(GifPlainTextExtensionEvent): void} listener + * @returns {GifParser} for chaining + */ + onPlainTextExtension(listener) { + super.addEventListener(GifParseEventType.PLAIN_TEXT_EXTENSION, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifTableBasedImageEvent. + * @param {function(GifTableBasedImageEvent): void} listener + * @returns {GifParser} for chaining + */ + onTableBasedImage(listener) { + super.addEventListener(GifParseEventType.TABLE_BASED_IMAGE, listener); + return this; + } + + /** + * Type-safe way to bind a listener for a GifTrailerEvent. + * @param {function(GifTrailerEvent): void} listener + * @returns {GifParser} for chaining + */ + onTrailer(listener) { + super.addEventListener(GifParseEventType.TRAILER, listener); + return this; } /** @@ -224,7 +294,7 @@ export class GifParser extends EventTarget { const version = this.version = this.bstream.readString(3); // "87a" or "89a" if (!["87a", "89a"].includes(version)) throw `Bad version: ${version}`; - this.dispatchEvent(new GifHeaderParseEvent( + this.dispatchEvent(new GifHeaderEvent( /** @type {GifHeader} */ ({ version }) )); @@ -253,7 +323,7 @@ export class GifParser extends EventTarget { })); } } - this.dispatchEvent(new GifLogicalScreenParseEvent( + this.dispatchEvent(new GifLogicalScreenEvent( /** @type {GifLogicalScreen} */ ({ logicalScreenWidth, logicalScreenHeight, diff --git a/index.js b/index.js index 3ce5633..a99ba68 100644 --- a/index.js +++ b/index.js @@ -24,7 +24,7 @@ export { export { getFullMIMEString, getShortMIMEString } from './codecs/codecs.js'; export { findMimeType } from './file/sniffer.js'; export { GifApplicationExtensionEvent, GifCommentExtensionEvent, GifGraphicControlExtensionEvent, - GifHeaderParseEvent, GifLogicalScreenParseEvent, GifParseEventType, GifParser, + GifHeaderEvent, GifLogicalScreenEvent, GifParseEventType, GifParser, GifPlainTextExtensionEvent, GifTableBasedImageEvent } from './image/parsers/gif.js'; export { convertWebPtoPNG, convertWebPtoJPG } from './image/webp-shim/webp-shim.js'; export { BitBuffer } from './io/bitbuffer.js'; diff --git a/tests/image-parsers-gif.spec.js b/tests/image-parsers-gif.spec.js index d21ae0b..c0b4f7f 100644 --- a/tests/image-parsers-gif.spec.js +++ b/tests/image-parsers-gif.spec.js @@ -14,18 +14,18 @@ describe('bitjs.image.parsers.GifParser', () => { const parser = new GifParser(ab); let trailerFound = false; let comment; - parser.addEventListener('logical_screen', evt => { + parser.onLogicalScreen(evt => { const {logicalScreenWidth, logicalScreenHeight} = evt.logicalScreen; expect(logicalScreenWidth).equals(32); expect(logicalScreenHeight).equals(52); }); - parser.addEventListener('table_based_image', evt => { + parser.onTableBasedImage(evt => { const {imageWidth, imageHeight} = evt.tableBasedImage; expect(imageWidth).equals(32); expect(imageHeight).equals(52); }); - parser.addEventListener('comment_extension', evt => comment = evt.comment); - parser.addEventListener('trailer', evt => trailerFound = true); + parser.onCommentExtension(evt => comment = evt.comment); + parser.onTrailer(evt => trailerFound = true); await parser.start(); @@ -41,7 +41,7 @@ describe('bitjs.image.parsers.GifParser', () => { let appId; let appAuthCode; let hasAppData = false; - parser.addEventListener('application_extension', evt => { + parser.onApplicationExtension(evt => { appId = evt.applicationExtension.applicationIdentifier appAuthCode = new TextDecoder().decode( evt.applicationExtension.applicationAuthenticationCode);