diff --git a/resources/assets/src/components/mixins/setAsAvatar.js b/resources/assets/src/components/mixins/setAsAvatar.js index 1b13ae05..1979815d 100644 --- a/resources/assets/src/components/mixins/setAsAvatar.js +++ b/resources/assets/src/components/mixins/setAsAvatar.js @@ -21,10 +21,8 @@ export default { if (errno === 0) { toastr.success(msg) - $('[alt="User Image"]').each(function it() { - // eslint-disable-next-line no-invalid-this - $(this).prop('src', `${$(this).attr('src')}?${new Date().getTime()}`) - }) + Array.from(document.querySelectorAll('[alt="User Image"]')) + .forEach(el => (el.src += `?${new Date().getTime()}`)) } else { toastr.warning(msg) } diff --git a/resources/assets/src/components/user/Profile.vue b/resources/assets/src/components/user/Profile.vue index 8ac76afd..84933ab5 100644 --- a/resources/assets/src/components/user/Profile.vue +++ b/resources/assets/src/components/user/Profile.vue @@ -301,10 +301,8 @@ export default { { new_nickname: nickname } ) if (errno === 0) { - $('.nickname').each(function it() { - // eslint-disable-next-line no-invalid-this - $(this).text(nickname) - }) + Array.from(document.querySelectorAll('.nickname')) + .forEach(el => (el.textContent = nickname)) return swal({ type: 'success', text: msg }) } return swal({ type: 'warning', text: msg }) diff --git a/resources/assets/src/js/check-updates.js b/resources/assets/src/js/check-updates.js index c3604ecb..ce03b8bb 100644 --- a/resources/assets/src/js/check-updates.js +++ b/resources/assets/src/js/check-updates.js @@ -1,4 +1,3 @@ -import $ from 'jquery' import { init } from './net' export async function checkForUpdates() { @@ -7,12 +6,11 @@ export async function checkForUpdates() { if (response.ok) { const data = await response.json() if (data.available) { - const dom = ` - - v${data.latest} - ` - - $(`[href="${blessing.base_url}/admin/update"]`).append(dom) + document.querySelector(`[href="${blessing.base_url}/admin/update"]`) + .innerHTML += ` + + v${data.latest} + ` } } } @@ -23,12 +21,11 @@ export async function checkForPluginUpdates() { if (response.ok) { const data = await response.json() if (data.available) { - const dom = ` - - ${data.plugins.length} - ` - - $(`[href="${blessing.base_url}/admin/plugins/market"]`).append(dom) + document.querySelector(`[href="${blessing.base_url}/admin/plugins/market"]`) + .innerHTML += ` + + ${data.plugins.length} + ` } } } diff --git a/resources/assets/src/js/layout.js b/resources/assets/src/js/layout.js index 707e7ab5..74dcfe49 100644 --- a/resources/assets/src/js/layout.js +++ b/resources/assets/src/js/layout.js @@ -18,7 +18,7 @@ Vue.mixin({ }, }) -$(document).ready(() => { +document.addEventListener('loadend', () => { $('input').iCheck({ radioClass: 'iradio_square-blue', checkboxClass: 'icheckbox_square-blue', @@ -26,6 +26,7 @@ $(document).ready(() => { $('[data-toggle="tooltip"]').tooltip() }) + ;(() => { const list = [ { diff --git a/resources/assets/src/js/logout.js b/resources/assets/src/js/logout.js index ea7b8b28..d4be2a2a 100644 --- a/resources/assets/src/js/logout.js +++ b/resources/assets/src/js/logout.js @@ -1,4 +1,3 @@ -import $ from 'jquery' import { post } from './net' import { swal } from './notify' import { trans } from './i18n' @@ -20,4 +19,8 @@ export async function logout() { swal({ type: 'success', text: msg }) } -$('#logout-button').click(logout) +const button = document.querySelector('#logout-button') +/* istanbul ignore next, not all pages contains this button. */ +if (button) { + button.addEventListener('click', logout) +} diff --git a/resources/assets/src/js/notify.js b/resources/assets/src/js/notify.js index 04e3ff38..a4380a0f 100644 --- a/resources/assets/src/js/notify.js +++ b/resources/assets/src/js/notify.js @@ -4,21 +4,6 @@ import Swal from 'sweetalert2' import toastr from 'toastr' import { trans } from './i18n' -/** - * Show message to div#msg with level - * - * @param {string} msg - * @param {string} type - * @return {void} - */ -export function showMsg(msg, type = 'info') { - $('#msg') - .removeClass() - .addClass('callout') - .addClass(`callout-${type}`) - .html(msg) -} - /** * Show modal if error occured when sending an ajax request. * @@ -64,10 +49,11 @@ export function showModal(msg, title = 'Message', type = 'default', options = {} ` - $(dom).on('hidden.bs.modal', /* istanbul ignore next */ function modal() { + $(dom) + .on('hidden.bs.modal', /* istanbul ignore next */ function modal() { // eslint-disable-next-line no-invalid-this - destroyOnClose && $(this).remove() - }) + destroyOnClose && $(this).remove() + }) .modal(options) } @@ -85,4 +71,4 @@ export function swal(options) { window.toastr = toastr window.swal = swal -blessing.notify = { showMsg, showModal } +blessing.notify = { showModal } diff --git a/resources/assets/src/shims.d.ts b/resources/assets/src/shims.d.ts index 563595f4..0a59ff63 100644 --- a/resources/assets/src/shims.d.ts +++ b/resources/assets/src/shims.d.ts @@ -25,7 +25,6 @@ declare global { } notify: { - showMsg(message: string, type?: string): void showModal( message: string, title?: string, diff --git a/resources/assets/tests/components/user/ClosetItem.test.js b/resources/assets/tests/components/user/ClosetItem.test.js index 007190b0..ad9808ca 100644 --- a/resources/assets/tests/components/user/ClosetItem.test.js +++ b/resources/assets/tests/components/user/ClosetItem.test.js @@ -98,19 +98,11 @@ test('set as avatar', async () => { swal .mockResolvedValueOnce({ dismiss: 'cancel' }) .mockResolvedValue({}) - window.$ = jest.fn(() => ({ - each(fn) { - fn() - }, - prop() {}, - attr() { - return '' - }, - })) const wrapper = mount(ClosetItem, { propsData: factory() }) const button = wrapper.findAll('.dropdown-menu > li').at(2) .find('a') + document.body.innerHTML += 'User Image' button.trigger('click') await wrapper.vm.$nextTick() @@ -123,7 +115,7 @@ test('set as avatar', async () => { await flushPromises() await wrapper.vm.$nextTick() expect(Vue.prototype.$http.post).toBeCalledWith('/user/profile/avatar', { tid: 1 }) - expect(window.$).toBeCalledWith('[alt="User Image"]') + expect(document.querySelector('img').src).toMatch(/\d+$/) }) test('no avatar option if texture is cape', () => { diff --git a/resources/assets/tests/components/user/Profile.test.js b/resources/assets/tests/components/user/Profile.test.js index 3bc865e4..535eb166 100644 --- a/resources/assets/tests/components/user/Profile.test.js +++ b/resources/assets/tests/components/user/Profile.test.js @@ -96,14 +96,9 @@ test('change nickname', async () => { swal.mockResolvedValueOnce({}) .mockResolvedValueOnce({ dismiss: 1 }) .mockResolvedValue({}) - window.$ = jest.fn(() => ({ - each(fn) { - fn() - }, - text() {}, - })) const wrapper = mount(Profile) const button = wrapper.find('[data-test=changeNickName]') + document.body.innerHTML += '' button.trigger('click') expect(Vue.prototype.$http.post).not.toBeCalled() @@ -130,6 +125,7 @@ test('change nickname', async () => { button.trigger('click') await flushPromises() expect(swal).toBeCalledWith({ type: 'success', text: 'o' }) + expect(document.querySelector('.nickname').textContent).toBe('nickname') }) test('change email', async () => { diff --git a/resources/assets/tests/js/notify.test.js b/resources/assets/tests/js/notify.test.js index 1b6b5314..e712c10f 100644 --- a/resources/assets/tests/js/notify.test.js +++ b/resources/assets/tests/js/notify.test.js @@ -9,16 +9,6 @@ jest.mock('sweetalert2', () => ({ fire() {}, })) -test('show message', () => { - document.body.innerHTML = '
' - notify.showMsg('hi') - - const element = $('#msg') - expect(element.hasClass('callout')).toBeTrue() - expect(element.hasClass('callout-info')).toBeTrue() - expect(element.html()).toBe('hi') -}) - test('show AJAX error', () => { $.fn.modal = function () { document.body.innerHTML = this.html() diff --git a/resources/views/admin/master.blade.php b/resources/views/admin/master.blade.php index 5c0f0a6a..d7f8a511 100644 --- a/resources/views/admin/master.blade.php +++ b/resources/views/admin/master.blade.php @@ -96,10 +96,10 @@ @include('common.dependencies.script') @yield('script')