diff --git a/framework/core/js/src/common/components/AutocompleteDropdown.tsx b/framework/core/js/src/common/components/AutocompleteDropdown.tsx index 68859dda7d..6ac110d1c9 100644 --- a/framework/core/js/src/common/components/AutocompleteDropdown.tsx +++ b/framework/core/js/src/common/components/AutocompleteDropdown.tsx @@ -102,7 +102,7 @@ export default abstract class AutocompleteDropdown< .onSelect(this.selectSuggestion.bind(this), true) .bindTo(input); - input.addEventListener('focus', function() { + input.addEventListener('focus', function () { component.hasFocus = true; m.redraw(); @@ -174,7 +174,7 @@ export default abstract class AutocompleteDropdown< fixedIndex = 0; } - items.forEach(el => el.classList.remove('active')); + items.forEach((el) => el.classList.remove('active')); const item = items[fixedIndex]; const dropdown = item.parentElement!; item.classList.add('active'); @@ -201,7 +201,7 @@ export default abstract class AutocompleteDropdown< if (typeof scrollTop !== 'undefined') { dropdown.scrollTo({ top: scrollTop, - behavior: 'smooth' + behavior: 'smooth', }); } } diff --git a/framework/core/js/src/common/components/FormModal.tsx b/framework/core/js/src/common/components/FormModal.tsx index 0c09b68ded..6deab2179a 100644 --- a/framework/core/js/src/common/components/FormModal.tsx +++ b/framework/core/js/src/common/components/FormModal.tsx @@ -30,7 +30,7 @@ export default abstract class FormModal input.addEventListener(ev as 'input'| 'focus', function() { - search(this.value.toLowerCase()); - })); + ['input', 'focus'].forEach((ev) => + input.addEventListener(ev as 'input' | 'focus', function () { + search(this.value.toLowerCase()); + }) + ); } onremove(vnode: Mithril.VnodeDOM) { diff --git a/framework/core/js/src/common/components/Tooltip.tsx b/framework/core/js/src/common/components/Tooltip.tsx index 13c0906a2e..49213b33e4 100644 --- a/framework/core/js/src/common/components/Tooltip.tsx +++ b/framework/core/js/src/common/components/Tooltip.tsx @@ -235,7 +235,7 @@ export default class Tooltip extends Component { html, delay: delay || 0, placement: position, - trigger: trigger as any + trigger: trigger as any, }); } diff --git a/framework/core/js/src/common/components/UploadImageButton.tsx b/framework/core/js/src/common/components/UploadImageButton.tsx index e88de6bc28..26708b9946 100644 --- a/framework/core/js/src/common/components/UploadImageButton.tsx +++ b/framework/core/js/src/common/components/UploadImageButton.tsx @@ -73,7 +73,7 @@ export default class UploadImageButton; \ No newline at end of file + }, +} satisfies Modifier; diff --git a/framework/core/js/src/common/utils/scrollEnd.ts b/framework/core/js/src/common/utils/scrollEnd.ts index 959dddfb33..60c1e52ca2 100644 --- a/framework/core/js/src/common/utils/scrollEnd.ts +++ b/framework/core/js/src/common/utils/scrollEnd.ts @@ -1,24 +1,24 @@ /** * A utility function that waits for the scroll to end. * Due to lack of support from some browsers, this is a workaround for `scrollend` event. - * + * * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo#behavior * @see https://caniuse.com/mdn-api_element_scrollend_event * @param container The container element to wait scroll end on. * @returns A promise that resolves when the scroll is ended. */ export default function scrollEnd(container: HTMLElement): Promise { - let lastTop = container.scrollTop; + let lastTop = container.scrollTop; - return new Promise((resolve) => { - const animFrame = () => { - if (lastTop === container.scrollTop) { - resolve(); - } else { - requestAnimationFrame(animFrame); - lastTop = container.scrollTop; - } - }; + return new Promise((resolve) => { + const animFrame = () => { + if (lastTop === container.scrollTop) { + resolve(); + } else { requestAnimationFrame(animFrame); - }); -} \ No newline at end of file + lastTop = container.scrollTop; + } + }; + requestAnimationFrame(animFrame); + }); +} diff --git a/framework/core/js/src/forum/components/AbstractPost.tsx b/framework/core/js/src/forum/components/AbstractPost.tsx index 802b5f0571..aac96e735d 100644 --- a/framework/core/js/src/forum/components/AbstractPost.tsx +++ b/framework/core/js/src/forum/components/AbstractPost.tsx @@ -90,10 +90,9 @@ export default abstract class AbstractPost) { super.onupdate(vnode); - this.element.querySelector('.Post-actions')?.classList.toggle( - 'openWithin', - this.element.querySelector('.Post-controls')?.classList.contains('open') - ); + this.element + .querySelector('.Post-actions') + ?.classList.toggle('openWithin', this.element.querySelector('.Post-controls')?.classList.contains('open')); } elementAttrs(): Record { diff --git a/framework/core/js/src/forum/components/AffixedSidebar.js b/framework/core/js/src/forum/components/AffixedSidebar.js index 3cba6e88ef..16ffc3dcb3 100644 --- a/framework/core/js/src/forum/components/AffixedSidebar.js +++ b/framework/core/js/src/forum/components/AffixedSidebar.js @@ -31,6 +31,7 @@ export default class AffixedSidebar extends Component { } onresize() { + return; const $sidebar = this.$(); const $header = $('#header'); const $footer = $('#footer'); diff --git a/framework/core/js/src/forum/components/CommentPost.js b/framework/core/js/src/forum/components/CommentPost.js index 7e61d3fb20..beac77418d 100644 --- a/framework/core/js/src/forum/components/CommentPost.js +++ b/framework/core/js/src/forum/components/CommentPost.js @@ -87,7 +87,7 @@ export default class CommentPost extends Post { script.textContent = el.textContent; Array.from(el.attributes).forEach((attr) => script.setAttribute(attr.name, attr.value)); this.parentNode.replaceChild(script, el); - }) + }); } this.contentHtml = contentHtml; @@ -193,9 +193,13 @@ export default class CommentPost extends Post { const userCard = this.element.querySelector('.UserCard'); if (!userCard) return; userCard.classList.remove('show'); - userCard.addEventListener('transitionend', () => { - this.cardVisible = false; - m.redraw(); - }, { once: true }); + userCard.addEventListener( + 'transitionend', + () => { + this.cardVisible = false; + m.redraw(); + }, + { once: true } + ); } } diff --git a/framework/core/js/src/forum/components/DiscussionListPane.js b/framework/core/js/src/forum/components/DiscussionListPane.js index d995c84f0e..5e4222c893 100644 --- a/framework/core/js/src/forum/components/DiscussionListPane.js +++ b/framework/core/js/src/forum/components/DiscussionListPane.js @@ -67,8 +67,7 @@ export default class DiscussionListPane extends Component { } onremove(vnode) { - if (vnode.dom) - app.cache.discussionListPaneScrollTop = vnode.dom.scrollTop; + if (vnode.dom) app.cache.discussionListPaneScrollTop = vnode.dom.scrollTop; document.removeEventListener('mousemove', hotEdge); } diff --git a/framework/core/js/src/forum/components/HeaderList.tsx b/framework/core/js/src/forum/components/HeaderList.tsx index 3902f8b8b3..6225966a4f 100644 --- a/framework/core/js/src/forum/components/HeaderList.tsx +++ b/framework/core/js/src/forum/components/HeaderList.tsx @@ -47,7 +47,7 @@ export default class HeaderList scrollTop + indexBottom) { window.scrollTo({ - top: discussionTop - indexTop + top: discussionTop - indexTop, }); } } diff --git a/framework/core/js/src/forum/components/NotificationGrid.js b/framework/core/js/src/forum/components/NotificationGrid.js index ed19435137..39f288e2b4 100644 --- a/framework/core/js/src/forum/components/NotificationGrid.js +++ b/framework/core/js/src/forum/components/NotificationGrid.js @@ -92,16 +92,22 @@ export default class NotificationGrid extends Component { super.oncreate(vnode); this.element.querySelectorAll('thead .NotificationGrid-groupToggle').forEach((toggle) => { - ['mouseenter', 'mouseleave'].forEach((ev) => toggle.addEventListener(ev, function(e) { - const i = parseInt(Array.from(this.parentElement.children).indexOf(this), 10) + 1; - this.closest('table').querySelectorAll('td:nth-child(' + i + ')').forEach((td) => td.classList.toggle('highlighted', e.type === 'mouseenter')); - })); + ['mouseenter', 'mouseleave'].forEach((ev) => + toggle.addEventListener(ev, function (e) { + const i = parseInt(Array.from(this.parentElement.children).indexOf(this), 10) + 1; + this.closest('table') + .querySelectorAll('td:nth-child(' + i + ')') + .forEach((td) => td.classList.toggle('highlighted', e.type === 'mouseenter')); + }) + ); }); this.element.querySelectorAll('tbody .NotificationGrid-groupToggle').forEach((toggle) => { - ['mouseenter', 'mouseleave'].forEach((ev) => toggle.addEventListener(ev, function(e) { - this.parentElement.querySelectorAll('td').forEach((td) => td.classList.toggle('highlighted', e.type === 'mouseenter')); - })); + ['mouseenter', 'mouseleave'].forEach((ev) => + toggle.addEventListener(ev, function (e) { + this.parentElement.querySelectorAll('td').forEach((td) => td.classList.toggle('highlighted', e.type === 'mouseenter')); + }) + ); }); } diff --git a/framework/core/js/src/forum/components/PostStream.js b/framework/core/js/src/forum/components/PostStream.js index c0545a531c..c259bda327 100644 --- a/framework/core/js/src/forum/components/PostStream.js +++ b/framework/core/js/src/forum/components/PostStream.js @@ -347,7 +347,9 @@ export default class PostStream extends Component { * @return {Promise} */ scrollToIndex(index, animate, reply) { - const item = reply ? document.querySelector('.PostStream-item:last-child') : this.element.querySelector(`.PostStream-item[data-index='${index}']`); + const item = reply + ? document.querySelector('.PostStream-item:last-child') + : this.element.querySelector(`.PostStream-item[data-index='${index}']`); this.scrollToItem(item, animate, true, reply); @@ -371,18 +373,18 @@ export default class PostStream extends Component { const index = parseInt(item.getAttribute('data-index')); const itemTopOffset = item.getBoundingClientRect().top + document.documentElement.scrollTop; - const itemTop = itemTopOffset- this.getMarginTop(); - const itemBottom = itemTopOffset + item.clientHeight; - const scrollTop = document.documentElement.scrollTop; - const scrollBottom = scrollTop + window.innerHeight; - - // If the item is already in the viewport, we may not need to scroll. - // If we're scrolling to the reply placeholder, we'll make sure its - // bottom will line up with the top of the composer. - if (force || itemTop < scrollTop || itemBottom > scrollBottom) { - const top = reply ? itemBottom - window.innerHeight + app.composer.computedHeight() : item.parentElement.children[0] == item ? 0 : itemTop; - - document.documentElement.scrollTo({ top, behavior: animate ? 'smooth' : 'instant' }); + const itemTop = itemTopOffset - this.getMarginTop(); + const itemBottom = itemTopOffset + item.clientHeight; + const scrollTop = document.documentElement.scrollTop; + const scrollBottom = scrollTop + window.innerHeight; + + // If the item is already in the viewport, we may not need to scroll. + // If we're scrolling to the reply placeholder, we'll make sure its + // bottom will line up with the top of the composer. + if (force || itemTop < scrollTop || itemBottom > scrollBottom) { + const top = reply ? itemBottom - window.innerHeight + app.composer.computedHeight() : item.parentElement.children[0] == item ? 0 : itemTop; + + document.documentElement.scrollTo({ top, behavior: animate ? 'smooth' : 'instant' }); } const updateScrubberHeight = () => { @@ -411,7 +413,14 @@ export default class PostStream extends Component { let itemRect; if (reply) { const placeholder = document.querySelector('.PostStream-item:last-child'); - window.scrollTo({ top: placeholder.getBoundingClientRect().top + document.documentElement.scrollTop + placeholder.clientHeight - window.innerHeight + app.composer.computedHeight() }); + window.scrollTo({ + top: + placeholder.getBoundingClientRect().top + + document.documentElement.scrollTop + + placeholder.clientHeight - + window.innerHeight + + app.composer.computedHeight(), + }); } else if (index === 0) { window.scrollTo({ top: 0 }); } else if ((itemRect = document.querySelector(`.PostStream-item[data-index='${index}']`))) { diff --git a/framework/core/js/src/forum/components/Search.tsx b/framework/core/js/src/forum/components/Search.tsx index c62a6f8032..d9e7aef83f 100644 --- a/framework/core/js/src/forum/components/Search.tsx +++ b/framework/core/js/src/forum/components/Search.tsx @@ -202,7 +202,7 @@ export default class Search extends Compone searchResults.addEventListener('mousedown', (e) => e.preventDefault()); searchResults.addEventListener('click', () => this.element.querySelector('input')?.blur()); // Whenever the mouse is hovered over a search result, highlight it. - searchResults.addEventListener('mouseenter', function(e) { + searchResults.addEventListener('mouseenter', function (e) { const el = e.target as HTMLElement; if (el.parentElement != searchResults || el.tagName != 'LI' || el.classList.contains('Dropdown-header')) return; search.setIndex(search.selectableItems().indexOf(el as HTMLLIElement)); @@ -219,8 +219,8 @@ export default class Search extends Compone .bindTo(input); // Handle input key events on the search input, triggering results to load. - ['input', 'focus'].forEach(ev => { - input.addEventListener(ev as 'input' | 'focus', function() { + ['input', 'focus'].forEach((ev) => { + input.addEventListener(ev as 'input' | 'focus', function () { const query = this.value.toLowerCase(); if (!query) return; @@ -247,7 +247,7 @@ export default class Search extends Compone }, 250); }); }); - input.addEventListener('focus', function() { + input.addEventListener('focus', function () { this.addEventListener('mouseup', (e) => e.preventDefault(), { once: true }); this.select(); }); @@ -344,7 +344,7 @@ export default class Search extends Compone fixedIndex = 0; } - items.forEach(el => el.classList.remove('active')); + items.forEach((el) => el.classList.remove('active')); const item = items[fixedIndex]; const dropdown = item.parentElement!; item.classList.add('active'); @@ -371,7 +371,7 @@ export default class Search extends Compone if (typeof scrollTop !== 'undefined') { dropdown.scrollTo({ top: scrollTop, - behavior: 'smooth' + behavior: 'smooth', }); } } diff --git a/framework/core/js/src/forum/components/WelcomeHero.tsx b/framework/core/js/src/forum/components/WelcomeHero.tsx index 18d20be465..7f897adc6d 100644 --- a/framework/core/js/src/forum/components/WelcomeHero.tsx +++ b/framework/core/js/src/forum/components/WelcomeHero.tsx @@ -24,15 +24,18 @@ export default class WelcomeHero extends Component { const el = this.element as HTMLElement; el.style.height = el.clientHeight + 'px'; el.style.overflow = 'hidden'; - const anim = el.animate({ - 'height': '0' - }, { - duration: 400 - }); + const anim = el.animate( + { + height: '0', + }, + { + duration: 400, + } + ); anim.addEventListener('finish', () => { el.style.height = '0'; anim.cancel(); - }) + }); anim.addEventListener('finish', this.hide.bind(this)); }; diff --git a/framework/core/js/src/forum/utils/slidable.js b/framework/core/js/src/forum/utils/slidable.js index 44ed601bf1..99a8d662c7 100644 --- a/framework/core/js/src/forum/utils/slidable.js +++ b/framework/core/js/src/forum/utils/slidable.js @@ -34,9 +34,12 @@ export default function slidable(element) { options.duration ||= 200; const content = element.querySelector('.Slidable-content'); - const anim = content.animate({ - 'transform': 'translate(' + newPos + 'px, 0)' - }, options); + const anim = content.animate( + { + transform: 'translate(' + newPos + 'px, 0)', + }, + options + ); anim.addEventListener('finish', () => { content.style.transform = 'translate(' + newPos + 'px, 0)';