mirror of
https://github.com/koloml/furbooru-tagging-assistant.git
synced 2026-03-24 23:02:58 +00:00
Merge pull request #159 from koloml/feature/support-replacing-tag-link-texts
Tag Links: Support replaceting text of links to the decoded tag name
This commit is contained in:
@@ -8,6 +8,7 @@ export class BlockCommunication extends BaseComponent {
|
||||
#tagLinks: HTMLAnchorElement[] = [];
|
||||
|
||||
#tagLinksReplaced: boolean | null = null;
|
||||
#linkTextReplaced: boolean | null = null;
|
||||
|
||||
protected build() {
|
||||
this.#contentSection = this.container.querySelector('.communication__content');
|
||||
@@ -15,14 +16,30 @@ export class BlockCommunication extends BaseComponent {
|
||||
}
|
||||
|
||||
protected init() {
|
||||
BlockCommunication.#tagSettings.resolveReplaceLinks().then(this.#onReplaceLinkSettingResolved.bind(this));
|
||||
Promise.all([
|
||||
BlockCommunication.#tagSettings.resolveReplaceLinks(),
|
||||
BlockCommunication.#tagSettings.resolveReplaceLinkText(),
|
||||
]).then(([replaceLinks, replaceLinkText]) => {
|
||||
this.#onReplaceLinkSettingResolved(
|
||||
replaceLinks,
|
||||
replaceLinkText
|
||||
);
|
||||
});
|
||||
|
||||
BlockCommunication.#tagSettings.subscribe(settings => {
|
||||
this.#onReplaceLinkSettingResolved(settings.replaceLinks ?? false);
|
||||
this.#onReplaceLinkSettingResolved(
|
||||
settings.replaceLinks ?? false,
|
||||
settings.replaceLinkText ?? true
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#onReplaceLinkSettingResolved(haveToReplaceLinks: boolean) {
|
||||
if (!this.#tagLinks.length || this.#tagLinksReplaced === haveToReplaceLinks) {
|
||||
#onReplaceLinkSettingResolved(haveToReplaceLinks: boolean, shouldReplaceLinkText: boolean) {
|
||||
if (
|
||||
!this.#tagLinks.length
|
||||
|| this.#tagLinksReplaced === haveToReplaceLinks
|
||||
&& this.#linkTextReplaced === shouldReplaceLinkText
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -34,15 +51,52 @@ export class BlockCommunication extends BaseComponent {
|
||||
linkElement.textContent = linkElement.children[0].textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolved tag name. It should be stored for the text replacement.
|
||||
*/
|
||||
let tagName: string | undefined;
|
||||
|
||||
if (haveToReplaceLinks) {
|
||||
const tagName = resolveTagNameFromLink(new URL(linkElement.href)) ?? '';
|
||||
tagName = resolveTagNameFromLink(new URL(linkElement.href)) ?? '';
|
||||
linkElement.dataset.tagCategory = resolveTagCategoryFromTagName(tagName) ?? '';
|
||||
} else {
|
||||
linkElement.dataset.tagCategory = '';
|
||||
}
|
||||
|
||||
this.#toggleTagLinkText(
|
||||
linkElement,
|
||||
haveToReplaceLinks && shouldReplaceLinkText,
|
||||
tagName,
|
||||
);
|
||||
}
|
||||
|
||||
this.#tagLinksReplaced = haveToReplaceLinks;
|
||||
this.#linkTextReplaced = shouldReplaceLinkText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the link text with the tag name or restore it back to original content. This function will only perform
|
||||
* replacement on links without any additional tags inside. This will ensure link won't break original content.
|
||||
* @param linkElement Element to swap the text on.
|
||||
* @param shouldSwapToTagName Should we swap the text to tag name or retore it back from memory.
|
||||
* @param tagName Tag name to swap the text to. If not provided, text will be swapped back.
|
||||
* @private
|
||||
*/
|
||||
#toggleTagLinkText(linkElement: HTMLElement, shouldSwapToTagName: boolean, tagName?: string) {
|
||||
if (linkElement.childElementCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we save the original text to memory.
|
||||
if (!BlockCommunication.#originalTagLinkTexts.has(linkElement)) {
|
||||
BlockCommunication.#originalTagLinkTexts.set(linkElement, linkElement.textContent);
|
||||
}
|
||||
|
||||
if (shouldSwapToTagName && tagName) {
|
||||
linkElement.textContent = tagName;
|
||||
} else {
|
||||
linkElement.textContent = BlockCommunication.#originalTagLinkTexts.get(linkElement) ?? linkElement.textContent;
|
||||
}
|
||||
}
|
||||
|
||||
#findAllTagLinks(): HTMLAnchorElement[] {
|
||||
@@ -60,6 +114,13 @@ export class BlockCommunication extends BaseComponent {
|
||||
|
||||
static #tagSettings = new TagSettings();
|
||||
|
||||
/**
|
||||
* Map of links to their original texts. These texts need to be stored here to make them restorable. Keys is a link
|
||||
* element and value is a text.
|
||||
* @private
|
||||
*/
|
||||
static #originalTagLinkTexts: WeakMap<HTMLElement, string> = new WeakMap();
|
||||
|
||||
static findAndInitializeAll() {
|
||||
for (const container of document.querySelectorAll<HTMLElement>('.block.communication')) {
|
||||
if (getComponent(container)) {
|
||||
|
||||
@@ -102,7 +102,8 @@ export function resolveTagNameFromLink(tagLink: URL): string | null {
|
||||
|
||||
return decodeURIComponent(encodedTagName)
|
||||
.replaceAll(/-[a-z]+-/gi, match => slugEncodedCharacters.get(match) ?? match)
|
||||
.replaceAll('-', ' ');
|
||||
.replaceAll('-', ' ')
|
||||
.replaceAll('+', ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,6 +3,7 @@ import CacheableSettings from "$lib/extension/base/CacheableSettings";
|
||||
interface TagSettingsFields {
|
||||
groupSeparation: boolean;
|
||||
replaceLinks: boolean;
|
||||
replaceLinkText: boolean;
|
||||
}
|
||||
|
||||
export default class TagSettings extends CacheableSettings<TagSettingsFields> {
|
||||
@@ -18,6 +19,10 @@ export default class TagSettings extends CacheableSettings<TagSettingsFields> {
|
||||
return this._resolveSetting("replaceLinks", false);
|
||||
}
|
||||
|
||||
async resolveReplaceLinkText() {
|
||||
return this._resolveSetting("replaceLinkText", true);
|
||||
}
|
||||
|
||||
async setGroupSeparation(value: boolean) {
|
||||
return this._writeSetting("groupSeparation", Boolean(value));
|
||||
}
|
||||
@@ -25,4 +30,8 @@ export default class TagSettings extends CacheableSettings<TagSettingsFields> {
|
||||
async setReplaceLinks(value: boolean) {
|
||||
return this._writeSetting("replaceLinks", Boolean(value));
|
||||
}
|
||||
|
||||
async setReplaceLinkText(value: boolean) {
|
||||
return this._writeSetting("replaceLinkText", Boolean(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
import Menu from "$components/ui/menu/Menu.svelte";
|
||||
import MenuItem from "$components/ui/menu/MenuItem.svelte";
|
||||
import { stripBlacklistedTagsEnabled } from "$stores/preferences/maintenance";
|
||||
import { shouldReplaceLinksOnForumPosts, shouldSeparateTagGroups } from "$stores/preferences/tag";
|
||||
import {
|
||||
shouldReplaceLinksOnForumPosts,
|
||||
shouldReplaceTextOfTagLinks,
|
||||
shouldSeparateTagGroups
|
||||
} from "$stores/preferences/tag";
|
||||
import { popupTitle } from "$stores/popup";
|
||||
|
||||
$popupTitle = 'Tagging Preferences';
|
||||
@@ -31,4 +35,11 @@
|
||||
Find and replace links to the tags in the forum posts
|
||||
</CheckboxField>
|
||||
</FormControl>
|
||||
{#if $shouldReplaceLinksOnForumPosts}
|
||||
<FormControl>
|
||||
<CheckboxField bind:checked={$shouldReplaceTextOfTagLinks}>
|
||||
Try to replace text on links pointing to tags in forum posts
|
||||
</CheckboxField>
|
||||
</FormControl>
|
||||
{/if}
|
||||
</FormContainer>
|
||||
|
||||
@@ -5,11 +5,13 @@ const tagSettings = new TagSettings();
|
||||
|
||||
export const shouldSeparateTagGroups = writable(false);
|
||||
export const shouldReplaceLinksOnForumPosts = writable(false);
|
||||
export const shouldReplaceTextOfTagLinks = writable(true);
|
||||
|
||||
Promise
|
||||
.allSettled([
|
||||
tagSettings.resolveGroupSeparation().then(value => shouldSeparateTagGroups.set(value)),
|
||||
tagSettings.resolveReplaceLinks().then(value => shouldReplaceLinksOnForumPosts.set(value)),
|
||||
tagSettings.resolveReplaceLinkText().then(value => shouldReplaceTextOfTagLinks.set(value)),
|
||||
])
|
||||
.then(() => {
|
||||
shouldSeparateTagGroups.subscribe(value => {
|
||||
@@ -20,8 +22,13 @@ Promise
|
||||
void tagSettings.setReplaceLinks(value);
|
||||
});
|
||||
|
||||
shouldReplaceTextOfTagLinks.subscribe(value => {
|
||||
void tagSettings.setReplaceLinkText(value);
|
||||
});
|
||||
|
||||
tagSettings.subscribe(settings => {
|
||||
shouldSeparateTagGroups.set(Boolean(settings.groupSeparation));
|
||||
shouldReplaceLinksOnForumPosts.set(Boolean(settings.replaceLinks));
|
||||
shouldReplaceTextOfTagLinks.set(Boolean(settings.replaceLinkText));
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user