diff --git a/src/lib/components/TagDropdownWrapper.ts b/src/lib/components/TagDropdownWrapper.ts index 0f3335c..cca7caa 100644 --- a/src/lib/components/TagDropdownWrapper.ts +++ b/src/lib/components/TagDropdownWrapper.ts @@ -3,6 +3,8 @@ import MaintenanceProfile from "$entities/MaintenanceProfile"; import MaintenanceSettings from "$lib/extension/settings/MaintenanceSettings"; import { getComponent } from "$lib/components/base/component-utils"; import CustomCategoriesResolver from "$lib/extension/CustomCategoriesResolver"; +import { on } from "$lib/components/events/comms"; +import { eventFormEditorUpdated } from "$lib/components/events/tags-form-events"; const categoriesResolver = new CustomCategoriesResolver(); @@ -278,5 +280,12 @@ export function watchTagDropdownsInTagsEditor() { for (const tagDropdownElement of closestTagEditor.querySelectorAll('.tag.dropdown')) { wrapTagDropdown(tagDropdownElement); } - }) + }); + + // When form is submitted, its DOM is completely updated. We need to fetch those tags in this case. + on(document.body, eventFormEditorUpdated, event => { + for (const tagDropdownElement of event.detail.querySelectorAll('.tag.dropdown')) { + wrapTagDropdown(tagDropdownElement); + } + }); } diff --git a/src/lib/components/TagsForm.ts b/src/lib/components/TagsForm.ts index 60aa018..ed6681d 100644 --- a/src/lib/components/TagsForm.ts +++ b/src/lib/components/TagsForm.ts @@ -1,7 +1,66 @@ import { BaseComponent } from "$lib/components/base/BaseComponent"; import { getComponent } from "$lib/components/base/component-utils"; +import { emit, on, type UnsubscribeFunction } from "$lib/components/events/comms"; +import { eventFetchComplete } from "$lib/components/events/booru-events"; +import { eventFormEditorUpdated } from "$lib/components/events/tags-form-events"; export class TagsForm extends BaseComponent { + protected init() { + // Site sending the event when form is submitted vie Fetch API. We use this event to reload our logic here. + const unsubscribe = on( + this.container, + eventFetchComplete, + () => this.#waitAndDetectUpdatedForm(unsubscribe), + ); + } + + #waitAndDetectUpdatedForm(unsubscribe: UnsubscribeFunction): void { + const elementContainingTagEditor = this.container + .closest('#image_tags_and_source') + ?.parentElement; + + if (!elementContainingTagEditor) { + return; + } + + const observer = new MutationObserver(() => { + const tagsFormElement = elementContainingTagEditor.querySelector('#tags-form'); + + if (!tagsFormElement || getComponent(tagsFormElement)) { + return; + } + + const tagFormComponent = new TagsForm(tagsFormElement); + tagFormComponent.initialize(); + + const fullTagEditor = tagFormComponent.parentTagEditorElement; + + if (fullTagEditor) { + emit(document.body, eventFormEditorUpdated, fullTagEditor); + } else { + console.info('Tag form is not in the tag editor. Event is not sent.'); + } + + observer.disconnect(); + unsubscribe(); + }); + + observer.observe(elementContainingTagEditor, { + subtree: true, + childList: true, + }); + + // Make sure to forcibly disconnect everything after a while. + setTimeout(() => { + observer.disconnect(); + unsubscribe(); + }, 5000); + } + + get parentTagEditorElement(): HTMLElement | null { + return this.container.closest('.js-tagsauce') + } + /** * Collect all the tag categories available on the page and color the tags in the editor according to them. */ diff --git a/src/lib/components/events/comms.ts b/src/lib/components/events/comms.ts index 359e78d..3624491 100644 --- a/src/lib/components/events/comms.ts +++ b/src/lib/components/events/comms.ts @@ -2,11 +2,13 @@ import type { MaintenancePopupEventsMap } from "$lib/components/events/maintenan import { BaseComponent } from "$lib/components/base/BaseComponent"; import type { FullscreenViewerEventsMap } from "$lib/components/events/fullscreen-viewer-events"; import type { BooruEventsMap } from "$lib/components/events/booru-events"; +import type { TagsFormEventsMap } from "$lib/components/events/tags-form-events"; type EventsMapping = MaintenancePopupEventsMap & FullscreenViewerEventsMap - & BooruEventsMap; + & BooruEventsMap + & TagsFormEventsMap; type EventCallback = (event: CustomEvent) => void; export type UnsubscribeFunction = () => void; diff --git a/src/lib/components/events/tags-form-events.ts b/src/lib/components/events/tags-form-events.ts new file mode 100644 index 0000000..64461dc --- /dev/null +++ b/src/lib/components/events/tags-form-events.ts @@ -0,0 +1,5 @@ +export const eventFormEditorUpdated = 'tags-form-updated'; + +export interface TagsFormEventsMap { + [eventFormEditorUpdated]: HTMLElement; +}