1
0
mirror of https://github.com/koloml/furbooru-tagging-assistant.git synced 2025-12-23 23:02:58 +00:00

Merge pull request #101 from koloml/bugfix/detect-and-init-tags-and-tags-form

Fixed custom tags categories not being reapplied to the tags form
This commit is contained in:
2025-02-22 19:26:16 -05:00
committed by GitHub
5 changed files with 87 additions and 4 deletions

View File

@@ -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<HTMLElement>('.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<HTMLElement>('.tag.dropdown')) {
wrapTagDropdown(tagDropdownElement);
}
});
}

View File

@@ -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<HTMLElement>('#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<HTMLElement>('.js-tagsauce')
}
/**
* Collect all the tag categories available on the page and color the tags in the editor according to them.
*/

View File

@@ -0,0 +1,5 @@
export const eventFetchComplete = 'fetchcomplete';
export interface BooruEventsMap {
[eventFetchComplete]: null; // Site sends the response, but extension will not get it due to isolation.
}

View File

@@ -1,12 +1,17 @@
import type { MaintenancePopupEventsMap } from "$lib/components/events/maintenance-popup-events";
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";
interface EventsMapping extends MaintenancePopupEventsMap, FullscreenViewerEventsMap {
}
type EventsMapping =
MaintenancePopupEventsMap
& FullscreenViewerEventsMap
& BooruEventsMap
& TagsFormEventsMap;
type EventCallback<EventDetails> = (event: CustomEvent<EventDetails>) => void;
type UnsubscribeFunction = () => void;
export type UnsubscribeFunction = () => void;
type ResolvableTarget = EventTarget | BaseComponent;
function resolveTarget(componentOrElement: ResolvableTarget): EventTarget {

View File

@@ -0,0 +1,5 @@
export const eventFormEditorUpdated = 'tags-form-updated';
export interface TagsFormEventsMap {
[eventFormEditorUpdated]: HTMLElement;
}