diff --git a/assets/js/match_query.js b/assets/js/match_query.js index 618ddcb8..a76d68e4 100644 --- a/assets/js/match_query.js +++ b/assets/js/match_query.js @@ -874,7 +874,4 @@ SearchAST.prototype.dumpTree = function() { return retStrArr.join('\n'); }; -// Force module handling for Jest, can be removed after TypeScript migration -export {}; - export default parseSearch; diff --git a/assets/js/utils/__tests__/draggable.spec.ts b/assets/js/utils/__tests__/draggable.spec.ts index e2786ec1..9c3cd858 100644 --- a/assets/js/utils/__tests__/draggable.spec.ts +++ b/assets/js/utils/__tests__/draggable.spec.ts @@ -269,7 +269,7 @@ describe('Draggable Utilities', () => { initDraggables(); const mockEvent = createDragEvent('dragstart'); - const documentClosestSpy = jest.spyOn(mockDraggable, 'closest').mockReturnValue(null); + const draggableClosestSpy = jest.spyOn(mockDraggable, 'closest').mockReturnValue(null); try { fireEvent(mockDraggable, mockEvent); @@ -277,7 +277,7 @@ describe('Draggable Utilities', () => { expect(mockEvent.dataTransfer?.effectAllowed).toBeFalsy(); } finally { - documentClosestSpy.mockRestore(); + draggableClosestSpy.mockRestore(); } }); }); diff --git a/assets/js/utils/draggable.js b/assets/js/utils/draggable.ts similarity index 51% rename from assets/js/utils/draggable.js rename to assets/js/utils/draggable.ts index 9ac06d9c..f4676dcc 100644 --- a/assets/js/utils/draggable.js +++ b/assets/js/utils/draggable.ts @@ -1,11 +1,13 @@ import { $$ } from './dom'; -let dragSrcEl; +let dragSrcEl: HTMLElement | undefined; -function dragStart(event, target) { +function dragStart(event: DragEvent, target: HTMLElement) { target.classList.add('dragging'); dragSrcEl = target; + if (!event.dataTransfer) return; + if (event.dataTransfer.items.length === 0) { event.dataTransfer.setData('text/plain', ''); } @@ -13,30 +15,34 @@ function dragStart(event, target) { event.dataTransfer.effectAllowed = 'move'; } -function dragOver(event) { +function dragOver(event: DragEvent) { event.preventDefault(); - event.dataTransfer.dropEffect = 'move'; + if (event.dataTransfer) { + event.dataTransfer.dropEffect = 'move'; + } } -function dragEnter(event, target) { +function dragEnter(event: DragEvent, target: HTMLElement) { target.classList.add('over'); } -function dragLeave(event, target) { +function dragLeave(event: DragEvent, target: HTMLElement) { target.classList.remove('over'); } -function drop(event, target) { +function drop(event: DragEvent, target: HTMLElement) { event.preventDefault(); + if (!dragSrcEl) return; + dragSrcEl.classList.remove('dragging'); if (dragSrcEl === target) return; // divide the target element into two sets of coordinates - // and determine how to act based on the relative mouse positioin + // and determine how to act based on the relative mouse position const bbox = target.getBoundingClientRect(); - const detX = bbox.left + (bbox.width / 2); + const detX = bbox.left + bbox.width / 2; if (event.clientX < detX) { target.insertAdjacentElement('beforebegin', dragSrcEl); @@ -46,17 +52,21 @@ function drop(event, target) { } } -function dragEnd(event, target) { - dragSrcEl.classList.remove('dragging'); +function dragEnd(event: DragEvent, target: HTMLElement) { + dragSrcEl?.classList.remove('dragging'); - $$('.over', target.parentNode).forEach(t => t.classList.remove('over')); + if (target.parentNode) { + $$('.over', target.parentNode).forEach(t => t.classList.remove('over')); + } } -function wrapper(func) { - return function(event) { - if (!event.target.closest) return; - const target = event.target.closest('.drag-container [draggable]'); - if (target) func(event, target); +function wrapper(func: (event: E, target: T) => void) { + return function(event: E) { + const evtTarget = event.target as EventTarget | Element | null; + if (evtTarget && 'closest' in evtTarget && typeof evtTarget.closest === 'function') { + const target: T | null = evtTarget.closest('.drag-container [draggable]'); + if (target) func(event, target); + } }; }