From 3863be18301cec9fec480db7fe28a19439c708d2 Mon Sep 17 00:00:00 2001 From: Ronin0000 <89286474+Ronin0000@users.noreply.github.com> Date: Mon, 22 Nov 2021 09:06:52 -0800 Subject: [PATCH] Delete apps/schoolCalendar/fullcalendar/interaction/src directory --- .../interaction/src/ElementScrollGeomCache.ts | 16 - .../interaction/src/OffsetTracker.ts | 76 --- .../interaction/src/ScrollGeomCache.ts | 107 ---- .../interaction/src/WindowScrollGeomCache.ts | 27 - .../interaction/src/api-type-deps.ts | 6 - .../interaction/src/dnd/AutoScroller.ts | 217 -------- .../interaction/src/dnd/ElementMirror.ts | 146 ------ .../src/dnd/FeaturefulElementDragging.ts | 213 -------- .../interaction/src/dnd/PointerDragging.ts | 344 ------------- .../ExternalDraggable.ts | 70 --- .../ExternalElementDragging.ts | 268 ---------- .../InferredElementDragging.ts | 77 --- .../ThirdPartyDraggable.ts | 52 -- .../src/interactions/DateClicking.ts | 71 --- .../src/interactions/DateSelecting.ts | 152 ------ .../src/interactions/EventDragging.ts | 482 ------------------ .../src/interactions/EventResizing.ts | 263 ---------- .../src/interactions/HitDragging.ts | 220 -------- .../src/interactions/UnselectAuto.ts | 77 --- .../interaction/src/main.global.ts | 7 - .../fullcalendar/interaction/src/main.ts | 23 - .../interaction/src/options-declare.ts | 9 - .../fullcalendar/interaction/src/options.ts | 26 - .../fullcalendar/interaction/src/utils.ts | 38 -- 24 files changed, 2987 deletions(-) delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/ElementScrollGeomCache.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/OffsetTracker.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/ScrollGeomCache.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/WindowScrollGeomCache.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/api-type-deps.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/dnd/AutoScroller.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/dnd/ElementMirror.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/dnd/FeaturefulElementDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/dnd/PointerDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalDraggable.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalElementDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/InferredElementDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ThirdPartyDraggable.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateClicking.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateSelecting.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventResizing.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/HitDragging.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/interactions/UnselectAuto.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/main.global.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/main.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/options-declare.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/options.ts delete mode 100644 apps/schoolCalendar/fullcalendar/interaction/src/utils.ts diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/ElementScrollGeomCache.ts b/apps/schoolCalendar/fullcalendar/interaction/src/ElementScrollGeomCache.ts deleted file mode 100644 index 83be540cd..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/ElementScrollGeomCache.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { computeInnerRect, ElementScrollController } from '@fullcalendar/common' -import { ScrollGeomCache } from './ScrollGeomCache' - -export class ElementScrollGeomCache extends ScrollGeomCache { - constructor(el: HTMLElement, doesListening: boolean) { - super(new ElementScrollController(el), doesListening) - } - - getEventTarget(): EventTarget { - return (this.scrollController as ElementScrollController).el - } - - computeClientRect() { - return computeInnerRect((this.scrollController as ElementScrollController).el) - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/OffsetTracker.ts b/apps/schoolCalendar/fullcalendar/interaction/src/OffsetTracker.ts deleted file mode 100644 index b1fac23e6..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/OffsetTracker.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - getClippingParents, computeRect, - pointInsideRect, Rect, -} from '@fullcalendar/common' -import { ElementScrollGeomCache } from './ElementScrollGeomCache' - -/* -When this class is instantiated, it records the offset of an element (relative to the document topleft), -and continues to monitor scrolling, updating the cached coordinates if it needs to. -Does not access the DOM after instantiation, so highly performant. - -Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element -and an determine if a given point is inside the combined clipping rectangle. -*/ -export class OffsetTracker { // ElementOffsetTracker - scrollCaches: ElementScrollGeomCache[] - origRect: Rect - - constructor(el: HTMLElement) { - this.origRect = computeRect(el) - - // will work fine for divs that have overflow:hidden - this.scrollCaches = getClippingParents(el).map( - (scrollEl) => new ElementScrollGeomCache(scrollEl, true), // listen=true - ) - } - - destroy() { - for (let scrollCache of this.scrollCaches) { - scrollCache.destroy() - } - } - - computeLeft() { - let left = this.origRect.left - - for (let scrollCache of this.scrollCaches) { - left += scrollCache.origScrollLeft - scrollCache.getScrollLeft() - } - - return left - } - - computeTop() { - let top = this.origRect.top - - for (let scrollCache of this.scrollCaches) { - top += scrollCache.origScrollTop - scrollCache.getScrollTop() - } - - return top - } - - isWithinClipping(pageX: number, pageY: number): boolean { - let point = { left: pageX, top: pageY } - - for (let scrollCache of this.scrollCaches) { - if ( - !isIgnoredClipping(scrollCache.getEventTarget()) && - !pointInsideRect(point, scrollCache.clientRect) - ) { - return false - } - } - - return true - } -} - -// certain clipping containers should never constrain interactions, like and -// https://github.com/fullcalendar/fullcalendar/issues/3615 -function isIgnoredClipping(node: EventTarget) { - let tagName = (node as HTMLElement).tagName - - return tagName === 'HTML' || tagName === 'BODY' -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/ScrollGeomCache.ts b/apps/schoolCalendar/fullcalendar/interaction/src/ScrollGeomCache.ts deleted file mode 100644 index 63ec6a5e1..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/ScrollGeomCache.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Rect, ScrollController } from '@fullcalendar/common' - -/* -Is a cache for a given element's scroll information (all the info that ScrollController stores) -in addition the "client rectangle" of the element.. the area within the scrollbars. - -The cache can be in one of two modes: -- doesListening:false - ignores when the container is scrolled by someone else -- doesListening:true - watch for scrolling and update the cache -*/ -export abstract class ScrollGeomCache extends ScrollController { - clientRect: Rect - origScrollTop: number - origScrollLeft: number - - protected scrollController: ScrollController - protected doesListening: boolean - protected scrollTop: number - protected scrollLeft: number - protected scrollWidth: number - protected scrollHeight: number - protected clientWidth: number - protected clientHeight: number - - constructor(scrollController: ScrollController, doesListening: boolean) { - super() - this.scrollController = scrollController - this.doesListening = doesListening - this.scrollTop = this.origScrollTop = scrollController.getScrollTop() - this.scrollLeft = this.origScrollLeft = scrollController.getScrollLeft() - this.scrollWidth = scrollController.getScrollWidth() - this.scrollHeight = scrollController.getScrollHeight() - this.clientWidth = scrollController.getClientWidth() - this.clientHeight = scrollController.getClientHeight() - this.clientRect = this.computeClientRect() // do last in case it needs cached values - - if (this.doesListening) { - this.getEventTarget().addEventListener('scroll', this.handleScroll) - } - } - - abstract getEventTarget(): EventTarget - abstract computeClientRect(): Rect - - destroy() { - if (this.doesListening) { - this.getEventTarget().removeEventListener('scroll', this.handleScroll) - } - } - - handleScroll = () => { - this.scrollTop = this.scrollController.getScrollTop() - this.scrollLeft = this.scrollController.getScrollLeft() - this.handleScrollChange() - } - - getScrollTop() { - return this.scrollTop - } - - getScrollLeft() { - return this.scrollLeft - } - - setScrollTop(top: number) { - this.scrollController.setScrollTop(top) - - if (!this.doesListening) { - // we are not relying on the element to normalize out-of-bounds scroll values - // so we need to sanitize ourselves - this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0) - - this.handleScrollChange() - } - } - - setScrollLeft(top: number) { - this.scrollController.setScrollLeft(top) - - if (!this.doesListening) { - // we are not relying on the element to normalize out-of-bounds scroll values - // so we need to sanitize ourselves - this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0) - - this.handleScrollChange() - } - } - - getClientWidth() { - return this.clientWidth - } - - getClientHeight() { - return this.clientHeight - } - - getScrollWidth() { - return this.scrollWidth - } - - getScrollHeight() { - return this.scrollHeight - } - - handleScrollChange() { - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/WindowScrollGeomCache.ts b/apps/schoolCalendar/fullcalendar/interaction/src/WindowScrollGeomCache.ts deleted file mode 100644 index ca65dee6e..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/WindowScrollGeomCache.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Rect, WindowScrollController } from '@fullcalendar/common' -import { ScrollGeomCache } from './ScrollGeomCache' - -export class WindowScrollGeomCache extends ScrollGeomCache { - constructor(doesListening: boolean) { - super(new WindowScrollController(), doesListening) - } - - getEventTarget(): EventTarget { - return window - } - - computeClientRect(): Rect { - return { - left: this.scrollLeft, - right: this.scrollLeft + this.clientWidth, - top: this.scrollTop, - bottom: this.scrollTop + this.clientHeight, - } - } - - // the window is the only scroll object that changes it's rectangle relative - // to the document's topleft as it scrolls - handleScrollChange() { - this.clientRect = this.computeClientRect() - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/api-type-deps.ts b/apps/schoolCalendar/fullcalendar/interaction/src/api-type-deps.ts deleted file mode 100644 index 2b1b51b06..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/api-type-deps.ts +++ /dev/null @@ -1,6 +0,0 @@ -// TODO: rename file to public-types.ts - -export { DateClickArg } from './interactions/DateClicking' -export { EventDragStartArg, EventDragStopArg } from './interactions/EventDragging' -export { EventResizeStartArg, EventResizeStopArg, EventResizeDoneArg } from './interactions/EventResizing' -export { DropArg, EventReceiveArg, EventLeaveArg } from './utils' diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/AutoScroller.ts b/apps/schoolCalendar/fullcalendar/interaction/src/dnd/AutoScroller.ts deleted file mode 100644 index 8d4e8f015..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/AutoScroller.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { getElRoot } from '@fullcalendar/common' -import { ScrollGeomCache } from '../ScrollGeomCache' -import { ElementScrollGeomCache } from '../ElementScrollGeomCache' -import { WindowScrollGeomCache } from '../WindowScrollGeomCache' - -interface Edge { - scrollCache: ScrollGeomCache - name: 'top' | 'left' | 'right' | 'bottom' - distance: number // how many pixels the current pointer is from the edge -} - -// If available we are using native "performance" API instead of "Date" -// Read more about it on MDN: -// https://developer.mozilla.org/en-US/docs/Web/API/Performance -const getTime = typeof performance === 'function' ? (performance as any).now : Date.now - -/* -For a pointer interaction, automatically scrolls certain scroll containers when the pointer -approaches the edge. - -The caller must call start + handleMove + stop. -*/ -export class AutoScroller { - // options that can be set by caller - isEnabled: boolean = true - scrollQuery: (Window | string)[] = [window, '.fc-scroller'] - edgeThreshold: number = 50 // pixels - maxVelocity: number = 300 // pixels per second - - // internal state - pointerScreenX: number | null = null - pointerScreenY: number | null = null - isAnimating: boolean = false - scrollCaches: ScrollGeomCache[] | null = null - msSinceRequest?: number - - // protect against the initial pointerdown being too close to an edge and starting the scroll - everMovedUp: boolean = false - everMovedDown: boolean = false - everMovedLeft: boolean = false - everMovedRight: boolean = false - - start(pageX: number, pageY: number, scrollStartEl: HTMLElement) { - if (this.isEnabled) { - this.scrollCaches = this.buildCaches(scrollStartEl) - this.pointerScreenX = null - this.pointerScreenY = null - this.everMovedUp = false - this.everMovedDown = false - this.everMovedLeft = false - this.everMovedRight = false - this.handleMove(pageX, pageY) - } - } - - handleMove(pageX: number, pageY: number) { - if (this.isEnabled) { - let pointerScreenX = pageX - window.pageXOffset - let pointerScreenY = pageY - window.pageYOffset - - let yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY - let xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX - - if (yDelta < 0) { - this.everMovedUp = true - } else if (yDelta > 0) { - this.everMovedDown = true - } - - if (xDelta < 0) { - this.everMovedLeft = true - } else if (xDelta > 0) { - this.everMovedRight = true - } - - this.pointerScreenX = pointerScreenX - this.pointerScreenY = pointerScreenY - - if (!this.isAnimating) { - this.isAnimating = true - this.requestAnimation(getTime()) - } - } - } - - stop() { - if (this.isEnabled) { - this.isAnimating = false // will stop animation - - for (let scrollCache of this.scrollCaches!) { - scrollCache.destroy() - } - - this.scrollCaches = null - } - } - - requestAnimation(now: number) { - this.msSinceRequest = now - requestAnimationFrame(this.animate) - } - - private animate = () => { - if (this.isAnimating) { // wasn't cancelled between animation calls - let edge = this.computeBestEdge( - this.pointerScreenX! + window.pageXOffset, - this.pointerScreenY! + window.pageYOffset, - ) - - if (edge) { - let now = getTime() - this.handleSide(edge, (now - this.msSinceRequest!) / 1000) - this.requestAnimation(now) - } else { - this.isAnimating = false // will stop animation - } - } - } - - private handleSide(edge: Edge, seconds: number) { - let { scrollCache } = edge - let { edgeThreshold } = this - let invDistance = edgeThreshold - edge.distance - let velocity = // the closer to the edge, the faster we scroll - ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic - this.maxVelocity * seconds - let sign = 1 - - switch (edge.name) { - case 'left': - sign = -1 - // falls through - case 'right': - scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign) - break - - case 'top': - sign = -1 - // falls through - case 'bottom': - scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign) - break - } - } - - // left/top are relative to document topleft - private computeBestEdge(left: number, top: number): Edge | null { - let { edgeThreshold } = this - let bestSide: Edge | null = null - - for (let scrollCache of this.scrollCaches!) { - let rect = scrollCache.clientRect - let leftDist = left - rect.left - let rightDist = rect.right - left - let topDist = top - rect.top - let bottomDist = rect.bottom - top - - // completely within the rect? - if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { - if ( - topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && - (!bestSide || bestSide.distance > topDist) - ) { - bestSide = { scrollCache, name: 'top', distance: topDist } - } - - if ( - bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && - (!bestSide || bestSide.distance > bottomDist) - ) { - bestSide = { scrollCache, name: 'bottom', distance: bottomDist } - } - - if ( - leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && - (!bestSide || bestSide.distance > leftDist) - ) { - bestSide = { scrollCache, name: 'left', distance: leftDist } - } - - if ( - rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && - (!bestSide || bestSide.distance > rightDist) - ) { - bestSide = { scrollCache, name: 'right', distance: rightDist } - } - } - } - - return bestSide - } - - private buildCaches(scrollStartEl: HTMLElement) { - return this.queryScrollEls(scrollStartEl).map((el) => { - if (el === window) { - return new WindowScrollGeomCache(false) // false = don't listen to user-generated scrolls - } - return new ElementScrollGeomCache(el, false) // false = don't listen to user-generated scrolls - }) - } - - private queryScrollEls(scrollStartEl: HTMLElement) { - let els = [] - - for (let query of this.scrollQuery) { - if (typeof query === 'object') { - els.push(query) - } else { - els.push(...Array.prototype.slice.call( - getElRoot(scrollStartEl).querySelectorAll(query), - )) - } - } - - return els - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/ElementMirror.ts b/apps/schoolCalendar/fullcalendar/interaction/src/dnd/ElementMirror.ts deleted file mode 100644 index 6c1e9f4a1..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/ElementMirror.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { removeElement, applyStyle, whenTransitionDone, Rect } from '@fullcalendar/common' - -/* -An effect in which an element follows the movement of a pointer across the screen. -The moving element is a clone of some other element. -Must call start + handleMove + stop. -*/ -export class ElementMirror { - isVisible: boolean = false // must be explicitly enabled - origScreenX?: number - origScreenY?: number - deltaX?: number - deltaY?: number - sourceEl: HTMLElement | null = null - mirrorEl: HTMLElement | null = null - sourceElRect: Rect | null = null // screen coords relative to viewport - - // options that can be set directly by caller - parentNode: HTMLElement = document.body // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues - zIndex: number = 9999 - revertDuration: number = 0 - - start(sourceEl: HTMLElement, pageX: number, pageY: number) { - this.sourceEl = sourceEl - this.sourceElRect = this.sourceEl.getBoundingClientRect() - this.origScreenX = pageX - window.pageXOffset - this.origScreenY = pageY - window.pageYOffset - this.deltaX = 0 - this.deltaY = 0 - this.updateElPosition() - } - - handleMove(pageX: number, pageY: number) { - this.deltaX = (pageX - window.pageXOffset) - this.origScreenX! - this.deltaY = (pageY - window.pageYOffset) - this.origScreenY! - this.updateElPosition() - } - - // can be called before start - setIsVisible(bool: boolean) { - if (bool) { - if (!this.isVisible) { - if (this.mirrorEl) { - this.mirrorEl.style.display = '' - } - - this.isVisible = bool // needs to happen before updateElPosition - this.updateElPosition() // because was not updating the position while invisible - } - } else if (this.isVisible) { - if (this.mirrorEl) { - this.mirrorEl.style.display = 'none' - } - - this.isVisible = bool - } - } - - // always async - stop(needsRevertAnimation: boolean, callback: () => void) { - let done = () => { - this.cleanup() - callback() - } - - if ( - needsRevertAnimation && - this.mirrorEl && - this.isVisible && - this.revertDuration && // if 0, transition won't work - (this.deltaX || this.deltaY) // if same coords, transition won't work - ) { - this.doRevertAnimation(done, this.revertDuration) - } else { - setTimeout(done, 0) - } - } - - doRevertAnimation(callback: () => void, revertDuration: number) { - let mirrorEl = this.mirrorEl! - let finalSourceElRect = this.sourceEl!.getBoundingClientRect() // because autoscrolling might have happened - - mirrorEl.style.transition = - 'top ' + revertDuration + 'ms,' + - 'left ' + revertDuration + 'ms' - - applyStyle(mirrorEl, { - left: finalSourceElRect.left, - top: finalSourceElRect.top, - }) - - whenTransitionDone(mirrorEl, () => { - mirrorEl.style.transition = '' - callback() - }) - } - - cleanup() { - if (this.mirrorEl) { - removeElement(this.mirrorEl) - this.mirrorEl = null - } - - this.sourceEl = null - } - - updateElPosition() { - if (this.sourceEl && this.isVisible) { - applyStyle(this.getMirrorEl(), { - left: this.sourceElRect!.left + this.deltaX!, - top: this.sourceElRect!.top + this.deltaY!, - }) - } - } - - getMirrorEl(): HTMLElement { - let sourceElRect = this.sourceElRect! - let mirrorEl = this.mirrorEl - - if (!mirrorEl) { - mirrorEl = this.mirrorEl = this.sourceEl!.cloneNode(true) as HTMLElement // cloneChildren=true - - // we don't want long taps or any mouse interaction causing selection/menus. - // would use preventSelection(), but that prevents selectstart, causing problems. - mirrorEl.classList.add('fc-unselectable') - - mirrorEl.classList.add('fc-event-dragging') - - applyStyle(mirrorEl, { - position: 'fixed', - zIndex: this.zIndex, - visibility: '', // in case original element was hidden by the drag effect - boxSizing: 'border-box', // for easy width/height - width: sourceElRect.right - sourceElRect.left, // explicit height in case there was a 'right' value - height: sourceElRect.bottom - sourceElRect.top, // explicit width in case there was a 'bottom' value - right: 'auto', // erase and set width instead - bottom: 'auto', // erase and set height instead - margin: 0, - }) - - this.parentNode.appendChild(mirrorEl) - } - - return mirrorEl - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/FeaturefulElementDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/dnd/FeaturefulElementDragging.ts deleted file mode 100644 index 3f1c7826b..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/FeaturefulElementDragging.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { - PointerDragEvent, - preventSelection, - allowSelection, - preventContextMenu, - allowContextMenu, - ElementDragging, -} from '@fullcalendar/common' -import { PointerDragging } from './PointerDragging' -import { ElementMirror } from './ElementMirror' -import { AutoScroller } from './AutoScroller' - -/* -Monitors dragging on an element. Has a number of high-level features: -- minimum distance required before dragging -- minimum wait time ("delay") before dragging -- a mirror element that follows the pointer -*/ -export class FeaturefulElementDragging extends ElementDragging { - pointer: PointerDragging - mirror: ElementMirror - autoScroller: AutoScroller - - // options that can be directly set by caller - // the caller can also set the PointerDragging's options as well - delay: number | null = null - minDistance: number = 0 - touchScrollAllowed: boolean = true // prevents drag from starting and blocks scrolling during drag - - mirrorNeedsRevert: boolean = false - isInteracting: boolean = false // is the user validly moving the pointer? lasts until pointerup - isDragging: boolean = false // is it INTENTFULLY dragging? lasts until after revert animation - isDelayEnded: boolean = false - isDistanceSurpassed: boolean = false - delayTimeoutId: number | null = null - - constructor(private containerEl: HTMLElement, selector?: string) { - super(containerEl) - - let pointer = this.pointer = new PointerDragging(containerEl) - pointer.emitter.on('pointerdown', this.onPointerDown) - pointer.emitter.on('pointermove', this.onPointerMove) - pointer.emitter.on('pointerup', this.onPointerUp) - - if (selector) { - pointer.selector = selector - } - - this.mirror = new ElementMirror() - this.autoScroller = new AutoScroller() - } - - destroy() { - this.pointer.destroy() - - // HACK: simulate a pointer-up to end the current drag - // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) - this.onPointerUp({} as any) - } - - onPointerDown = (ev: PointerDragEvent) => { - if (!this.isDragging) { // so new drag doesn't happen while revert animation is going - this.isInteracting = true - this.isDelayEnded = false - this.isDistanceSurpassed = false - - preventSelection(document.body) - preventContextMenu(document.body) - - // prevent links from being visited if there's an eventual drag. - // also prevents selection in older browsers (maybe?). - // not necessary for touch, besides, browser would complain about passiveness. - if (!ev.isTouch) { - ev.origEvent.preventDefault() - } - - this.emitter.trigger('pointerdown', ev) - - if ( - this.isInteracting && // not destroyed via pointerdown handler - !this.pointer.shouldIgnoreMove - ) { - // actions related to initiating dragstart+dragmove+dragend... - - this.mirror.setIsVisible(false) // reset. caller must set-visible - this.mirror.start(ev.subjectEl as HTMLElement, ev.pageX, ev.pageY) // must happen on first pointer down - - this.startDelay(ev) - - if (!this.minDistance) { - this.handleDistanceSurpassed(ev) - } - } - } - } - - onPointerMove = (ev: PointerDragEvent) => { - if (this.isInteracting) { - this.emitter.trigger('pointermove', ev) - - if (!this.isDistanceSurpassed) { - let minDistance = this.minDistance - let distanceSq // current distance from the origin, squared - let { deltaX, deltaY } = ev - - distanceSq = deltaX * deltaX + deltaY * deltaY - if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem - this.handleDistanceSurpassed(ev) - } - } - - if (this.isDragging) { - // a real pointer move? (not one simulated by scrolling) - if (ev.origEvent.type !== 'scroll') { - this.mirror.handleMove(ev.pageX, ev.pageY) - this.autoScroller.handleMove(ev.pageX, ev.pageY) - } - - this.emitter.trigger('dragmove', ev) - } - } - } - - onPointerUp = (ev: PointerDragEvent) => { - if (this.isInteracting) { - this.isInteracting = false - - allowSelection(document.body) - allowContextMenu(document.body) - - this.emitter.trigger('pointerup', ev) // can potentially set mirrorNeedsRevert - - if (this.isDragging) { - this.autoScroller.stop() - this.tryStopDrag(ev) // which will stop the mirror - } - - if (this.delayTimeoutId) { - clearTimeout(this.delayTimeoutId) - this.delayTimeoutId = null - } - } - } - - startDelay(ev: PointerDragEvent) { - if (typeof this.delay === 'number') { - this.delayTimeoutId = setTimeout(() => { - this.delayTimeoutId = null - this.handleDelayEnd(ev) - }, this.delay) as any // not assignable to number! - } else { - this.handleDelayEnd(ev) - } - } - - handleDelayEnd(ev: PointerDragEvent) { - this.isDelayEnded = true - this.tryStartDrag(ev) - } - - handleDistanceSurpassed(ev: PointerDragEvent) { - this.isDistanceSurpassed = true - this.tryStartDrag(ev) - } - - tryStartDrag(ev: PointerDragEvent) { - if (this.isDelayEnded && this.isDistanceSurpassed) { - if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { - this.isDragging = true - this.mirrorNeedsRevert = false - - this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl) - this.emitter.trigger('dragstart', ev) - - if (this.touchScrollAllowed === false) { - this.pointer.cancelTouchScroll() - } - } - } - } - - tryStopDrag(ev: PointerDragEvent) { - // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events - // that come from the document to fire beforehand. much more convenient this way. - this.mirror.stop( - this.mirrorNeedsRevert, - this.stopDrag.bind(this, ev), // bound with args - ) - } - - stopDrag(ev: PointerDragEvent) { - this.isDragging = false - this.emitter.trigger('dragend', ev) - } - - // fill in the implementations... - - setIgnoreMove(bool: boolean) { - this.pointer.shouldIgnoreMove = bool - } - - setMirrorIsVisible(bool: boolean) { - this.mirror.setIsVisible(bool) - } - - setMirrorNeedsRevert(bool: boolean) { - this.mirrorNeedsRevert = bool - } - - setAutoScrollEnabled(bool: boolean) { - this.autoScroller.isEnabled = bool - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/PointerDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/dnd/PointerDragging.ts deleted file mode 100644 index dbe7d8abb..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/dnd/PointerDragging.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { config, elementClosest, Emitter, PointerDragEvent } from '@fullcalendar/common' - -config.touchMouseIgnoreWait = 500 - -let ignoreMouseDepth = 0 -let listenerCnt = 0 -let isWindowTouchMoveCancelled = false - -/* -Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. -Tracks when the pointer "drags" on a certain element, meaning down+move+up. - -Also, tracks if there was touch-scrolling. -Also, can prevent touch-scrolling from happening. -Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. - -emits: -- pointerdown -- pointermove -- pointerup -*/ -export class PointerDragging { - containerEl: EventTarget - subjectEl: HTMLElement | null = null - emitter: Emitter - - // options that can be directly assigned by caller - selector: string = '' // will cause subjectEl in all emitted events to be this element - handleSelector: string = '' - shouldIgnoreMove: boolean = false - shouldWatchScroll: boolean = true // for simulating pointermove on scroll - - // internal states - isDragging: boolean = false - isTouchDragging: boolean = false - wasTouchScroll: boolean = false - origPageX: number - origPageY: number - prevPageX: number - prevPageY: number - prevScrollX: number // at time of last pointer pageX/pageY capture - prevScrollY: number // " - - constructor(containerEl: EventTarget) { - this.containerEl = containerEl - this.emitter = new Emitter() - containerEl.addEventListener('mousedown', this.handleMouseDown as EventListener) - containerEl.addEventListener('touchstart', this.handleTouchStart as EventListener, { passive: true }) - listenerCreated() - } - - destroy() { - this.containerEl.removeEventListener('mousedown', this.handleMouseDown as EventListener) - this.containerEl.removeEventListener('touchstart', this.handleTouchStart as EventListener, { passive: true } as AddEventListenerOptions) - listenerDestroyed() - } - - tryStart(ev: UIEvent): boolean { - let subjectEl = this.querySubjectEl(ev) - let downEl = ev.target as HTMLElement - - if ( - subjectEl && - (!this.handleSelector || elementClosest(downEl, this.handleSelector)) - ) { - this.subjectEl = subjectEl - this.isDragging = true // do this first so cancelTouchScroll will work - this.wasTouchScroll = false - - return true - } - - return false - } - - cleanup() { - isWindowTouchMoveCancelled = false - this.isDragging = false - this.subjectEl = null - // keep wasTouchScroll around for later access - this.destroyScrollWatch() - } - - querySubjectEl(ev: UIEvent): HTMLElement { - if (this.selector) { - return elementClosest(ev.target as HTMLElement, this.selector) - } - return this.containerEl as HTMLElement - } - - // Mouse - // ---------------------------------------------------------------------------------------------------- - - handleMouseDown = (ev: MouseEvent) => { - if ( - !this.shouldIgnoreMouse() && - isPrimaryMouseButton(ev) && - this.tryStart(ev) - ) { - let pev = this.createEventFromMouse(ev, true) - this.emitter.trigger('pointerdown', pev) - this.initScrollWatch(pev) - - if (!this.shouldIgnoreMove) { - document.addEventListener('mousemove', this.handleMouseMove) - } - - document.addEventListener('mouseup', this.handleMouseUp) - } - } - - handleMouseMove = (ev: MouseEvent) => { - let pev = this.createEventFromMouse(ev) - this.recordCoords(pev) - this.emitter.trigger('pointermove', pev) - } - - handleMouseUp = (ev: MouseEvent) => { - document.removeEventListener('mousemove', this.handleMouseMove) - document.removeEventListener('mouseup', this.handleMouseUp) - - this.emitter.trigger('pointerup', this.createEventFromMouse(ev)) - - this.cleanup() // call last so that pointerup has access to props - } - - shouldIgnoreMouse() { - return ignoreMouseDepth || this.isTouchDragging - } - - // Touch - // ---------------------------------------------------------------------------------------------------- - - handleTouchStart = (ev: TouchEvent) => { - if (this.tryStart(ev)) { - this.isTouchDragging = true - - let pev = this.createEventFromTouch(ev, true) - this.emitter.trigger('pointerdown', pev) - this.initScrollWatch(pev) - - // unlike mouse, need to attach to target, not document - // https://stackoverflow.com/a/45760014 - let targetEl = ev.target as HTMLElement - - if (!this.shouldIgnoreMove) { - targetEl.addEventListener('touchmove', this.handleTouchMove) - } - - targetEl.addEventListener('touchend', this.handleTouchEnd) - targetEl.addEventListener('touchcancel', this.handleTouchEnd) // treat it as a touch end - - // attach a handler to get called when ANY scroll action happens on the page. - // this was impossible to do with normal on/off because 'scroll' doesn't bubble. - // http://stackoverflow.com/a/32954565/96342 - window.addEventListener( - 'scroll', - this.handleTouchScroll, - true, // useCapture - ) - } - } - - handleTouchMove = (ev: TouchEvent) => { - let pev = this.createEventFromTouch(ev) - this.recordCoords(pev) - this.emitter.trigger('pointermove', pev) - } - - handleTouchEnd = (ev: TouchEvent) => { - if (this.isDragging) { // done to guard against touchend followed by touchcancel - let targetEl = ev.target as HTMLElement - - targetEl.removeEventListener('touchmove', this.handleTouchMove) - targetEl.removeEventListener('touchend', this.handleTouchEnd) - targetEl.removeEventListener('touchcancel', this.handleTouchEnd) - window.removeEventListener('scroll', this.handleTouchScroll, true) // useCaptured=true - - this.emitter.trigger('pointerup', this.createEventFromTouch(ev)) - - this.cleanup() // call last so that pointerup has access to props - this.isTouchDragging = false - startIgnoringMouse() - } - } - - handleTouchScroll = () => { - this.wasTouchScroll = true - } - - // can be called by user of this class, to cancel touch-based scrolling for the current drag - cancelTouchScroll() { - if (this.isDragging) { - isWindowTouchMoveCancelled = true - } - } - - // Scrolling that simulates pointermoves - // ---------------------------------------------------------------------------------------------------- - - initScrollWatch(ev: PointerDragEvent) { - if (this.shouldWatchScroll) { - this.recordCoords(ev) - window.addEventListener('scroll', this.handleScroll, true) // useCapture=true - } - } - - recordCoords(ev: PointerDragEvent) { - if (this.shouldWatchScroll) { - this.prevPageX = (ev as any).pageX - this.prevPageY = (ev as any).pageY - this.prevScrollX = window.pageXOffset - this.prevScrollY = window.pageYOffset - } - } - - handleScroll = (ev: UIEvent) => { - if (!this.shouldIgnoreMove) { - let pageX = (window.pageXOffset - this.prevScrollX) + this.prevPageX - let pageY = (window.pageYOffset - this.prevScrollY) + this.prevPageY - - this.emitter.trigger('pointermove', { - origEvent: ev, - isTouch: this.isTouchDragging, - subjectEl: this.subjectEl, - pageX, - pageY, - deltaX: pageX - this.origPageX, - deltaY: pageY - this.origPageY, - } as PointerDragEvent) - } - } - - destroyScrollWatch() { - if (this.shouldWatchScroll) { - window.removeEventListener('scroll', this.handleScroll, true) // useCaptured=true - } - } - - // Event Normalization - // ---------------------------------------------------------------------------------------------------- - - createEventFromMouse(ev: MouseEvent, isFirst?: boolean): PointerDragEvent { - let deltaX = 0 - let deltaY = 0 - - // TODO: repeat code - if (isFirst) { - this.origPageX = ev.pageX - this.origPageY = ev.pageY - } else { - deltaX = ev.pageX - this.origPageX - deltaY = ev.pageY - this.origPageY - } - - return { - origEvent: ev, - isTouch: false, - subjectEl: this.subjectEl, - pageX: ev.pageX, - pageY: ev.pageY, - deltaX, - deltaY, - } - } - - createEventFromTouch(ev: TouchEvent, isFirst?: boolean): PointerDragEvent { - let touches = ev.touches - let pageX - let pageY - let deltaX = 0 - let deltaY = 0 - - // if touch coords available, prefer, - // because FF would give bad ev.pageX ev.pageY - if (touches && touches.length) { - pageX = touches[0].pageX - pageY = touches[0].pageY - } else { - pageX = (ev as any).pageX - pageY = (ev as any).pageY - } - - // TODO: repeat code - if (isFirst) { - this.origPageX = pageX - this.origPageY = pageY - } else { - deltaX = pageX - this.origPageX - deltaY = pageY - this.origPageY - } - - return { - origEvent: ev, - isTouch: true, - subjectEl: this.subjectEl, - pageX, - pageY, - deltaX, - deltaY, - } - } -} - -// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) -function isPrimaryMouseButton(ev: MouseEvent) { - return ev.button === 0 && !ev.ctrlKey -} - -// Ignoring fake mouse events generated by touch -// ---------------------------------------------------------------------------------------------------- - -function startIgnoringMouse() { // can be made non-class function - ignoreMouseDepth += 1 - - setTimeout(() => { - ignoreMouseDepth -= 1 - }, config.touchMouseIgnoreWait) -} - -// We want to attach touchmove as early as possible for Safari -// ---------------------------------------------------------------------------------------------------- - -function listenerCreated() { - listenerCnt += 1 - - if (listenerCnt === 1) { - window.addEventListener('touchmove', onWindowTouchMove, { passive: false }) - } -} - -function listenerDestroyed() { - listenerCnt -= 1 - - if (!listenerCnt) { - window.removeEventListener('touchmove', onWindowTouchMove, { passive: false } as AddEventListenerOptions) - } -} - -function onWindowTouchMove(ev: UIEvent) { - if (isWindowTouchMoveCancelled) { - ev.preventDefault() - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalDraggable.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalDraggable.ts deleted file mode 100644 index 22aba108d..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalDraggable.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { BASE_OPTION_DEFAULTS, PointerDragEvent } from '@fullcalendar/common' -import { FeaturefulElementDragging } from '../dnd/FeaturefulElementDragging' -import { ExternalElementDragging, DragMetaGenerator } from './ExternalElementDragging' - -export interface ExternalDraggableSettings { - eventData?: DragMetaGenerator - itemSelector?: string - minDistance?: number - longPressDelay?: number - appendTo?: HTMLElement -} - -/* -Makes an element (that is *external* to any calendar) draggable. -Can pass in data that determines how an event will be created when dropped onto a calendar. -Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. -*/ -export class ExternalDraggable { - dragging: FeaturefulElementDragging - settings: ExternalDraggableSettings - - constructor(el: HTMLElement, settings: ExternalDraggableSettings = {}) { - this.settings = settings - - let dragging = this.dragging = new FeaturefulElementDragging(el) - dragging.touchScrollAllowed = false - - if (settings.itemSelector != null) { - dragging.pointer.selector = settings.itemSelector - } - - if (settings.appendTo != null) { - dragging.mirror.parentNode = settings.appendTo // TODO: write tests - } - - dragging.emitter.on('pointerdown', this.handlePointerDown) - dragging.emitter.on('dragstart', this.handleDragStart) - - new ExternalElementDragging(dragging, settings.eventData) // eslint-disable-line no-new - } - - handlePointerDown = (ev: PointerDragEvent) => { - let { dragging } = this - let { minDistance, longPressDelay } = this.settings - - dragging.minDistance = - minDistance != null ? - minDistance : - (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance) - - dragging.delay = - ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv - (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) : - 0 - } - - handleDragStart = (ev: PointerDragEvent) => { - if ( - ev.isTouch && - this.dragging.delay && - (ev.subjectEl as HTMLElement).classList.contains('fc-event') - ) { - this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected') - } - } - - destroy() { - this.dragging.destroy() - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalElementDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalElementDragging.ts deleted file mode 100644 index 95ac7e0c2..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ExternalElementDragging.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { - Hit, - interactionSettingsStore, - PointerDragEvent, - parseEventDef, createEventInstance, EventTuple, - createEmptyEventStore, eventTupleToStore, - config, - DateSpan, DatePointApi, - EventInteractionState, - DragMetaInput, DragMeta, parseDragMeta, - EventApi, - elementMatches, - enableCursor, disableCursor, - isInteractionValid, - ElementDragging, - ViewApi, - CalendarContext, - getDefaultEventEnd, - refineEventDef, -} from '@fullcalendar/common' -import { __assign } from 'tslib' -import { HitDragging } from '../interactions/HitDragging' -import { buildDatePointApiWithContext } from '../utils' - -export type DragMetaGenerator = DragMetaInput | ((el: HTMLElement) => DragMetaInput) - -export interface ExternalDropApi extends DatePointApi { - draggedEl: HTMLElement - jsEvent: UIEvent - view: ViewApi -} - -/* -Given an already instantiated draggable object for one-or-more elements, -Interprets any dragging as an attempt to drag an events that lives outside -of a calendar onto a calendar. -*/ -export class ExternalElementDragging { - hitDragging: HitDragging - receivingContext: CalendarContext | null = null - droppableEvent: EventTuple | null = null // will exist for all drags, even if create:false - suppliedDragMeta: DragMetaGenerator | null = null - dragMeta: DragMeta | null = null - - constructor(dragging: ElementDragging, suppliedDragMeta?: DragMetaGenerator) { - let hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore) - hitDragging.requireInitial = false // will start outside of a component - hitDragging.emitter.on('dragstart', this.handleDragStart) - hitDragging.emitter.on('hitupdate', this.handleHitUpdate) - hitDragging.emitter.on('dragend', this.handleDragEnd) - - this.suppliedDragMeta = suppliedDragMeta - } - - handleDragStart = (ev: PointerDragEvent) => { - this.dragMeta = this.buildDragMeta(ev.subjectEl as HTMLElement) - } - - buildDragMeta(subjectEl: HTMLElement) { - if (typeof this.suppliedDragMeta === 'object') { - return parseDragMeta(this.suppliedDragMeta) - } - if (typeof this.suppliedDragMeta === 'function') { - return parseDragMeta(this.suppliedDragMeta(subjectEl)) - } - return getDragMetaFromEl(subjectEl) - } - - handleHitUpdate = (hit: Hit | null, isFinal: boolean, ev: PointerDragEvent) => { - let { dragging } = this.hitDragging - let receivingContext: CalendarContext | null = null - let droppableEvent: EventTuple | null = null - let isInvalid = false - let interaction: EventInteractionState = { - affectedEvents: createEmptyEventStore(), - mutatedEvents: createEmptyEventStore(), - isEvent: this.dragMeta!.create, - } - - if (hit) { - receivingContext = hit.context - - if (this.canDropElOnCalendar(ev.subjectEl as HTMLElement, receivingContext)) { - droppableEvent = computeEventForDateSpan( - hit.dateSpan, - this.dragMeta!, - receivingContext, - ) - - interaction.mutatedEvents = eventTupleToStore(droppableEvent) - isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext) - - if (isInvalid) { - interaction.mutatedEvents = createEmptyEventStore() - droppableEvent = null - } - } - } - - this.displayDrag(receivingContext, interaction) - - // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) - // TODO: wish we could somehow wait for dispatch to guarantee render - dragging.setMirrorIsVisible( - isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'), // TODO: turn className into constant - // TODO: somehow query FullCalendars WITHIN shadow-roots for existing event-mirror els - ) - - if (!isInvalid) { - enableCursor() - } else { - disableCursor() - } - - if (!isFinal) { - dragging.setMirrorNeedsRevert(!droppableEvent) - - this.receivingContext = receivingContext - this.droppableEvent = droppableEvent - } - } - - handleDragEnd = (pev: PointerDragEvent) => { - let { receivingContext, droppableEvent } = this - - this.clearDrag() - - if (receivingContext && droppableEvent) { - let finalHit = this.hitDragging.finalHit! - let finalView = finalHit.context.viewApi - let dragMeta = this.dragMeta! - - receivingContext.emitter.trigger('drop', { - ...buildDatePointApiWithContext(finalHit.dateSpan, receivingContext), - draggedEl: pev.subjectEl as HTMLElement, - jsEvent: pev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: finalView, - }) - - if (dragMeta.create) { - let addingEvents = eventTupleToStore(droppableEvent) - - receivingContext.dispatch({ - type: 'MERGE_EVENTS', - eventStore: addingEvents, - }) - - if (pev.isTouch) { - receivingContext.dispatch({ - type: 'SELECT_EVENT', - eventInstanceId: droppableEvent.instance.instanceId, - }) - } - - // signal that an external event landed - receivingContext.emitter.trigger('eventReceive', { - event: new EventApi( - receivingContext, - droppableEvent.def, - droppableEvent.instance, - ), - relatedEvents: [], - revert() { - receivingContext.dispatch({ - type: 'REMOVE_EVENTS', - eventStore: addingEvents, - }) - }, - draggedEl: pev.subjectEl as HTMLElement, - view: finalView, - }) - } - } - - this.receivingContext = null - this.droppableEvent = null - } - - displayDrag(nextContext: CalendarContext | null, state: EventInteractionState) { - let prevContext = this.receivingContext - - if (prevContext && prevContext !== nextContext) { - prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }) - } - - if (nextContext) { - nextContext.dispatch({ type: 'SET_EVENT_DRAG', state }) - } - } - - clearDrag() { - if (this.receivingContext) { - this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }) - } - } - - canDropElOnCalendar(el: HTMLElement, receivingContext: CalendarContext): boolean { - let dropAccept = receivingContext.options.dropAccept - - if (typeof dropAccept === 'function') { - return dropAccept.call(receivingContext.calendarApi, el) - } - - if (typeof dropAccept === 'string' && dropAccept) { - return Boolean(elementMatches(el, dropAccept)) - } - - return true - } -} - -// Utils for computing event store from the DragMeta -// ---------------------------------------------------------------------------------------------------- - -function computeEventForDateSpan(dateSpan: DateSpan, dragMeta: DragMeta, context: CalendarContext): EventTuple { - let defProps = { ...dragMeta.leftoverProps } - - for (let transform of context.pluginHooks.externalDefTransforms) { - __assign(defProps, transform(dateSpan, dragMeta)) - } - - let { refined, extra } = refineEventDef(defProps, context) - let def = parseEventDef( - refined, - extra, - dragMeta.sourceId, - dateSpan.allDay, - context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd - context, - ) - - let start = dateSpan.range.start - - // only rely on time info if drop zone is all-day, - // otherwise, we already know the time - if (dateSpan.allDay && dragMeta.startTime) { - start = context.dateEnv.add(start, dragMeta.startTime) - } - - let end = dragMeta.duration ? - context.dateEnv.add(start, dragMeta.duration) : - getDefaultEventEnd(dateSpan.allDay, start, context) - - let instance = createEventInstance(def.defId, { start, end }) - - return { def, instance } -} - -// Utils for extracting data from element -// ---------------------------------------------------------------------------------------------------- - -function getDragMetaFromEl(el: HTMLElement): DragMeta { - let str = getEmbeddedElData(el, 'event') - let obj = str ? - JSON.parse(str) : - { create: false } // if no embedded data, assume no event creation - - return parseDragMeta(obj) -} - -config.dataAttrPrefix = '' - -function getEmbeddedElData(el: HTMLElement, name: string): string { - let prefix = config.dataAttrPrefix - let prefixedName = (prefix ? prefix + '-' : '') + name - - return el.getAttribute('data-' + prefixedName) || '' -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/InferredElementDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/InferredElementDragging.ts deleted file mode 100644 index ab03cec00..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/InferredElementDragging.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { PointerDragEvent, ElementDragging } from '@fullcalendar/common' -import { PointerDragging } from '../dnd/PointerDragging' - -/* -Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. -The third-party system is responsible for drawing the visuals effects of the drag. -This class simply monitors for pointer movements and fires events. -It also has the ability to hide the moving element (the "mirror") during the drag. -*/ -export class InferredElementDragging extends ElementDragging { - pointer: PointerDragging - shouldIgnoreMove: boolean = false - mirrorSelector: string = '' - currentMirrorEl: HTMLElement | null = null - - constructor(containerEl: HTMLElement) { - super(containerEl) - - let pointer = this.pointer = new PointerDragging(containerEl) - pointer.emitter.on('pointerdown', this.handlePointerDown) - pointer.emitter.on('pointermove', this.handlePointerMove) - pointer.emitter.on('pointerup', this.handlePointerUp) - } - - destroy() { - this.pointer.destroy() - } - - handlePointerDown = (ev: PointerDragEvent) => { - this.emitter.trigger('pointerdown', ev) - - if (!this.shouldIgnoreMove) { - // fire dragstart right away. does not support delay or min-distance - this.emitter.trigger('dragstart', ev) - } - } - - handlePointerMove = (ev: PointerDragEvent) => { - if (!this.shouldIgnoreMove) { - this.emitter.trigger('dragmove', ev) - } - } - - handlePointerUp = (ev: PointerDragEvent) => { - this.emitter.trigger('pointerup', ev) - - if (!this.shouldIgnoreMove) { - // fire dragend right away. does not support a revert animation - this.emitter.trigger('dragend', ev) - } - } - - setIgnoreMove(bool: boolean) { - this.shouldIgnoreMove = bool - } - - setMirrorIsVisible(bool: boolean) { - if (bool) { - // restore a previously hidden element. - // use the reference in case the selector class has already been removed. - if (this.currentMirrorEl) { - this.currentMirrorEl.style.visibility = '' - this.currentMirrorEl = null - } - } else { - let mirrorEl = this.mirrorSelector - // TODO: somehow query FullCalendars WITHIN shadow-roots - ? document.querySelector(this.mirrorSelector) as HTMLElement - : null - - if (mirrorEl) { - this.currentMirrorEl = mirrorEl - mirrorEl.style.visibility = 'hidden' - } - } - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ThirdPartyDraggable.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ThirdPartyDraggable.ts deleted file mode 100644 index 324b22255..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions-external/ThirdPartyDraggable.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { ExternalElementDragging, DragMetaGenerator } from './ExternalElementDragging' -import { InferredElementDragging } from './InferredElementDragging' - -export interface ThirdPartyDraggableSettings { - eventData?: DragMetaGenerator - itemSelector?: string - mirrorSelector?: string -} - -/* -Bridges third-party drag-n-drop systems with FullCalendar. -Must be instantiated and destroyed by caller. -*/ -export class ThirdPartyDraggable { - dragging: InferredElementDragging - - constructor( - containerOrSettings?: EventTarget | ThirdPartyDraggableSettings, - settings?: ThirdPartyDraggableSettings, - ) { - let containerEl: EventTarget = document - - if ( - // wish we could just test instanceof EventTarget, but doesn't work in IE11 - containerOrSettings === document || - containerOrSettings instanceof Element - ) { - containerEl = containerOrSettings as EventTarget - settings = settings || {} - } else { - settings = (containerOrSettings || {}) as ThirdPartyDraggableSettings - } - - let dragging = this.dragging = new InferredElementDragging(containerEl as HTMLElement) - - if (typeof settings.itemSelector === 'string') { - dragging.pointer.selector = settings.itemSelector - } else if (containerEl === document) { - dragging.pointer.selector = '[data-event]' - } - - if (typeof settings.mirrorSelector === 'string') { - dragging.mirrorSelector = settings.mirrorSelector - } - - new ExternalElementDragging(dragging, settings.eventData) // eslint-disable-line no-new - } - - destroy() { - this.dragging.destroy() - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateClicking.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateClicking.ts deleted file mode 100644 index 06b352de9..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateClicking.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { - PointerDragEvent, Interaction, InteractionSettings, interactionSettingsToStore, - DatePointApi, - ViewApi, -} from '@fullcalendar/common' -import { FeaturefulElementDragging } from '../dnd/FeaturefulElementDragging' -import { HitDragging, isHitsEqual } from './HitDragging' -import { buildDatePointApiWithContext } from '../utils' - -export interface DateClickArg extends DatePointApi { - dayEl: HTMLElement - jsEvent: MouseEvent - view: ViewApi -} - -/* -Monitors when the user clicks on a specific date/time of a component. -A pointerdown+pointerup on the same "hit" constitutes a click. -*/ -export class DateClicking extends Interaction { - dragging: FeaturefulElementDragging - hitDragging: HitDragging - - constructor(settings: InteractionSettings) { - super(settings) - - // we DO want to watch pointer moves because otherwise finalHit won't get populated - this.dragging = new FeaturefulElementDragging(settings.el) - this.dragging.autoScroller.isEnabled = false - - let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings)) - hitDragging.emitter.on('pointerdown', this.handlePointerDown) - hitDragging.emitter.on('dragend', this.handleDragEnd) - } - - destroy() { - this.dragging.destroy() - } - - handlePointerDown = (pev: PointerDragEvent) => { - let { dragging } = this - let downEl = pev.origEvent.target as HTMLElement - - // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired - dragging.setIgnoreMove( - !this.component.isValidDateDownEl(downEl), - ) - } - - // won't even fire if moving was ignored - handleDragEnd = (ev: PointerDragEvent) => { - let { component } = this - let { pointer } = this.dragging - - if (!pointer.wasTouchScroll) { - let { initialHit, finalHit } = this.hitDragging - - if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { - let { context } = component - let arg: DateClickArg = { - ...buildDatePointApiWithContext(initialHit.dateSpan, context), - dayEl: initialHit.dayEl, - jsEvent: ev.origEvent as MouseEvent, - view: context.viewApi || context.calendarApi.view, - } - - context.emitter.trigger('dateClick', arg) - } - } - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateSelecting.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateSelecting.ts deleted file mode 100644 index fa6b3ff09..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/DateSelecting.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - compareNumbers, enableCursor, disableCursor, DateComponent, Hit, - DateSpan, PointerDragEvent, dateSelectionJoinTransformer, - Interaction, InteractionSettings, interactionSettingsToStore, - triggerDateSelect, isDateSelectionValid, -} from '@fullcalendar/common' -import { __assign } from 'tslib' -import { HitDragging } from './HitDragging' -import { FeaturefulElementDragging } from '../dnd/FeaturefulElementDragging' - -/* -Tracks when the user selects a portion of time of a component, -constituted by a drag over date cells, with a possible delay at the beginning of the drag. -*/ -export class DateSelecting extends Interaction { - dragging: FeaturefulElementDragging - hitDragging: HitDragging - dragSelection: DateSpan | null = null - - constructor(settings: InteractionSettings) { - super(settings) - let { component } = settings - let { options } = component.context - - let dragging = this.dragging = new FeaturefulElementDragging(settings.el) - dragging.touchScrollAllowed = false - dragging.minDistance = options.selectMinDistance || 0 - dragging.autoScroller.isEnabled = options.dragScroll - - let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings)) - hitDragging.emitter.on('pointerdown', this.handlePointerDown) - hitDragging.emitter.on('dragstart', this.handleDragStart) - hitDragging.emitter.on('hitupdate', this.handleHitUpdate) - hitDragging.emitter.on('pointerup', this.handlePointerUp) - } - - destroy() { - this.dragging.destroy() - } - - handlePointerDown = (ev: PointerDragEvent) => { - let { component, dragging } = this - let { options } = component.context - - let canSelect = options.selectable && - component.isValidDateDownEl(ev.origEvent.target as HTMLElement) - - // don't bother to watch expensive moves if component won't do selection - dragging.setIgnoreMove(!canSelect) - - // if touch, require user to hold down - dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null - } - - handleDragStart = (ev: PointerDragEvent) => { - this.component.context.calendarApi.unselect(ev) // unselect previous selections - } - - handleHitUpdate = (hit: Hit | null, isFinal: boolean) => { - let { context } = this.component - let dragSelection: DateSpan | null = null - let isInvalid = false - - if (hit) { - let initialHit = this.hitDragging.initialHit! - let disallowed = hit.componentId === initialHit.componentId - && this.isHitComboAllowed - && !this.isHitComboAllowed(initialHit, hit) - - if (!disallowed) { - dragSelection = joinHitsIntoSelection( - initialHit, - hit, - context.pluginHooks.dateSelectionTransformers, - ) - } - - if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) { - isInvalid = true - dragSelection = null - } - } - - if (dragSelection) { - context.dispatch({ type: 'SELECT_DATES', selection: dragSelection }) - } else if (!isFinal) { // only unselect if moved away while dragging - context.dispatch({ type: 'UNSELECT_DATES' }) - } - - if (!isInvalid) { - enableCursor() - } else { - disableCursor() - } - - if (!isFinal) { - this.dragSelection = dragSelection // only clear if moved away from all hits while dragging - } - } - - handlePointerUp = (pev: PointerDragEvent) => { - if (this.dragSelection) { - // selection is already rendered, so just need to report selection - triggerDateSelect(this.dragSelection, pev, this.component.context) - - this.dragSelection = null - } - } -} - -function getComponentTouchDelay(component: DateComponent): number { - let { options } = component.context - let delay = options.selectLongPressDelay - - if (delay == null) { - delay = options.longPressDelay - } - - return delay -} - -function joinHitsIntoSelection(hit0: Hit, hit1: Hit, dateSelectionTransformers: dateSelectionJoinTransformer[]): DateSpan { - let dateSpan0 = hit0.dateSpan - let dateSpan1 = hit1.dateSpan - let ms = [ - dateSpan0.range.start, - dateSpan0.range.end, - dateSpan1.range.start, - dateSpan1.range.end, - ] - - ms.sort(compareNumbers) - - let props = {} as DateSpan - - for (let transformer of dateSelectionTransformers) { - let res = transformer(hit0, hit1) - - if (res === false) { - return null - } - - if (res) { - __assign(props, res) - } - } - - props.range = { start: ms[0], end: ms[3] } - props.allDay = dateSpan0.allDay - - return props -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventDragging.ts deleted file mode 100644 index 9a9ecfc49..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventDragging.ts +++ /dev/null @@ -1,482 +0,0 @@ -import { - DateComponent, Seg, - PointerDragEvent, Hit, - EventMutation, applyMutationToEventStore, - startOfDay, - elementClosest, - EventStore, getRelevantEvents, createEmptyEventStore, - EventInteractionState, - diffDates, enableCursor, disableCursor, - EventRenderRange, getElSeg, - EventApi, - eventDragMutationMassager, - Interaction, InteractionSettings, interactionSettingsStore, - EventDropTransformers, - CalendarContext, - ViewApi, - EventChangeArg, - buildEventApis, - EventAddArg, - EventRemoveArg, - isInteractionValid, - getElRoot, -} from '@fullcalendar/common' -import { __assign } from 'tslib' -import { HitDragging, isHitsEqual } from './HitDragging' -import { FeaturefulElementDragging } from '../dnd/FeaturefulElementDragging' -import { buildDatePointApiWithContext } from '../utils' - -export type EventDragStopArg = EventDragArg -export type EventDragStartArg = EventDragArg - -export interface EventDragArg { - el: HTMLElement - event: EventApi - jsEvent: MouseEvent - view: ViewApi -} - -export class EventDragging extends Interaction { // TODO: rename to EventSelectingAndDragging - // TODO: test this in IE11 - // QUESTION: why do we need it on the resizable??? - static SELECTOR = '.fc-event-draggable, .fc-event-resizable' - - dragging: FeaturefulElementDragging - hitDragging: HitDragging - - // internal state - subjectEl: HTMLElement | null = null - subjectSeg: Seg | null = null // the seg being selected/dragged - isDragging: boolean = false - eventRange: EventRenderRange | null = null - relevantEvents: EventStore | null = null // the events being dragged - receivingContext: CalendarContext | null = null - validMutation: EventMutation | null = null - mutatedRelevantEvents: EventStore | null = null - - constructor(settings: InteractionSettings) { - super(settings) - let { component } = this - let { options } = component.context - - let dragging = this.dragging = new FeaturefulElementDragging(settings.el) - dragging.pointer.selector = EventDragging.SELECTOR - dragging.touchScrollAllowed = false - dragging.autoScroller.isEnabled = options.dragScroll - - let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsStore) - hitDragging.useSubjectCenter = settings.useEventCenter - hitDragging.emitter.on('pointerdown', this.handlePointerDown) - hitDragging.emitter.on('dragstart', this.handleDragStart) - hitDragging.emitter.on('hitupdate', this.handleHitUpdate) - hitDragging.emitter.on('pointerup', this.handlePointerUp) - hitDragging.emitter.on('dragend', this.handleDragEnd) - } - - destroy() { - this.dragging.destroy() - } - - handlePointerDown = (ev: PointerDragEvent) => { - let origTarget = ev.origEvent.target as HTMLElement - let { component, dragging } = this - let { mirror } = dragging - let { options } = component.context - let initialContext = component.context - this.subjectEl = ev.subjectEl as HTMLElement - let subjectSeg = this.subjectSeg = getElSeg(ev.subjectEl as HTMLElement)! - let eventRange = this.eventRange = subjectSeg.eventRange! - let eventInstanceId = eventRange.instance!.instanceId - - this.relevantEvents = getRelevantEvents( - initialContext.getCurrentData().eventStore, - eventInstanceId, - ) - - dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance - dragging.delay = - // only do a touch delay if touch and this event hasn't been selected yet - (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? - getComponentTouchDelay(component) : - null - - if (options.fixedMirrorParent) { - mirror.parentNode = options.fixedMirrorParent - } else { - mirror.parentNode = elementClosest(origTarget, '.fc') - } - - mirror.revertDuration = options.dragRevertDuration - - let isValid = - component.isValidSegDownEl(origTarget) && - !elementClosest(origTarget, '.fc-event-resizer') // NOT on a resizer - - dragging.setIgnoreMove(!isValid) - - // disable dragging for elements that are resizable (ie, selectable) - // but are not draggable - this.isDragging = isValid && - (ev.subjectEl as HTMLElement).classList.contains('fc-event-draggable') - } - - handleDragStart = (ev: PointerDragEvent) => { - let initialContext = this.component.context - let eventRange = this.eventRange! - let eventInstanceId = eventRange.instance.instanceId - - if (ev.isTouch) { - // need to select a different event? - if (eventInstanceId !== this.component.props.eventSelection) { - initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId }) - } - } else { - // if now using mouse, but was previous touch interaction, clear selected event - initialContext.dispatch({ type: 'UNSELECT_EVENT' }) - } - - if (this.isDragging) { - initialContext.calendarApi.unselect(ev) // unselect *date* selection - initialContext.emitter.trigger('eventDragStart', { - el: this.subjectEl, - event: new EventApi(initialContext, eventRange.def, eventRange.instance), - jsEvent: ev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: initialContext.viewApi, - } as EventDragStartArg) - } - } - - handleHitUpdate = (hit: Hit | null, isFinal: boolean) => { - if (!this.isDragging) { - return - } - - let relevantEvents = this.relevantEvents! - let initialHit = this.hitDragging.initialHit! - let initialContext = this.component.context - - // states based on new hit - let receivingContext: CalendarContext | null = null - let mutation: EventMutation | null = null - let mutatedRelevantEvents: EventStore | null = null - let isInvalid = false - let interaction: EventInteractionState = { - affectedEvents: relevantEvents, - mutatedEvents: createEmptyEventStore(), - isEvent: true, - } - - if (hit) { - receivingContext = hit.context - let receivingOptions = receivingContext.options - - if ( - initialContext === receivingContext || - (receivingOptions.editable && receivingOptions.droppable) - ) { - mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers) - - if (mutation) { - mutatedRelevantEvents = applyMutationToEventStore( - relevantEvents, - receivingContext.getCurrentData().eventUiBases, - mutation, - receivingContext, - ) - interaction.mutatedEvents = mutatedRelevantEvents - - if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) { - isInvalid = true - mutation = null - mutatedRelevantEvents = null - interaction.mutatedEvents = createEmptyEventStore() - } - } - } else { - receivingContext = null - } - } - - this.displayDrag(receivingContext, interaction) - - if (!isInvalid) { - enableCursor() - } else { - disableCursor() - } - - if (!isFinal) { - if ( - initialContext === receivingContext && // TODO: write test for this - isHitsEqual(initialHit, hit) - ) { - mutation = null - } - - this.dragging.setMirrorNeedsRevert(!mutation) - - // render the mirror if no already-rendered mirror - // TODO: wish we could somehow wait for dispatch to guarantee render - this.dragging.setMirrorIsVisible( - !hit || !getElRoot(this.subjectEl).querySelector('.fc-event-mirror'), // TODO: turn className into constant - ) - - // assign states based on new hit - this.receivingContext = receivingContext - this.validMutation = mutation - this.mutatedRelevantEvents = mutatedRelevantEvents - } - } - - handlePointerUp = () => { - if (!this.isDragging) { - this.cleanup() // because handleDragEnd won't fire - } - } - - handleDragEnd = (ev: PointerDragEvent) => { - if (this.isDragging) { - let initialContext = this.component.context - let initialView = initialContext.viewApi - let { receivingContext, validMutation } = this - let eventDef = this.eventRange!.def - let eventInstance = this.eventRange!.instance - let eventApi = new EventApi(initialContext, eventDef, eventInstance) - let relevantEvents = this.relevantEvents! - let mutatedRelevantEvents = this.mutatedRelevantEvents! - let { finalHit } = this.hitDragging - - this.clearDrag() // must happen after revert animation - - initialContext.emitter.trigger('eventDragStop', { - el: this.subjectEl, - event: eventApi, - jsEvent: ev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: initialView, - } as EventDragStopArg) - - if (validMutation) { - // dropped within same calendar - if (receivingContext === initialContext) { - let updatedEventApi = new EventApi( - initialContext, - mutatedRelevantEvents.defs[eventDef.defId], - eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null, - ) - - initialContext.dispatch({ - type: 'MERGE_EVENTS', - eventStore: mutatedRelevantEvents, - }) - - let eventChangeArg: EventChangeArg = { - oldEvent: eventApi, - event: updatedEventApi, - relatedEvents: buildEventApis(mutatedRelevantEvents, initialContext, eventInstance), - revert() { - initialContext.dispatch({ - type: 'MERGE_EVENTS', - eventStore: relevantEvents, // the pre-change data - }) - }, - } - - let transformed: ReturnType = {} - for (let transformer of initialContext.getCurrentData().pluginHooks.eventDropTransformers) { - __assign(transformed, transformer(validMutation, initialContext)) - } - - initialContext.emitter.trigger('eventDrop', { - ...eventChangeArg, - ...transformed, - el: ev.subjectEl as HTMLElement, - delta: validMutation.datesDelta!, - jsEvent: ev.origEvent as MouseEvent, // bad - view: initialView, - }) - - initialContext.emitter.trigger('eventChange', eventChangeArg) - - // dropped in different calendar - } else if (receivingContext) { - let eventRemoveArg: EventRemoveArg = { - event: eventApi, - relatedEvents: buildEventApis(relevantEvents, initialContext, eventInstance), - revert() { - initialContext.dispatch({ - type: 'MERGE_EVENTS', - eventStore: relevantEvents, - }) - }, - } - - initialContext.emitter.trigger('eventLeave', { - ...eventRemoveArg, - draggedEl: ev.subjectEl as HTMLElement, - view: initialView, - }) - - initialContext.dispatch({ - type: 'REMOVE_EVENTS', - eventStore: relevantEvents, - }) - - initialContext.emitter.trigger('eventRemove', eventRemoveArg) - - let addedEventDef = mutatedRelevantEvents.defs[eventDef.defId] - let addedEventInstance = mutatedRelevantEvents.instances[eventInstance.instanceId] - let addedEventApi = new EventApi(receivingContext, addedEventDef, addedEventInstance) - - receivingContext.dispatch({ - type: 'MERGE_EVENTS', - eventStore: mutatedRelevantEvents, - }) - - let eventAddArg: EventAddArg = { - event: addedEventApi, - relatedEvents: buildEventApis(mutatedRelevantEvents, receivingContext, addedEventInstance), - revert() { - receivingContext.dispatch({ - type: 'REMOVE_EVENTS', - eventStore: mutatedRelevantEvents, - }) - }, - } - - receivingContext.emitter.trigger('eventAdd', eventAddArg) - - if (ev.isTouch) { - receivingContext.dispatch({ - type: 'SELECT_EVENT', - eventInstanceId: eventInstance.instanceId, - }) - } - - receivingContext.emitter.trigger('drop', { - ...buildDatePointApiWithContext(finalHit.dateSpan, receivingContext), - draggedEl: ev.subjectEl as HTMLElement, - jsEvent: ev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: finalHit.context.viewApi, - }) - - receivingContext.emitter.trigger('eventReceive', { - ...eventAddArg, - draggedEl: ev.subjectEl as HTMLElement, - view: finalHit.context.viewApi, - }) - } - } else { - initialContext.emitter.trigger('_noEventDrop') - } - } - - this.cleanup() - } - - // render a drag state on the next receivingCalendar - displayDrag(nextContext: CalendarContext | null, state: EventInteractionState) { - let initialContext = this.component.context - let prevContext = this.receivingContext - - // does the previous calendar need to be cleared? - if (prevContext && prevContext !== nextContext) { - // does the initial calendar need to be cleared? - // if so, don't clear all the way. we still need to to hide the affectedEvents - if (prevContext === initialContext) { - prevContext.dispatch({ - type: 'SET_EVENT_DRAG', - state: { - affectedEvents: state.affectedEvents, - mutatedEvents: createEmptyEventStore(), - isEvent: true, - }, - }) - - // completely clear the old calendar if it wasn't the initial - } else { - prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }) - } - } - - if (nextContext) { - nextContext.dispatch({ type: 'SET_EVENT_DRAG', state }) - } - } - - clearDrag() { - let initialCalendar = this.component.context - let { receivingContext } = this - - if (receivingContext) { - receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }) - } - - // the initial calendar might have an dummy drag state from displayDrag - if (initialCalendar !== receivingContext) { - initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }) - } - } - - cleanup() { // reset all internal state - this.subjectSeg = null - this.isDragging = false - this.eventRange = null - this.relevantEvents = null - this.receivingContext = null - this.validMutation = null - this.mutatedRelevantEvents = null - } -} - -function computeEventMutation(hit0: Hit, hit1: Hit, massagers: eventDragMutationMassager[]): EventMutation { - let dateSpan0 = hit0.dateSpan - let dateSpan1 = hit1.dateSpan - let date0 = dateSpan0.range.start - let date1 = dateSpan1.range.start - let standardProps = {} as any - - if (dateSpan0.allDay !== dateSpan1.allDay) { - standardProps.allDay = dateSpan1.allDay - standardProps.hasEnd = hit1.context.options.allDayMaintainDuration - - if (dateSpan1.allDay) { - // means date1 is already start-of-day, - // but date0 needs to be converted - date0 = startOfDay(date0) - } - } - - let delta = diffDates( - date0, date1, - hit0.context.dateEnv, - hit0.componentId === hit1.componentId ? - hit0.largeUnit : - null, - ) - - if (delta.milliseconds) { // has hours/minutes/seconds - standardProps.allDay = false - } - - let mutation: EventMutation = { - datesDelta: delta, - standardProps, - } - - for (let massager of massagers) { - massager(mutation, hit0, hit1) - } - - return mutation -} - -function getComponentTouchDelay(component: DateComponent): number | null { - let { options } = component.context - let delay = options.eventLongPressDelay - - if (delay == null) { - delay = options.longPressDelay - } - - return delay -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventResizing.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventResizing.ts deleted file mode 100644 index 013b399ae..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/EventResizing.ts +++ /dev/null @@ -1,263 +0,0 @@ -import { - Seg, Hit, - EventMutation, applyMutationToEventStore, - elementClosest, - PointerDragEvent, - EventStore, getRelevantEvents, createEmptyEventStore, - diffDates, enableCursor, disableCursor, - DateRange, - EventApi, - EventRenderRange, getElSeg, - createDuration, - EventInteractionState, - Interaction, InteractionSettings, interactionSettingsToStore, ViewApi, Duration, EventChangeArg, buildEventApis, isInteractionValid, -} from '@fullcalendar/common' -import { __assign } from 'tslib' -import { HitDragging, isHitsEqual } from './HitDragging' -import { FeaturefulElementDragging } from '../dnd/FeaturefulElementDragging' - -export type EventResizeStartArg = EventResizeStartStopArg -export type EventResizeStopArg = EventResizeStartStopArg - -export interface EventResizeStartStopArg { - el: HTMLElement - event: EventApi - jsEvent: MouseEvent - view: ViewApi -} - -export interface EventResizeDoneArg extends EventChangeArg { - el: HTMLElement - startDelta: Duration - endDelta: Duration - jsEvent: MouseEvent - view: ViewApi -} - -export class EventResizing extends Interaction { - dragging: FeaturefulElementDragging - hitDragging: HitDragging - - // internal state - draggingSegEl: HTMLElement | null = null - draggingSeg: Seg | null = null // TODO: rename to resizingSeg? subjectSeg? - eventRange: EventRenderRange | null = null - relevantEvents: EventStore | null = null - validMutation: EventMutation | null = null - mutatedRelevantEvents: EventStore | null = null - - constructor(settings: InteractionSettings) { - super(settings) - let { component } = settings - - let dragging = this.dragging = new FeaturefulElementDragging(settings.el) - dragging.pointer.selector = '.fc-event-resizer' - dragging.touchScrollAllowed = false - dragging.autoScroller.isEnabled = component.context.options.dragScroll - - let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings)) - hitDragging.emitter.on('pointerdown', this.handlePointerDown) - hitDragging.emitter.on('dragstart', this.handleDragStart) - hitDragging.emitter.on('hitupdate', this.handleHitUpdate) - hitDragging.emitter.on('dragend', this.handleDragEnd) - } - - destroy() { - this.dragging.destroy() - } - - handlePointerDown = (ev: PointerDragEvent) => { - let { component } = this - let segEl = this.querySegEl(ev) - let seg = getElSeg(segEl) - let eventRange = this.eventRange = seg.eventRange! - - this.dragging.minDistance = component.context.options.eventDragMinDistance - - // if touch, need to be working with a selected event - this.dragging.setIgnoreMove( - !this.component.isValidSegDownEl(ev.origEvent.target as HTMLElement) || - (ev.isTouch && this.component.props.eventSelection !== eventRange.instance!.instanceId), - ) - } - - handleDragStart = (ev: PointerDragEvent) => { - let { context } = this.component - let eventRange = this.eventRange! - - this.relevantEvents = getRelevantEvents( - context.getCurrentData().eventStore, - this.eventRange.instance!.instanceId, - ) - - let segEl = this.querySegEl(ev) - this.draggingSegEl = segEl - this.draggingSeg = getElSeg(segEl) - - context.calendarApi.unselect() - context.emitter.trigger('eventResizeStart', { - el: segEl, - event: new EventApi(context, eventRange.def, eventRange.instance), - jsEvent: ev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: context.viewApi, - } as EventResizeStartArg) - } - - handleHitUpdate = (hit: Hit | null, isFinal: boolean, ev: PointerDragEvent) => { - let { context } = this.component - let relevantEvents = this.relevantEvents! - let initialHit = this.hitDragging.initialHit! - let eventInstance = this.eventRange.instance! - let mutation: EventMutation | null = null - let mutatedRelevantEvents: EventStore | null = null - let isInvalid = false - let interaction: EventInteractionState = { - affectedEvents: relevantEvents, - mutatedEvents: createEmptyEventStore(), - isEvent: true, - } - - if (hit) { - let disallowed = hit.componentId === initialHit.componentId - && this.isHitComboAllowed - && !this.isHitComboAllowed(initialHit, hit) - - if (!disallowed) { - mutation = computeMutation( - initialHit, - hit, - (ev.subjectEl as HTMLElement).classList.contains('fc-event-resizer-start'), - eventInstance.range, - ) - } - } - - if (mutation) { - mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context) - interaction.mutatedEvents = mutatedRelevantEvents - - if (!isInteractionValid(interaction, hit.dateProfile, context)) { - isInvalid = true - mutation = null - mutatedRelevantEvents = null - interaction.mutatedEvents = null - } - } - - if (mutatedRelevantEvents) { - context.dispatch({ - type: 'SET_EVENT_RESIZE', - state: interaction, - }) - } else { - context.dispatch({ type: 'UNSET_EVENT_RESIZE' }) - } - - if (!isInvalid) { - enableCursor() - } else { - disableCursor() - } - - if (!isFinal) { - if (mutation && isHitsEqual(initialHit, hit)) { - mutation = null - } - - this.validMutation = mutation - this.mutatedRelevantEvents = mutatedRelevantEvents - } - } - - handleDragEnd = (ev: PointerDragEvent) => { - let { context } = this.component - let eventDef = this.eventRange!.def - let eventInstance = this.eventRange!.instance - let eventApi = new EventApi(context, eventDef, eventInstance) - let relevantEvents = this.relevantEvents! - let mutatedRelevantEvents = this.mutatedRelevantEvents! - - context.emitter.trigger('eventResizeStop', { - el: this.draggingSegEl, - event: eventApi, - jsEvent: ev.origEvent as MouseEvent, // Is this always a mouse event? See #4655 - view: context.viewApi, - } as EventResizeStopArg) - - if (this.validMutation) { - let updatedEventApi = new EventApi( - context, - mutatedRelevantEvents.defs[eventDef.defId], - eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null, - ) - - context.dispatch({ - type: 'MERGE_EVENTS', - eventStore: mutatedRelevantEvents, - }) - - let eventChangeArg: EventChangeArg = { - oldEvent: eventApi, - event: updatedEventApi, - relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance), - revert() { - context.dispatch({ - type: 'MERGE_EVENTS', - eventStore: relevantEvents, // the pre-change events - }) - }, - } - - context.emitter.trigger('eventResize', { - ...eventChangeArg, - el: this.draggingSegEl, - startDelta: this.validMutation.startDelta || createDuration(0), - endDelta: this.validMutation.endDelta || createDuration(0), - jsEvent: ev.origEvent as MouseEvent, - view: context.viewApi, - }) - - context.emitter.trigger('eventChange', eventChangeArg) - } else { - context.emitter.trigger('_noEventResize') - } - - // reset all internal state - this.draggingSeg = null - this.relevantEvents = null - this.validMutation = null - - // okay to keep eventInstance around. useful to set it in handlePointerDown - } - - querySegEl(ev: PointerDragEvent) { - return elementClosest(ev.subjectEl as HTMLElement, '.fc-event') - } -} - -function computeMutation( - hit0: Hit, - hit1: Hit, - isFromStart: boolean, - instanceRange: DateRange, -): EventMutation | null { - let dateEnv = hit0.context.dateEnv - let date0 = hit0.dateSpan.range.start - let date1 = hit1.dateSpan.range.start - - let delta = diffDates( - date0, date1, - dateEnv, - hit0.largeUnit, - ) - - if (isFromStart) { - if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { - return { startDelta: delta } - } - } else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { - return { endDelta: delta } - } - - return null -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/HitDragging.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/HitDragging.ts deleted file mode 100644 index d0a329e9c..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/HitDragging.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { - Emitter, PointerDragEvent, - isDateSpansEqual, - computeRect, - constrainPoint, intersectRects, getRectCenter, diffPoints, Point, - rangeContainsRange, - Hit, - InteractionSettingsStore, - mapHash, - ElementDragging, -} from '@fullcalendar/common' -import { OffsetTracker } from '../OffsetTracker' - -/* -Tracks movement over multiple droppable areas (aka "hits") -that exist in one or more DateComponents. -Relies on an existing draggable. - -emits: -- pointerdown -- dragstart -- hitchange - fires initially, even if not over a hit -- pointerup -- (hitchange - again, to null, if ended over a hit) -- dragend -*/ -export class HitDragging { - droppableStore: InteractionSettingsStore - dragging: ElementDragging - emitter: Emitter - - // options that can be set by caller - useSubjectCenter: boolean = false - requireInitial: boolean = true // if doesn't start out on a hit, won't emit any events - - // internal state - offsetTrackers: { [componentUid: string]: OffsetTracker } - initialHit: Hit | null = null - movingHit: Hit | null = null - finalHit: Hit | null = null // won't ever be populated if shouldIgnoreMove - coordAdjust?: Point - - constructor(dragging: ElementDragging, droppableStore: InteractionSettingsStore) { - this.droppableStore = droppableStore - - dragging.emitter.on('pointerdown', this.handlePointerDown) - dragging.emitter.on('dragstart', this.handleDragStart) - dragging.emitter.on('dragmove', this.handleDragMove) - dragging.emitter.on('pointerup', this.handlePointerUp) - dragging.emitter.on('dragend', this.handleDragEnd) - - this.dragging = dragging - this.emitter = new Emitter() - } - - handlePointerDown = (ev: PointerDragEvent) => { - let { dragging } = this - - this.initialHit = null - this.movingHit = null - this.finalHit = null - - this.prepareHits() - this.processFirstCoord(ev) - - if (this.initialHit || !this.requireInitial) { - dragging.setIgnoreMove(false) - - // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( - this.emitter.trigger('pointerdown', ev) - } else { - dragging.setIgnoreMove(true) - } - } - - // sets initialHit - // sets coordAdjust - processFirstCoord(ev: PointerDragEvent) { - let origPoint = { left: ev.pageX, top: ev.pageY } - let adjustedPoint = origPoint - let subjectEl = ev.subjectEl - let subjectRect - - if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot - subjectRect = computeRect(subjectEl) - adjustedPoint = constrainPoint(adjustedPoint, subjectRect) - } - - let initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top) - if (initialHit) { - if (this.useSubjectCenter && subjectRect) { - let slicedSubjectRect = intersectRects(subjectRect, initialHit.rect) - if (slicedSubjectRect) { - adjustedPoint = getRectCenter(slicedSubjectRect) - } - } - - this.coordAdjust = diffPoints(adjustedPoint, origPoint) - } else { - this.coordAdjust = { left: 0, top: 0 } - } - } - - handleDragStart = (ev: PointerDragEvent) => { - this.emitter.trigger('dragstart', ev) - this.handleMove(ev, true) // force = fire even if initially null - } - - handleDragMove = (ev: PointerDragEvent) => { - this.emitter.trigger('dragmove', ev) - this.handleMove(ev) - } - - handlePointerUp = (ev: PointerDragEvent) => { - this.releaseHits() - this.emitter.trigger('pointerup', ev) - } - - handleDragEnd = (ev: PointerDragEvent) => { - if (this.movingHit) { - this.emitter.trigger('hitupdate', null, true, ev) - } - - this.finalHit = this.movingHit - this.movingHit = null - this.emitter.trigger('dragend', ev) - } - - handleMove(ev: PointerDragEvent, forceHandle?: boolean) { - let hit = this.queryHitForOffset( - ev.pageX + this.coordAdjust!.left, - ev.pageY + this.coordAdjust!.top, - ) - - if (forceHandle || !isHitsEqual(this.movingHit, hit)) { - this.movingHit = hit - this.emitter.trigger('hitupdate', hit, false, ev) - } - } - - prepareHits() { - this.offsetTrackers = mapHash(this.droppableStore, (interactionSettings) => { - interactionSettings.component.prepareHits() - return new OffsetTracker(interactionSettings.el) - }) - } - - releaseHits() { - let { offsetTrackers } = this - - for (let id in offsetTrackers) { - offsetTrackers[id].destroy() - } - - this.offsetTrackers = {} - } - - queryHitForOffset(offsetLeft: number, offsetTop: number): Hit | null { - let { droppableStore, offsetTrackers } = this - let bestHit: Hit | null = null - - for (let id in droppableStore) { - let component = droppableStore[id].component - let offsetTracker = offsetTrackers[id] - - if ( - offsetTracker && // wasn't destroyed mid-drag - offsetTracker.isWithinClipping(offsetLeft, offsetTop) - ) { - let originLeft = offsetTracker.computeLeft() - let originTop = offsetTracker.computeTop() - let positionLeft = offsetLeft - originLeft - let positionTop = offsetTop - originTop - let { origRect } = offsetTracker - let width = origRect.right - origRect.left - let height = origRect.bottom - origRect.top - - if ( - // must be within the element's bounds - positionLeft >= 0 && positionLeft < width && - positionTop >= 0 && positionTop < height - ) { - let hit = component.queryHit(positionLeft, positionTop, width, height) - if ( - hit && ( - // make sure the hit is within activeRange, meaning it's not a dead cell - rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range) - ) && - (!bestHit || hit.layer > bestHit.layer) - ) { - hit.componentId = id - hit.context = component.context - - // TODO: better way to re-orient rectangle - hit.rect.left += originLeft - hit.rect.right += originLeft - hit.rect.top += originTop - hit.rect.bottom += originTop - - bestHit = hit - } - } - } - } - - return bestHit - } -} - -export function isHitsEqual(hit0: Hit | null, hit1: Hit | null): boolean { - if (!hit0 && !hit1) { - return true - } - - if (Boolean(hit0) !== Boolean(hit1)) { - return false - } - - return isDateSpansEqual(hit0!.dateSpan, hit1!.dateSpan) -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/UnselectAuto.ts b/apps/schoolCalendar/fullcalendar/interaction/src/interactions/UnselectAuto.ts deleted file mode 100644 index 23e5b47cb..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/interactions/UnselectAuto.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { - DateSelectionApi, - PointerDragEvent, - elementClosest, - CalendarContext, - getEventTargetViaRoot, -} from '@fullcalendar/common' -import { PointerDragging } from '../dnd/PointerDragging' -import { EventDragging } from './EventDragging' - -export class UnselectAuto { - documentPointer: PointerDragging // for unfocusing - isRecentPointerDateSelect = false // wish we could use a selector to detect date selection, but uses hit system - matchesCancel = false - matchesEvent = false - - constructor(private context: CalendarContext) { - let documentPointer = this.documentPointer = new PointerDragging(document) - documentPointer.shouldIgnoreMove = true - documentPointer.shouldWatchScroll = false - documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown) - documentPointer.emitter.on('pointerup', this.onDocumentPointerUp) - - /* - TODO: better way to know about whether there was a selection with the pointer - */ - context.emitter.on('select', this.onSelect) - } - - destroy() { - this.context.emitter.off('select', this.onSelect) - this.documentPointer.destroy() - } - - onSelect = (selectInfo: DateSelectionApi) => { - if (selectInfo.jsEvent) { - this.isRecentPointerDateSelect = true - } - } - - onDocumentPointerDown = (pev: PointerDragEvent) => { - let unselectCancel = this.context.options.unselectCancel - let downEl = getEventTargetViaRoot(pev.origEvent) as HTMLElement - - this.matchesCancel = !!elementClosest(downEl, unselectCancel) - this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR) // interaction started on an event? - } - - onDocumentPointerUp = (pev: PointerDragEvent) => { - let { context } = this - let { documentPointer } = this - let calendarState = context.getCurrentData() - - // touch-scrolling should never unfocus any type of selection - if (!documentPointer.wasTouchScroll) { - if ( - calendarState.dateSelection && // an existing date selection? - !this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? - ) { - let unselectAuto = context.options.unselectAuto - - if (unselectAuto && (!unselectAuto || !this.matchesCancel)) { - context.calendarApi.unselect(pev) - } - } - - if ( - calendarState.eventSelection && // an existing event selected? - !this.matchesEvent // interaction DIDN'T start on an event - ) { - context.dispatch({ type: 'UNSELECT_EVENT' }) - } - } - - this.isRecentPointerDateSelect = false - } -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/main.global.ts b/apps/schoolCalendar/fullcalendar/interaction/src/main.global.ts deleted file mode 100644 index 0af579774..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/main.global.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { globalPlugins } from '@fullcalendar/common' -import plugin from './main' - -globalPlugins.push(plugin) - -export default plugin -export * from './main' diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/main.ts b/apps/schoolCalendar/fullcalendar/interaction/src/main.ts deleted file mode 100644 index f57049ca3..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/main.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createPlugin } from '@fullcalendar/common' -import { DateClicking } from './interactions/DateClicking' -import { DateSelecting } from './interactions/DateSelecting' -import { EventDragging } from './interactions/EventDragging' -import { EventResizing } from './interactions/EventResizing' -import { UnselectAuto } from './interactions/UnselectAuto' -import { FeaturefulElementDragging } from './dnd/FeaturefulElementDragging' -import { OPTION_REFINERS, LISTENER_REFINERS } from './options' -import './options-declare' - -export default createPlugin({ - componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing], - calendarInteractions: [UnselectAuto], - elementDraggingImpl: FeaturefulElementDragging, - optionRefiners: OPTION_REFINERS, - listenerRefiners: LISTENER_REFINERS, -}) - -export * from './api-type-deps' -export { FeaturefulElementDragging } -export { PointerDragging } from './dnd/PointerDragging' -export { ExternalDraggable as Draggable } from './interactions-external/ExternalDraggable' -export { ThirdPartyDraggable } from './interactions-external/ThirdPartyDraggable' diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/options-declare.ts b/apps/schoolCalendar/fullcalendar/interaction/src/options-declare.ts deleted file mode 100644 index 9cbc5a4a8..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/options-declare.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { OPTION_REFINERS, LISTENER_REFINERS } from './options' - -type ExtraOptionRefiners = typeof OPTION_REFINERS -type ExtraListenerRefiners = typeof LISTENER_REFINERS - -declare module '@fullcalendar/common' { - interface BaseOptionRefiners extends ExtraOptionRefiners {} - interface CalendarListenerRefiners extends ExtraListenerRefiners {} -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/options.ts b/apps/schoolCalendar/fullcalendar/interaction/src/options.ts deleted file mode 100644 index a11ce5399..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/options.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { identity, Identity, EventDropArg } from '@fullcalendar/common' - -// public -import { - DateClickArg, - EventDragStartArg, EventDragStopArg, - EventResizeStartArg, EventResizeStopArg, EventResizeDoneArg, - DropArg, EventReceiveArg, EventLeaveArg, -} from './api-type-deps' - -export const OPTION_REFINERS = { - fixedMirrorParent: identity as Identity, -} - -export const LISTENER_REFINERS = { - dateClick: identity as Identity<(arg: DateClickArg) => void>, - eventDragStart: identity as Identity<(arg: EventDragStartArg) => void>, - eventDragStop: identity as Identity<(arg: EventDragStopArg) => void>, - eventDrop: identity as Identity<(arg: EventDropArg) => void>, - eventResizeStart: identity as Identity<(arg: EventResizeStartArg) => void>, - eventResizeStop: identity as Identity<(arg: EventResizeStopArg) => void>, - eventResize: identity as Identity<(arg: EventResizeDoneArg) => void>, - drop: identity as Identity<(arg: DropArg) => void>, - eventReceive: identity as Identity<(arg: EventReceiveArg) => void>, - eventLeave: identity as Identity<(arg: EventLeaveArg) => void>, -} diff --git a/apps/schoolCalendar/fullcalendar/interaction/src/utils.ts b/apps/schoolCalendar/fullcalendar/interaction/src/utils.ts deleted file mode 100644 index 056a0040d..000000000 --- a/apps/schoolCalendar/fullcalendar/interaction/src/utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { DateSpan, CalendarContext, DatePointApi, DateEnv, ViewApi, EventApi } from '@fullcalendar/common' -import { __assign } from 'tslib' - -export interface DropArg extends DatePointApi { - draggedEl: HTMLElement - jsEvent: MouseEvent - view: ViewApi -} - -export type EventReceiveArg = EventReceiveLeaveArg -export type EventLeaveArg = EventReceiveLeaveArg -export interface EventReceiveLeaveArg { // will this become public? - draggedEl: HTMLElement - event: EventApi - relatedEvents: EventApi[] - revert: () => void - view: ViewApi -} - -export function buildDatePointApiWithContext(dateSpan: DateSpan, context: CalendarContext) { - let props = {} as DatePointApi - - for (let transform of context.pluginHooks.datePointTransforms) { - __assign(props, transform(dateSpan, context)) - } - - __assign(props, buildDatePointApi(dateSpan, context.dateEnv)) - - return props -} - -export function buildDatePointApi(span: DateSpan, dateEnv: DateEnv): DatePointApi { - return { - date: dateEnv.toDate(span.range.start), - dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), - allDay: span.allDay, - } -}