diff --git a/assets/js/tags.js b/assets/js/tags.ts similarity index 65% rename from assets/js/tags.js rename to assets/js/tags.ts index 1a97c196..c3547f27 100644 --- a/assets/js/tags.js +++ b/assets/js/tags.ts @@ -2,23 +2,28 @@ * Tags Dropdown */ -import { showEl, hideEl } from './utils/dom'; +import { $$, showEl, hideEl } from './utils/dom'; +import { assertNotUndefined } from './utils/assert'; +import '../types/ujs'; -function addTag(tagId, list) { +type TagDropdownActionFunction = () => void; +type TagDropdownActionList = Record; + +function addTag(tagId: number, list: number[]) { list.push(tagId); } -function removeTag(tagId, list) { +function removeTag(tagId: number, list: number[]) { list.splice(list.indexOf(tagId), 1); } -function createTagDropdown(tag) { +function createTagDropdown(tag: HTMLSpanElement) { const { userIsSignedIn, userCanEditFilter, watchedTagList, spoileredTagList, hiddenTagList } = window.booru; - const [ unwatch, watch, unspoiler, spoiler, unhide, hide, signIn, filter ] = [].slice.call(tag.querySelectorAll('.tag__dropdown__link')); - const [ unwatched, watched, spoilered, hidden ] = [].slice.call(tag.querySelectorAll('.tag__state')); - const tagId = parseInt(tag.dataset.tagId, 10); + const [ unwatch, watch, unspoiler, spoiler, unhide, hide, signIn, filter ] = $$('.tag__dropdown__link', tag); + const [ unwatched, watched, spoilered, hidden ] = $$('.tag__state', tag); + const tagId = parseInt(assertNotUndefined(tag.dataset.tagId), 10); - const actions = { + const actions: TagDropdownActionList = { unwatch() { hideEl(unwatch, watched); showEl(watch, unwatched); removeTag(tagId, watchedTagList); }, watch() { hideEl(watch, unwatched); showEl(unwatch, watched); addTag(tagId, watchedTagList); }, @@ -51,11 +56,14 @@ function createTagDropdown(tag) { if (userIsSignedIn && !userCanEditFilter) showEl(filter); - tag.addEventListener('fetchcomplete', event => actions[event.target.dataset.tagAction]()); + tag.addEventListener('fetchcomplete', event => { + const act = assertNotUndefined(event.target.dataset.tagAction); + actions[act](); + }); } -function initTagDropdown() { - [].forEach.call(document.querySelectorAll('.tag.dropdown'), createTagDropdown); +export function initTagDropdown() { + for (const tagSpan of $$('.tag.dropdown')) { + createTagDropdown(tagSpan); + } } - -export { initTagDropdown }; diff --git a/lib/philomena_web/templates/tag/_tag.html.slime b/lib/philomena_web/templates/tag/_tag.html.slime index 0de59b7e..9fa32b92 100644 --- a/lib/philomena_web/templates/tag/_tag.html.slime +++ b/lib/philomena_web/templates/tag/_tag.html.slime @@ -1,5 +1,5 @@ span.tag.dropdown data-tag-category="#{@tag.category}" data-tag-id="#{@tag.id}" data-tag-name="#{@tag.name}" data-tag-slug="#{@tag.slug}" - / The order of tag states and dropdown links is important for tags.js + / The order of tag states and dropdown links is important for tags.ts span span.tag__state.hidden title="Unwatched" | +