@fullcalendar/scrollgrid
Advanced tools
Comparing version 7.0.0-beta.0 to 7.0.0-beta.1
/*! | ||
FullCalendar ScrollGrid Plugin v7.0.0-beta.0 | ||
FullCalendar ScrollGrid Plugin v7.0.0-beta.1 | ||
Docs & License: https://fullcalendar.io/docs/premium | ||
@@ -13,156 +13,70 @@ (c) 2024 Adam Shaw | ||
const WHEEL_EVENT_NAMES = 'wheel mousewheel DomMouseScroll MozMousePixelScroll'.split(' '); | ||
/* | ||
ALSO, with the ability to disable touch | ||
Fires: | ||
- scrollEnd: (x, y) => void | ||
*/ | ||
class ScrollListener { | ||
constructor(el) { | ||
this.el = el; | ||
this.emitter = new internal$1.Emitter(); | ||
this.isScrolling = false; | ||
this.isTouching = false; // user currently has finger down? | ||
this.isRecentlyWheeled = false; | ||
this.isRecentlyScrolled = false; | ||
this.wheelWaiter = new internal$1.DelayedRunner(this._handleWheelWaited.bind(this)); | ||
this.scrollWaiter = new internal$1.DelayedRunner(this._handleScrollWaited.bind(this)); | ||
// Handlers | ||
// ---------------------------------------------------------------------------------------------- | ||
this.handleScroll = () => { | ||
this.startScroll(); | ||
this.emitter.trigger('scroll', this.isRecentlyWheeled, this.isTouching); | ||
this.isRecentlyScrolled = true; | ||
this.scrollWaiter.request(500); | ||
}; | ||
// will fire *before* the scroll event is fired (might not cause a scroll) | ||
this.handleWheel = () => { | ||
this.isRecentlyWheeled = true; | ||
this.wheelWaiter.request(500); | ||
}; | ||
// will fire *before* the scroll event is fired (might not cause a scroll) | ||
this.handleTouchStart = () => { | ||
this.isTouching = true; | ||
}; | ||
this.handleTouchEnd = () => { | ||
this.isTouching = false; | ||
// if the user ended their touch, and the scroll area wasn't moving, | ||
// we consider this to be the end of the scroll. | ||
if (!this.isRecentlyScrolled) { | ||
this.endScroll(); // won't fire if already ended | ||
} | ||
}; | ||
el.addEventListener('scroll', this.handleScroll); | ||
el.addEventListener('touchstart', this.handleTouchStart, { passive: true }); | ||
el.addEventListener('touchend', this.handleTouchEnd); | ||
for (let eventName of WHEEL_EVENT_NAMES) { | ||
el.addEventListener(eventName, this.handleWheel, { passive: true }); | ||
} | ||
} | ||
destroy() { | ||
let { el } = this; | ||
el.removeEventListener('scroll', this.handleScroll); | ||
el.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); | ||
el.removeEventListener('touchend', this.handleTouchEnd); | ||
for (let eventName of WHEEL_EVENT_NAMES) { | ||
el.removeEventListener(eventName, this.handleWheel, { passive: true }); | ||
} | ||
} | ||
// Start / Stop | ||
// ---------------------------------------------------------------------------------------------- | ||
startScroll() { | ||
if (!this.isScrolling) { | ||
this.isScrolling = true; | ||
this.emitter.trigger('scrollStart', this.isRecentlyWheeled, this.isTouching); | ||
} | ||
} | ||
endScroll() { | ||
if (this.isScrolling) { | ||
this.emitter.trigger('scrollEnd'); | ||
this.isScrolling = false; | ||
this.isRecentlyScrolled = true; | ||
this.isRecentlyWheeled = false; | ||
this.scrollWaiter.clear(); | ||
this.wheelWaiter.clear(); | ||
} | ||
} | ||
_handleScrollWaited() { | ||
this.isRecentlyScrolled = false; | ||
// only end the scroll if not currently touching. | ||
// if touching, the scrolling will end later, on touchend. | ||
if (!this.isTouching) { | ||
this.endScroll(); // won't fire if already ended | ||
} | ||
} | ||
_handleWheelWaited() { | ||
this.isRecentlyWheeled = false; | ||
} | ||
} | ||
class ScrollerSyncer { | ||
constructor(isHorizontal = false) { | ||
this.isHorizontal = isHorizontal; | ||
this.scrollers = []; // TODO: move away from requiring Scroller | ||
this.scrollListeners = []; | ||
this.emitter = new internal$1.Emitter(); | ||
this.scrollers = []; | ||
this.destroyFuncs = []; | ||
this.isPaused = false; | ||
} | ||
handleChildren(scrollers, isRtl) { | ||
handleChildren(scrollers) { | ||
if (!internal$1.isArraysEqual(this.scrollers, scrollers)) { | ||
this.destroy(); | ||
this.scrollers = scrollers; | ||
const scrollListeners = []; | ||
for (const scroller of scrollers) { | ||
if (scroller) { // could be null | ||
scrollListeners.push(this.bindScroller(scroller.el)); | ||
this.destroyFuncs.push(this.bindScroller(scroller)); | ||
this.scrollers.push(scroller); | ||
} | ||
} | ||
this.scrollListeners = scrollListeners; | ||
} | ||
this.isRtl = isRtl; | ||
} | ||
destroy() { | ||
for (let scrollListener of this.scrollListeners) { | ||
scrollListener.destroy(); | ||
for (let destroyFunc of this.destroyFuncs) { | ||
destroyFunc(); | ||
} | ||
this.destroyFuncs = []; | ||
this.scrollers = []; | ||
} | ||
get x() { | ||
const { scrollListeners, masterEl, isRtl } = this; | ||
const el = masterEl || (scrollListeners.length ? scrollListeners[0].el : undefined); | ||
return internal$1.getNormalizedScrollX(el, isRtl); | ||
const { scrollers, masterScroller } = this; | ||
return (masterScroller || scrollers[0]).x; | ||
} | ||
get y() { | ||
const { scrollListeners, masterEl } = this; | ||
const el = masterEl || (scrollListeners.length ? scrollListeners[0].el : undefined); | ||
return el.scrollTop; | ||
const { scrollers, masterScroller } = this; | ||
return (masterScroller || scrollers[0]).y; | ||
} | ||
scrollTo({ x, y }) { | ||
scrollTo(scrollArg) { | ||
this.isPaused = true; | ||
const { scrollListeners, isRtl } = this; | ||
if (y != null) { | ||
for (let scrollListener of scrollListeners) { | ||
scrollListener.el.scrollTop = y; | ||
} | ||
const { scrollers } = this; | ||
for (let scroller of scrollers) { | ||
scroller.scrollTo(scrollArg); | ||
} | ||
if (x != null) { | ||
for (let scrollListener of scrollListeners) { | ||
internal$1.setNormalizedScrollX(scrollListener.el, isRtl, x); | ||
} | ||
} | ||
this.isPaused = false; | ||
} | ||
bindScroller(el) { | ||
addScrollEndListener(handler) { | ||
this.emitter.on('scrollEnd', handler); | ||
} | ||
removeScrollEndListener(handler) { | ||
this.emitter.off('scrollEnd', handler); | ||
} | ||
bindScroller(scroller) { | ||
let { isHorizontal } = this; | ||
let scrollListener = new ScrollListener(el); | ||
const onScroll = (isWheel, isTouch) => { | ||
if (!this.isPaused) { | ||
if (!this.masterEl || (this.masterEl !== el && (isWheel || isTouch))) { | ||
this.assignMaster(el); | ||
if (!this.masterScroller || (this.masterScroller !== scroller && (isWheel || isTouch))) { | ||
this.assignMaster(scroller); | ||
} | ||
if (this.masterEl === el) { // dealing with current | ||
for (let scrollListener of this.scrollListeners) { | ||
const otherEl = scrollListener.el; | ||
if (otherEl !== el) { | ||
if (this.masterScroller === scroller) { // dealing with current | ||
for (let otherScroller of this.scrollers) { | ||
if (otherScroller !== scroller) { | ||
if (isHorizontal) { | ||
otherEl.scrollLeft = el.scrollLeft; | ||
// TODO: user raw scrollLeft for better performance. No normalization necessary | ||
otherScroller.scrollTo({ x: scroller.x }); | ||
} | ||
else { | ||
otherEl.scrollTop = el.scrollTop; | ||
otherScroller.scrollTo({ y: scroller.y }); | ||
} | ||
@@ -175,15 +89,19 @@ } | ||
const onScrollEnd = () => { | ||
if (this.masterEl === el) { | ||
this.masterEl = null; | ||
if (this.masterScroller === scroller) { | ||
this.masterScroller = null; | ||
this.emitter.trigger('scrollEnd', this.x, this.y); | ||
} | ||
}; | ||
scrollListener.emitter.on('scroll', onScroll); | ||
scrollListener.emitter.on('scrollEnd', onScrollEnd); | ||
return scrollListener; | ||
scroller.listener.emitter.on('scroll', onScroll); | ||
scroller.listener.emitter.on('scrollEnd', onScrollEnd); | ||
return () => { | ||
scroller.listener.emitter.off('scroll', onScroll); | ||
scroller.listener.emitter.off('scrollEnd', onScrollEnd); | ||
}; | ||
} | ||
assignMaster(el) { | ||
this.masterEl = el; | ||
for (let scrollListener of this.scrollListeners) { | ||
if (scrollListener.el !== el) { | ||
scrollListener.endScroll(); // to prevent residual scrolls from reclaiming master | ||
assignMaster(masterScroller) { | ||
this.masterScroller = masterScroller; | ||
for (let scroller of this.scrollers) { | ||
if (scroller !== masterScroller) { | ||
scroller.endScroll(); // to prevent residual scrolls from reclaiming master | ||
} | ||
@@ -196,3 +114,3 @@ } | ||
name: '@fullcalendar/scrollgrid', | ||
premiumReleaseDate: '2024-10-01', | ||
premiumReleaseDate: '2024-10-09', | ||
deps: [premiumCommonPlugin__default["default"]], | ||
@@ -199,0 +117,0 @@ scrollerSyncerClass: ScrollerSyncer |
/*! | ||
FullCalendar ScrollGrid Plugin v7.0.0-beta.0 | ||
FullCalendar ScrollGrid Plugin v7.0.0-beta.1 | ||
Docs & License: https://fullcalendar.io/docs/premium | ||
(c) 2024 Adam Shaw | ||
*/ | ||
FullCalendar.ScrollGrid=function(e,l,s,t){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}var r=i(s);const o="wheel mousewheel DomMouseScroll MozMousePixelScroll".split(" ");class h{constructor(e){this.el=e,this.emitter=new t.Emitter,this.isScrolling=!1,this.isTouching=!1,this.isRecentlyWheeled=!1,this.isRecentlyScrolled=!1,this.wheelWaiter=new t.DelayedRunner(this._handleWheelWaited.bind(this)),this.scrollWaiter=new t.DelayedRunner(this._handleScrollWaited.bind(this)),this.handleScroll=()=>{this.startScroll(),this.emitter.trigger("scroll",this.isRecentlyWheeled,this.isTouching),this.isRecentlyScrolled=!0,this.scrollWaiter.request(500)},this.handleWheel=()=>{this.isRecentlyWheeled=!0,this.wheelWaiter.request(500)},this.handleTouchStart=()=>{this.isTouching=!0},this.handleTouchEnd=()=>{this.isTouching=!1,this.isRecentlyScrolled||this.endScroll()},e.addEventListener("scroll",this.handleScroll),e.addEventListener("touchstart",this.handleTouchStart,{passive:!0}),e.addEventListener("touchend",this.handleTouchEnd);for(let l of o)e.addEventListener(l,this.handleWheel,{passive:!0})}destroy(){let{el:e}=this;e.removeEventListener("scroll",this.handleScroll),e.removeEventListener("touchstart",this.handleTouchStart,{passive:!0}),e.removeEventListener("touchend",this.handleTouchEnd);for(let l of o)e.removeEventListener(l,this.handleWheel,{passive:!0})}startScroll(){this.isScrolling||(this.isScrolling=!0,this.emitter.trigger("scrollStart",this.isRecentlyWheeled,this.isTouching))}endScroll(){this.isScrolling&&(this.emitter.trigger("scrollEnd"),this.isScrolling=!1,this.isRecentlyScrolled=!0,this.isRecentlyWheeled=!1,this.scrollWaiter.clear(),this.wheelWaiter.clear())}_handleScrollWaited(){this.isRecentlyScrolled=!1,this.isTouching||this.endScroll()}_handleWheelWaited(){this.isRecentlyWheeled=!1}}class n{constructor(e=!1){this.isHorizontal=e,this.scrollers=[],this.scrollListeners=[],this.isPaused=!1}handleChildren(e,l){if(!t.isArraysEqual(this.scrollers,e)){this.destroy(),this.scrollers=e;const l=[];for(const s of e)s&&l.push(this.bindScroller(s.el));this.scrollListeners=l}this.isRtl=l}destroy(){for(let e of this.scrollListeners)e.destroy()}get x(){const{scrollListeners:e,masterEl:l,isRtl:s}=this,i=l||(e.length?e[0].el:void 0);return t.getNormalizedScrollX(i,s)}get y(){const{scrollListeners:e,masterEl:l}=this;return(l||(e.length?e[0].el:void 0)).scrollTop}scrollTo({x:e,y:l}){this.isPaused=!0;const{scrollListeners:s,isRtl:i}=this;if(null!=l)for(let e of s)e.el.scrollTop=l;if(null!=e)for(let l of s)t.setNormalizedScrollX(l.el,i,e);this.isPaused=!1}bindScroller(e){let{isHorizontal:l}=this,s=new h(e);return s.emitter.on("scroll",(s,t)=>{if(!this.isPaused&&((!this.masterEl||this.masterEl!==e&&(s||t))&&this.assignMaster(e),this.masterEl===e))for(let s of this.scrollListeners){const t=s.el;t!==e&&(l?t.scrollLeft=e.scrollLeft:t.scrollTop=e.scrollTop)}}),s.emitter.on("scrollEnd",()=>{this.masterEl===e&&(this.masterEl=null)}),s}assignMaster(e){this.masterEl=e;for(let l of this.scrollListeners)l.el!==e&&l.endScroll()}}var c=l.createPlugin({name:"@fullcalendar/scrollgrid",premiumReleaseDate:"2024-10-01",deps:[r.default],scrollerSyncerClass:n}),a={__proto__:null,ScrollerSyncer:n};return l.globalPlugins.push(c),e.Internal=a,e.default=c,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,FullCalendar.PremiumCommon,FullCalendar.Internal); | ||
FullCalendar.ScrollGrid=function(r,s,l,e){"use strict";function t(r){return r&&r.__esModule?r:{default:r}}var o=t(l);class i{constructor(r=!1){this.isHorizontal=r,this.emitter=new e.Emitter,this.scrollers=[],this.destroyFuncs=[],this.isPaused=!1}handleChildren(r){if(!e.isArraysEqual(this.scrollers,r)){this.destroy();for(const s of r)s&&(this.destroyFuncs.push(this.bindScroller(s)),this.scrollers.push(s))}}destroy(){for(let r of this.destroyFuncs)r();this.destroyFuncs=[],this.scrollers=[]}get x(){const{scrollers:r,masterScroller:s}=this;return(s||r[0]).x}get y(){const{scrollers:r,masterScroller:s}=this;return(s||r[0]).y}scrollTo(r){this.isPaused=!0;const{scrollers:s}=this;for(let l of s)l.scrollTo(r);this.isPaused=!1}addScrollEndListener(r){this.emitter.on("scrollEnd",r)}removeScrollEndListener(r){this.emitter.off("scrollEnd",r)}bindScroller(r){let{isHorizontal:s}=this;const l=(l,e)=>{if(!this.isPaused&&((!this.masterScroller||this.masterScroller!==r&&(l||e))&&this.assignMaster(r),this.masterScroller===r))for(let l of this.scrollers)l!==r&&(s?l.scrollTo({x:r.x}):l.scrollTo({y:r.y}))},e=()=>{this.masterScroller===r&&(this.masterScroller=null,this.emitter.trigger("scrollEnd",this.x,this.y))};return r.listener.emitter.on("scroll",l),r.listener.emitter.on("scrollEnd",e),()=>{r.listener.emitter.off("scroll",l),r.listener.emitter.off("scrollEnd",e)}}assignMaster(r){this.masterScroller=r;for(let s of this.scrollers)s!==r&&s.endScroll()}}var n=s.createPlugin({name:"@fullcalendar/scrollgrid",premiumReleaseDate:"2024-10-09",deps:[o.default],scrollerSyncerClass:i}),c={__proto__:null,ScrollerSyncer:i};return s.globalPlugins.push(n),r.Internal=c,r.default=n,Object.defineProperty(r,"__esModule",{value:!0}),r}({},FullCalendar,FullCalendar.PremiumCommon,FullCalendar.Internal); |
@@ -8,3 +8,3 @@ import { createPlugin } from '@fullcalendar/core/index.js'; | ||
name: '@fullcalendar/scrollgrid', | ||
premiumReleaseDate: '2024-10-01', | ||
premiumReleaseDate: '2024-10-09', | ||
deps: [premiumCommonPlugin], | ||
@@ -11,0 +11,0 @@ scrollerSyncerClass: ScrollerSyncer |
@@ -1,44 +0,25 @@ | ||
import { Emitter, ScrollerSyncerInterface, Scroller } from '@fullcalendar/core/internal'; | ||
import { ScrollerSyncerInterface, Scroller } from '@fullcalendar/core/internal'; | ||
declare class ScrollListener { | ||
el: HTMLElement; | ||
emitter: Emitter<any>; | ||
private isScrolling; | ||
private isTouching; | ||
private isRecentlyWheeled; | ||
private isRecentlyScrolled; | ||
private wheelWaiter; | ||
private scrollWaiter; | ||
constructor(el: HTMLElement); | ||
destroy(): void; | ||
private startScroll; | ||
endScroll(): void; | ||
handleScroll: () => void; | ||
_handleScrollWaited(): void; | ||
handleWheel: () => void; | ||
_handleWheelWaited(): void; | ||
handleTouchStart: () => void; | ||
handleTouchEnd: () => void; | ||
} | ||
declare class ScrollerSyncer implements ScrollerSyncerInterface { | ||
private isHorizontal; | ||
private emitter; | ||
private scrollers; | ||
private scrollListeners; | ||
private masterEl; | ||
private destroyFuncs; | ||
private masterScroller; | ||
private isPaused; | ||
private isRtl; | ||
constructor(isHorizontal?: boolean); | ||
handleChildren(scrollers: Scroller[], isRtl: boolean): void; | ||
handleChildren(scrollers: Scroller[]): void; | ||
destroy(): void; | ||
get x(): number; | ||
get y(): number; | ||
scrollTo({ x, y }: { | ||
scrollTo(scrollArg: { | ||
x?: number; | ||
y?: number; | ||
}): void; | ||
bindScroller(el: HTMLElement): ScrollListener; | ||
assignMaster(el: HTMLElement): void; | ||
addScrollEndListener(handler: (x: number, y: number) => void): void; | ||
removeScrollEndListener(handler: (x: number, y: number) => void): void; | ||
bindScroller(scroller: Scroller): () => void; | ||
assignMaster(masterScroller: Scroller): void; | ||
} | ||
export { ScrollerSyncer }; |
182
internal.js
@@ -1,157 +0,71 @@ | ||
import { Emitter, DelayedRunner, isArraysEqual, getNormalizedScrollX, setNormalizedScrollX } from '@fullcalendar/core/internal.js'; | ||
import { Emitter, isArraysEqual } from '@fullcalendar/core/internal.js'; | ||
const WHEEL_EVENT_NAMES = 'wheel mousewheel DomMouseScroll MozMousePixelScroll'.split(' '); | ||
/* | ||
ALSO, with the ability to disable touch | ||
Fires: | ||
- scrollEnd: (x, y) => void | ||
*/ | ||
class ScrollListener { | ||
constructor(el) { | ||
this.el = el; | ||
this.emitter = new Emitter(); | ||
this.isScrolling = false; | ||
this.isTouching = false; // user currently has finger down? | ||
this.isRecentlyWheeled = false; | ||
this.isRecentlyScrolled = false; | ||
this.wheelWaiter = new DelayedRunner(this._handleWheelWaited.bind(this)); | ||
this.scrollWaiter = new DelayedRunner(this._handleScrollWaited.bind(this)); | ||
// Handlers | ||
// ---------------------------------------------------------------------------------------------- | ||
this.handleScroll = () => { | ||
this.startScroll(); | ||
this.emitter.trigger('scroll', this.isRecentlyWheeled, this.isTouching); | ||
this.isRecentlyScrolled = true; | ||
this.scrollWaiter.request(500); | ||
}; | ||
// will fire *before* the scroll event is fired (might not cause a scroll) | ||
this.handleWheel = () => { | ||
this.isRecentlyWheeled = true; | ||
this.wheelWaiter.request(500); | ||
}; | ||
// will fire *before* the scroll event is fired (might not cause a scroll) | ||
this.handleTouchStart = () => { | ||
this.isTouching = true; | ||
}; | ||
this.handleTouchEnd = () => { | ||
this.isTouching = false; | ||
// if the user ended their touch, and the scroll area wasn't moving, | ||
// we consider this to be the end of the scroll. | ||
if (!this.isRecentlyScrolled) { | ||
this.endScroll(); // won't fire if already ended | ||
} | ||
}; | ||
el.addEventListener('scroll', this.handleScroll); | ||
el.addEventListener('touchstart', this.handleTouchStart, { passive: true }); | ||
el.addEventListener('touchend', this.handleTouchEnd); | ||
for (let eventName of WHEEL_EVENT_NAMES) { | ||
el.addEventListener(eventName, this.handleWheel, { passive: true }); | ||
} | ||
} | ||
destroy() { | ||
let { el } = this; | ||
el.removeEventListener('scroll', this.handleScroll); | ||
el.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); | ||
el.removeEventListener('touchend', this.handleTouchEnd); | ||
for (let eventName of WHEEL_EVENT_NAMES) { | ||
el.removeEventListener(eventName, this.handleWheel, { passive: true }); | ||
} | ||
} | ||
// Start / Stop | ||
// ---------------------------------------------------------------------------------------------- | ||
startScroll() { | ||
if (!this.isScrolling) { | ||
this.isScrolling = true; | ||
this.emitter.trigger('scrollStart', this.isRecentlyWheeled, this.isTouching); | ||
} | ||
} | ||
endScroll() { | ||
if (this.isScrolling) { | ||
this.emitter.trigger('scrollEnd'); | ||
this.isScrolling = false; | ||
this.isRecentlyScrolled = true; | ||
this.isRecentlyWheeled = false; | ||
this.scrollWaiter.clear(); | ||
this.wheelWaiter.clear(); | ||
} | ||
} | ||
_handleScrollWaited() { | ||
this.isRecentlyScrolled = false; | ||
// only end the scroll if not currently touching. | ||
// if touching, the scrolling will end later, on touchend. | ||
if (!this.isTouching) { | ||
this.endScroll(); // won't fire if already ended | ||
} | ||
} | ||
_handleWheelWaited() { | ||
this.isRecentlyWheeled = false; | ||
} | ||
} | ||
class ScrollerSyncer { | ||
constructor(isHorizontal = false) { | ||
this.isHorizontal = isHorizontal; | ||
this.scrollers = []; // TODO: move away from requiring Scroller | ||
this.scrollListeners = []; | ||
this.emitter = new Emitter(); | ||
this.scrollers = []; | ||
this.destroyFuncs = []; | ||
this.isPaused = false; | ||
} | ||
handleChildren(scrollers, isRtl) { | ||
handleChildren(scrollers) { | ||
if (!isArraysEqual(this.scrollers, scrollers)) { | ||
this.destroy(); | ||
this.scrollers = scrollers; | ||
const scrollListeners = []; | ||
for (const scroller of scrollers) { | ||
if (scroller) { // could be null | ||
scrollListeners.push(this.bindScroller(scroller.el)); | ||
this.destroyFuncs.push(this.bindScroller(scroller)); | ||
this.scrollers.push(scroller); | ||
} | ||
} | ||
this.scrollListeners = scrollListeners; | ||
} | ||
this.isRtl = isRtl; | ||
} | ||
destroy() { | ||
for (let scrollListener of this.scrollListeners) { | ||
scrollListener.destroy(); | ||
for (let destroyFunc of this.destroyFuncs) { | ||
destroyFunc(); | ||
} | ||
this.destroyFuncs = []; | ||
this.scrollers = []; | ||
} | ||
get x() { | ||
const { scrollListeners, masterEl, isRtl } = this; | ||
const el = masterEl || (scrollListeners.length ? scrollListeners[0].el : undefined); | ||
return getNormalizedScrollX(el, isRtl); | ||
const { scrollers, masterScroller } = this; | ||
return (masterScroller || scrollers[0]).x; | ||
} | ||
get y() { | ||
const { scrollListeners, masterEl } = this; | ||
const el = masterEl || (scrollListeners.length ? scrollListeners[0].el : undefined); | ||
return el.scrollTop; | ||
const { scrollers, masterScroller } = this; | ||
return (masterScroller || scrollers[0]).y; | ||
} | ||
scrollTo({ x, y }) { | ||
scrollTo(scrollArg) { | ||
this.isPaused = true; | ||
const { scrollListeners, isRtl } = this; | ||
if (y != null) { | ||
for (let scrollListener of scrollListeners) { | ||
scrollListener.el.scrollTop = y; | ||
} | ||
const { scrollers } = this; | ||
for (let scroller of scrollers) { | ||
scroller.scrollTo(scrollArg); | ||
} | ||
if (x != null) { | ||
for (let scrollListener of scrollListeners) { | ||
setNormalizedScrollX(scrollListener.el, isRtl, x); | ||
} | ||
} | ||
this.isPaused = false; | ||
} | ||
bindScroller(el) { | ||
addScrollEndListener(handler) { | ||
this.emitter.on('scrollEnd', handler); | ||
} | ||
removeScrollEndListener(handler) { | ||
this.emitter.off('scrollEnd', handler); | ||
} | ||
bindScroller(scroller) { | ||
let { isHorizontal } = this; | ||
let scrollListener = new ScrollListener(el); | ||
const onScroll = (isWheel, isTouch) => { | ||
if (!this.isPaused) { | ||
if (!this.masterEl || (this.masterEl !== el && (isWheel || isTouch))) { | ||
this.assignMaster(el); | ||
if (!this.masterScroller || (this.masterScroller !== scroller && (isWheel || isTouch))) { | ||
this.assignMaster(scroller); | ||
} | ||
if (this.masterEl === el) { // dealing with current | ||
for (let scrollListener of this.scrollListeners) { | ||
const otherEl = scrollListener.el; | ||
if (otherEl !== el) { | ||
if (this.masterScroller === scroller) { // dealing with current | ||
for (let otherScroller of this.scrollers) { | ||
if (otherScroller !== scroller) { | ||
if (isHorizontal) { | ||
otherEl.scrollLeft = el.scrollLeft; | ||
// TODO: user raw scrollLeft for better performance. No normalization necessary | ||
otherScroller.scrollTo({ x: scroller.x }); | ||
} | ||
else { | ||
otherEl.scrollTop = el.scrollTop; | ||
otherScroller.scrollTo({ y: scroller.y }); | ||
} | ||
@@ -164,15 +78,19 @@ } | ||
const onScrollEnd = () => { | ||
if (this.masterEl === el) { | ||
this.masterEl = null; | ||
if (this.masterScroller === scroller) { | ||
this.masterScroller = null; | ||
this.emitter.trigger('scrollEnd', this.x, this.y); | ||
} | ||
}; | ||
scrollListener.emitter.on('scroll', onScroll); | ||
scrollListener.emitter.on('scrollEnd', onScrollEnd); | ||
return scrollListener; | ||
scroller.listener.emitter.on('scroll', onScroll); | ||
scroller.listener.emitter.on('scrollEnd', onScrollEnd); | ||
return () => { | ||
scroller.listener.emitter.off('scroll', onScroll); | ||
scroller.listener.emitter.off('scrollEnd', onScrollEnd); | ||
}; | ||
} | ||
assignMaster(el) { | ||
this.masterEl = el; | ||
for (let scrollListener of this.scrollListeners) { | ||
if (scrollListener.el !== el) { | ||
scrollListener.endScroll(); // to prevent residual scrolls from reclaiming master | ||
assignMaster(masterScroller) { | ||
this.masterScroller = masterScroller; | ||
for (let scroller of this.scrollers) { | ||
if (scroller !== masterScroller) { | ||
scroller.endScroll(); // to prevent residual scrolls from reclaiming master | ||
} | ||
@@ -179,0 +97,0 @@ } |
{ | ||
"name": "@fullcalendar/scrollgrid", | ||
"version": "7.0.0-beta.0", | ||
"version": "7.0.0-beta.1", | ||
"title": "FullCalendar ScrollGrid Plugin", | ||
"description": "Tabular data chunked into scrollable panes", | ||
"dependencies": { | ||
"@fullcalendar/premium-common": "7.0.0-beta.0" | ||
"@fullcalendar/premium-common": "7.0.0-beta.1" | ||
}, | ||
"peerDependencies": { | ||
"@fullcalendar/core": "7.0.0-beta.0" | ||
"@fullcalendar/core": "7.0.0-beta.1" | ||
}, | ||
@@ -12,0 +12,0 @@ "type": "module", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
18091
379
+ Added@fullcalendar/core@7.0.0-beta.1(transitive)
+ Added@fullcalendar/premium-common@7.0.0-beta.1(transitive)
- Removed@fullcalendar/core@7.0.0-beta.0(transitive)
- Removed@fullcalendar/premium-common@7.0.0-beta.0(transitive)