diff --git a/src/lib/booru/scraped/ScrapedAPI.js b/src/lib/booru/scraped/ScrapedAPI.ts similarity index 69% rename from src/lib/booru/scraped/ScrapedAPI.js rename to src/lib/booru/scraped/ScrapedAPI.ts index f880eb8..7bcb929 100644 --- a/src/lib/booru/scraped/ScrapedAPI.js +++ b/src/lib/booru/scraped/ScrapedAPI.ts @@ -1,19 +1,25 @@ import PostParser from "$lib/booru/scraped/parsing/PostParser"; +type UpdaterFunction = (tags: Set) => Set; + export default class ScrapedAPI { /** * Update the tags of the image using callback. - * @param {number} imageId ID of the image. - * @param {function(Set): Set} callback Callback to call to change the content. - * @return {Promise|null>} Updated tags and aliases list for updating internal cached state. + * @param imageId ID of the image. + * @param callback Callback to call to change the content. + * @return Updated tags and aliases list for updating internal cached state. */ - async updateImageTags(imageId, callback) { + async updateImageTags(imageId: number, callback: UpdaterFunction): Promise | null> { const postParser = new PostParser(imageId); const formData = await postParser.resolveTagEditorFormData(); + const tagsFieldValue = formData.get(PostParser.tagsInputName); + + if (typeof tagsFieldValue !== 'string') { + throw new Error('Missing tags field!'); + } const tagsList = new Set( - formData - .get(PostParser.tagsInputName) + tagsFieldValue .split(',') .map(tagName => tagName.trim()) ); diff --git a/src/lib/booru/scraped/parsing/PageParser.js b/src/lib/booru/scraped/parsing/PageParser.ts similarity index 57% rename from src/lib/booru/scraped/parsing/PageParser.js rename to src/lib/booru/scraped/parsing/PageParser.ts index 8078f75..49cd9f1 100644 --- a/src/lib/booru/scraped/parsing/PageParser.js +++ b/src/lib/booru/scraped/parsing/PageParser.ts @@ -1,17 +1,12 @@ export default class PageParser { - /** @type {string} */ - #url; - /** @type {DocumentFragment|null} */ - #fragment = null; + readonly #url: string; + #fragment: DocumentFragment | null = null; - constructor(url) { + constructor(url: string) { this.#url = url; } - /** - * @return {Promise} - */ - async resolveFragment() { + async resolveFragment(): Promise { if (this.#fragment) { return this.#fragment; } @@ -34,12 +29,12 @@ export default class PageParser { /** * Create a document fragment from the following response. * - * @param {Response} response Response to create a fragment from. Note, that this response will be used. If you need - * to use the same response somewhere else, then you need to pass a cloned version of the response. + * @param response Response to create a fragment from. Note, that this response will be used. If you need to use the + * same response somewhere else, then you need to pass a cloned version of the response. * - * @return {Promise} Resulting document fragment ready for processing. + * @return Resulting document fragment ready for processing. */ - static async resolveFragmentFromResponse(response) { + static async resolveFragmentFromResponse(response: Response): Promise { const documentFragment = document.createDocumentFragment(); const template = document.createElement('template'); template.innerHTML = await response.text(); diff --git a/src/lib/booru/scraped/parsing/PostParser.js b/src/lib/booru/scraped/parsing/PostParser.ts similarity index 53% rename from src/lib/booru/scraped/parsing/PostParser.js rename to src/lib/booru/scraped/parsing/PostParser.ts index af6d104..43704b8 100644 --- a/src/lib/booru/scraped/parsing/PostParser.js +++ b/src/lib/booru/scraped/parsing/PostParser.ts @@ -2,23 +2,19 @@ import PageParser from "$lib/booru/scraped/parsing/PageParser"; import { buildTagsAndAliasesMap } from "$lib/booru/tag-utils"; export default class PostParser extends PageParser { - /** @type {HTMLFormElement} */ - #tagEditorForm; + #tagEditorForm: HTMLFormElement | null = null; - constructor(imageId) { + constructor(imageId: number) { super(`/images/${imageId}`); } - /** - * @return {Promise} - */ - async resolveTagEditorForm() { + async resolveTagEditorForm(): Promise { if (this.#tagEditorForm) { return this.#tagEditorForm; } const documentFragment = await this.resolveFragment(); - const tagsFormElement = documentFragment.querySelector("#tags-form"); + const tagsFormElement = documentFragment.querySelector("#tags-form"); if (!tagsFormElement) { throw new Error("Failed to find the tag editor form"); @@ -37,10 +33,8 @@ export default class PostParser extends PageParser { /** * Resolve the tags and aliases mapping from the post page. - * - * @return {Promise|null>} */ - async resolveTagsAndAliases() { + async resolveTagsAndAliases(): Promise | null> { return PostParser.resolveTagsAndAliasesFromPost( await this.resolveFragment() ); @@ -49,25 +43,32 @@ export default class PostParser extends PageParser { /** * Resolve the list of tags and aliases from the post content. * - * @param {DocumentFragment} documentFragment Real content to parse the data from. + * @param documentFragment Real content to parse the data from. * - * @return {Map|null} Tags and aliases or null if failed to parse. + * @return Tags and aliases or null if failed to parse. */ - static resolveTagsAndAliasesFromPost(documentFragment) { - const imageShowContainer = documentFragment.querySelector('.image-show-container'); - const tagsForm = documentFragment.querySelector('#tags-form'); + static resolveTagsAndAliasesFromPost(documentFragment: DocumentFragment): Map | null { + const imageShowContainer = documentFragment.querySelector('.image-show-container'); + const tagsForm = documentFragment.querySelector('#tags-form'); if (!imageShowContainer || !tagsForm) { return null; } const tagsFormData = new FormData(tagsForm); + const tagsAndAliasesValue = imageShowContainer.dataset.imageTagAliases; + const tagsValue = tagsFormData.get(this.tagsInputName); - const tagsAndAliasesList = imageShowContainer.dataset.imageTagAliases + if (!tagsAndAliasesValue || !tagsValue || typeof tagsValue !== 'string') { + console.warn('Failed to locate tags & aliases!'); + return null; + } + + const tagsAndAliasesList = tagsAndAliasesValue .split(',') .map(tagName => tagName.trim()); - const actualTagsList = tagsFormData.get(this.tagsInputName) + const actualTagsList = tagsValue .split(',') .map(tagName => tagName.trim());