diff --git a/extensions/embed/js/src/forum/index.js b/extensions/embed/js/src/forum/index.js
index f858688120..75a6290897 100644
--- a/extensions/embed/js/src/forum/index.js
+++ b/extensions/embed/js/src/forum/index.js
@@ -36,7 +36,7 @@ app.pageInfo = Stream({});
const reposition = function () {
const info = app.pageInfo();
- this.$().css('top', Math.max(0, info.scrollTop - info.offsetTop));
+ this.element.style.top = Math.max(0, info.scrollTop - info.offsetTop) + 'px';
};
extend(ModalManager.prototype, 'show', reposition);
@@ -50,7 +50,7 @@ window.iFrameResizer = {
extend('flarum/forum/components/PostStream', 'goToNumber', function (promise, number) {
if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {
- const itemTop = this.$('.PostStream-item:last').offset().top;
+ const itemTop = this.element.getBoundingClientRect().top + document.documentElement.scrollTop;
window.parentIFrame.scrollToOffset(0, itemTop);
}
});
diff --git a/extensions/emoji/js/src/forum/addComposerAutocomplete.js b/extensions/emoji/js/src/forum/addComposerAutocomplete.js
index 7d6df93903..120341bd74 100644
--- a/extensions/emoji/js/src/forum/addComposerAutocomplete.js
+++ b/extensions/emoji/js/src/forum/addComposerAutocomplete.js
@@ -24,7 +24,8 @@ export default function addComposerAutocomplete() {
extend('flarum/common/components/TextEditor', 'onbuild', function () {
this.emojiDropdown = new AutocompleteDropdown();
- const $editor = this.$('.TextEditor-editor').wrap('
');
+ const editor = this.element.querySelector('.TextEditor-editor');
+ editor.outerHTML = `${editor.outerHTML}
`;
this.navigator = new KeyboardNavigatable();
this.navigator
@@ -33,9 +34,9 @@ export default function addComposerAutocomplete() {
.onDown(() => this.emojiDropdown.navigate(1))
.onSelect(this.emojiDropdown.complete.bind(this.emojiDropdown))
.onCancel(this.emojiDropdown.hide.bind(this.emojiDropdown))
- .bindTo($editor);
+ .bindTo(editor);
- $editor.after($(''));
+ editor.outerHTML = editor.outerHTML + '';
});
extend('flarum/common/components/TextEditor', 'buildEditorParams', function (params) {
@@ -134,27 +135,28 @@ export default function addComposerAutocomplete() {
if (suggestions.length) {
this.emojiDropdown.items = suggestions;
- m.render(this.$('.ComposerBody-emojiDropdownContainer')[0], this.emojiDropdown.render());
+ m.render(this.element.querySelector('.ComposerBody-emojiDropdownContainer'), this.emojiDropdown.render());
this.emojiDropdown.show();
const coordinates = this.attrs.composer.editor.getCaretCoordinates(autocompleting.absoluteStart);
- const width = this.emojiDropdown.$().outerWidth();
- const height = this.emojiDropdown.$().outerHeight();
- const parent = this.emojiDropdown.$().offsetParent();
+ const rect = this.emojiDropdown.element.getBoundingClientRect();
+ const width = rect.width;
+ const height = rect.height;
+ const parent = this.emojiDropdown.element.offsetParent;
let left = coordinates.left;
let top = coordinates.top + 15;
// Keep the dropdown inside the editor.
- if (top + height > parent.height()) {
+ if (top + height > parent.clientHeight) {
top = coordinates.top - height - 15;
}
- if (left + width > parent.width()) {
- left = parent.width() - width;
+ if (left + width > parent.clientWidth) {
+ left = parent.clientWidth - width;
}
// Prevent the dropdown from going off screen on mobile
- top = Math.max(-(parent.offset().top - $(document).scrollTop()), top);
- left = Math.max(-parent.offset().left, left);
+ top = Math.max(-(parent.getBoundingClientRect().top), top);
+ left = Math.max(-parent.getBoundingClientRect().left + document.documentElement.scrollLeft, left);
this.emojiDropdown.show(left, top);
}
@@ -163,7 +165,7 @@ export default function addComposerAutocomplete() {
buildSuggestions();
this.emojiDropdown.setIndex(0);
- this.emojiDropdown.$().scrollTop(0);
+ this.emojiDropdown.element.scrollTo({ top: 0 });
this.emojiDropdown.active = true;
}
});
diff --git a/extensions/emoji/js/src/forum/fragments/AutocompleteDropdown.js b/extensions/emoji/js/src/forum/fragments/AutocompleteDropdown.js
index e4f27921e3..086b56821d 100644
--- a/extensions/emoji/js/src/forum/fragments/AutocompleteDropdown.js
+++ b/extensions/emoji/js/src/forum/fragments/AutocompleteDropdown.js
@@ -18,17 +18,15 @@ export default class AutocompleteDropdown extends Fragment {
}
show(left, top) {
- this.$()
- .show()
- .css({
- left: left + 'px',
- top: top + 'px',
- });
+ const style = this.element.style;
+ style.display = 'block';
+ style.left = left + 'px';
+ style.top = top + 'px';
this.active = true;
}
hide() {
- this.$().hide();
+ this.element.style.display = 'none';
this.active = false;
}
@@ -40,42 +38,51 @@ export default class AutocompleteDropdown extends Fragment {
}
complete() {
- this.$('li:not(.Dropdown-header)').eq(this.index).find('button').click();
+ this.element.querySelectorAll('li:not(.Dropdown-header)')[this.index].querySelector('button').click();
}
+ // todo: check if copied implementation matches the original behavior
setIndex(index, scrollToItem) {
if (this.keyWasJustPressed && !scrollToItem) return;
- const $dropdown = this.$();
- const $items = $dropdown.find('li:not(.Dropdown-header)');
+ const dropdown = this.element;
+ const items = dropdown.querySelectorAll('li:not(.Dropdown-header)');
let rangedIndex = index;
if (rangedIndex < 0) {
- rangedIndex = $items.length - 1;
- } else if (rangedIndex >= $items.length) {
+ rangedIndex = items.length - 1;
+ } else if (rangedIndex >= items.length) {
rangedIndex = 0;
}
this.index = rangedIndex;
- const $item = $items.removeClass('active').eq(rangedIndex).addClass('active');
+ items.forEach((el) => el.classList.remove('active'));
+ const item = items[rangedIndex];
+ item.classList.add('active');
if (scrollToItem) {
- const dropdownScroll = $dropdown.scrollTop();
- const dropdownTop = $dropdown.offset().top;
- const dropdownBottom = dropdownTop + $dropdown.outerHeight();
- const itemTop = $item.offset().top;
- const itemBottom = itemTop + $item.outerHeight();
+ const documentScrollTop = document.documentElement.scrollTop;
+ const dropdownScroll = dropdown.scrollTop;
+ const dropdownRect = dropdown.getBoundingClientRect();
+ const dropdownTop = dropdownRect.top + documentScrollTop;
+ const dropdownBottom = dropdownTop + dropdownRect.height;
+ const itemRect = item.getBoundingClientRect();
+ const itemTop = itemRect.top + documentScrollTop;
+ const itemBottom = itemTop + itemRect.height;
let scrollTop;
if (itemTop < dropdownTop) {
- scrollTop = dropdownScroll - dropdownTop + itemTop - parseInt($dropdown.css('padding-top'), 10);
+ scrollTop = dropdownScroll - dropdownTop + itemTop - parseInt(getComputedStyle(dropdown).paddingTop, 10);
} else if (itemBottom > dropdownBottom) {
- scrollTop = dropdownScroll - dropdownBottom + itemBottom + parseInt($dropdown.css('padding-bottom'), 10);
+ scrollTop = dropdownScroll - dropdownBottom + itemBottom + parseInt(getComputedStyle(dropdown).paddingBottom, 10);
}
if (typeof scrollTop !== 'undefined') {
- $dropdown.stop(true).animate({ scrollTop }, 100);
+ dropdown.scrollTo({
+ top: scrollTop,
+ behavior: 'smooth',
+ });
}
}
}