@fullcalendar_interaction.js 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905
  1. import "./chunk-DAAU2ANU.js";
  2. import {
  3. BASE_OPTION_DEFAULTS,
  4. ElementDragging,
  5. ElementScrollController,
  6. Emitter,
  7. EventImpl,
  8. Interaction,
  9. ScrollController,
  10. WindowScrollController,
  11. allowContextMenu,
  12. allowSelection,
  13. applyMutationToEventStore,
  14. applyStyle,
  15. buildEventApis,
  16. compareNumbers,
  17. computeInnerRect,
  18. computeRect,
  19. config,
  20. constrainPoint,
  21. createDuration,
  22. createEmptyEventStore,
  23. createEventInstance,
  24. createPlugin,
  25. diffDates,
  26. diffPoints,
  27. disableCursor,
  28. elementClosest,
  29. elementMatches,
  30. enableCursor,
  31. eventTupleToStore,
  32. getClippingParents,
  33. getDefaultEventEnd,
  34. getElSeg,
  35. getEventTargetViaRoot,
  36. getRectCenter,
  37. getRelevantEvents,
  38. identity,
  39. interactionSettingsStore,
  40. interactionSettingsToStore,
  41. intersectRects,
  42. isDateSelectionValid,
  43. isDateSpansEqual,
  44. isInteractionValid,
  45. mapHash,
  46. parseDragMeta,
  47. parseEventDef,
  48. pointInsideRect,
  49. preventContextMenu,
  50. preventSelection,
  51. rangeContainsRange,
  52. refineEventDef,
  53. removeElement,
  54. startOfDay,
  55. triggerDateSelect,
  56. whenTransitionDone
  57. } from "./chunk-QH2VTIUN.js";
  58. import "./chunk-PTVH4XAB.js";
  59. import "./chunk-2LSFTFF7.js";
  60. // node_modules/.pnpm/@fullcalendar+interaction@6.1.14_@fullcalendar+core@6.1.14/node_modules/@fullcalendar/interaction/index.js
  61. config.touchMouseIgnoreWait = 500;
  62. var ignoreMouseDepth = 0;
  63. var listenerCnt = 0;
  64. var isWindowTouchMoveCancelled = false;
  65. var PointerDragging = class {
  66. constructor(containerEl) {
  67. this.subjectEl = null;
  68. this.selector = "";
  69. this.handleSelector = "";
  70. this.shouldIgnoreMove = false;
  71. this.shouldWatchScroll = true;
  72. this.isDragging = false;
  73. this.isTouchDragging = false;
  74. this.wasTouchScroll = false;
  75. this.handleMouseDown = (ev) => {
  76. if (!this.shouldIgnoreMouse() && isPrimaryMouseButton(ev) && this.tryStart(ev)) {
  77. let pev = this.createEventFromMouse(ev, true);
  78. this.emitter.trigger("pointerdown", pev);
  79. this.initScrollWatch(pev);
  80. if (!this.shouldIgnoreMove) {
  81. document.addEventListener("mousemove", this.handleMouseMove);
  82. }
  83. document.addEventListener("mouseup", this.handleMouseUp);
  84. }
  85. };
  86. this.handleMouseMove = (ev) => {
  87. let pev = this.createEventFromMouse(ev);
  88. this.recordCoords(pev);
  89. this.emitter.trigger("pointermove", pev);
  90. };
  91. this.handleMouseUp = (ev) => {
  92. document.removeEventListener("mousemove", this.handleMouseMove);
  93. document.removeEventListener("mouseup", this.handleMouseUp);
  94. this.emitter.trigger("pointerup", this.createEventFromMouse(ev));
  95. this.cleanup();
  96. };
  97. this.handleTouchStart = (ev) => {
  98. if (this.tryStart(ev)) {
  99. this.isTouchDragging = true;
  100. let pev = this.createEventFromTouch(ev, true);
  101. this.emitter.trigger("pointerdown", pev);
  102. this.initScrollWatch(pev);
  103. let targetEl = ev.target;
  104. if (!this.shouldIgnoreMove) {
  105. targetEl.addEventListener("touchmove", this.handleTouchMove);
  106. }
  107. targetEl.addEventListener("touchend", this.handleTouchEnd);
  108. targetEl.addEventListener("touchcancel", this.handleTouchEnd);
  109. window.addEventListener("scroll", this.handleTouchScroll, true);
  110. }
  111. };
  112. this.handleTouchMove = (ev) => {
  113. let pev = this.createEventFromTouch(ev);
  114. this.recordCoords(pev);
  115. this.emitter.trigger("pointermove", pev);
  116. };
  117. this.handleTouchEnd = (ev) => {
  118. if (this.isDragging) {
  119. let targetEl = ev.target;
  120. targetEl.removeEventListener("touchmove", this.handleTouchMove);
  121. targetEl.removeEventListener("touchend", this.handleTouchEnd);
  122. targetEl.removeEventListener("touchcancel", this.handleTouchEnd);
  123. window.removeEventListener("scroll", this.handleTouchScroll, true);
  124. this.emitter.trigger("pointerup", this.createEventFromTouch(ev));
  125. this.cleanup();
  126. this.isTouchDragging = false;
  127. startIgnoringMouse();
  128. }
  129. };
  130. this.handleTouchScroll = () => {
  131. this.wasTouchScroll = true;
  132. };
  133. this.handleScroll = (ev) => {
  134. if (!this.shouldIgnoreMove) {
  135. let pageX = window.scrollX - this.prevScrollX + this.prevPageX;
  136. let pageY = window.scrollY - this.prevScrollY + this.prevPageY;
  137. this.emitter.trigger("pointermove", {
  138. origEvent: ev,
  139. isTouch: this.isTouchDragging,
  140. subjectEl: this.subjectEl,
  141. pageX,
  142. pageY,
  143. deltaX: pageX - this.origPageX,
  144. deltaY: pageY - this.origPageY
  145. });
  146. }
  147. };
  148. this.containerEl = containerEl;
  149. this.emitter = new Emitter();
  150. containerEl.addEventListener("mousedown", this.handleMouseDown);
  151. containerEl.addEventListener("touchstart", this.handleTouchStart, { passive: true });
  152. listenerCreated();
  153. }
  154. destroy() {
  155. this.containerEl.removeEventListener("mousedown", this.handleMouseDown);
  156. this.containerEl.removeEventListener("touchstart", this.handleTouchStart, { passive: true });
  157. listenerDestroyed();
  158. }
  159. tryStart(ev) {
  160. let subjectEl = this.querySubjectEl(ev);
  161. let downEl = ev.target;
  162. if (subjectEl && (!this.handleSelector || elementClosest(downEl, this.handleSelector))) {
  163. this.subjectEl = subjectEl;
  164. this.isDragging = true;
  165. this.wasTouchScroll = false;
  166. return true;
  167. }
  168. return false;
  169. }
  170. cleanup() {
  171. isWindowTouchMoveCancelled = false;
  172. this.isDragging = false;
  173. this.subjectEl = null;
  174. this.destroyScrollWatch();
  175. }
  176. querySubjectEl(ev) {
  177. if (this.selector) {
  178. return elementClosest(ev.target, this.selector);
  179. }
  180. return this.containerEl;
  181. }
  182. shouldIgnoreMouse() {
  183. return ignoreMouseDepth || this.isTouchDragging;
  184. }
  185. // can be called by user of this class, to cancel touch-based scrolling for the current drag
  186. cancelTouchScroll() {
  187. if (this.isDragging) {
  188. isWindowTouchMoveCancelled = true;
  189. }
  190. }
  191. // Scrolling that simulates pointermoves
  192. // ----------------------------------------------------------------------------------------------------
  193. initScrollWatch(ev) {
  194. if (this.shouldWatchScroll) {
  195. this.recordCoords(ev);
  196. window.addEventListener("scroll", this.handleScroll, true);
  197. }
  198. }
  199. recordCoords(ev) {
  200. if (this.shouldWatchScroll) {
  201. this.prevPageX = ev.pageX;
  202. this.prevPageY = ev.pageY;
  203. this.prevScrollX = window.scrollX;
  204. this.prevScrollY = window.scrollY;
  205. }
  206. }
  207. destroyScrollWatch() {
  208. if (this.shouldWatchScroll) {
  209. window.removeEventListener("scroll", this.handleScroll, true);
  210. }
  211. }
  212. // Event Normalization
  213. // ----------------------------------------------------------------------------------------------------
  214. createEventFromMouse(ev, isFirst) {
  215. let deltaX = 0;
  216. let deltaY = 0;
  217. if (isFirst) {
  218. this.origPageX = ev.pageX;
  219. this.origPageY = ev.pageY;
  220. } else {
  221. deltaX = ev.pageX - this.origPageX;
  222. deltaY = ev.pageY - this.origPageY;
  223. }
  224. return {
  225. origEvent: ev,
  226. isTouch: false,
  227. subjectEl: this.subjectEl,
  228. pageX: ev.pageX,
  229. pageY: ev.pageY,
  230. deltaX,
  231. deltaY
  232. };
  233. }
  234. createEventFromTouch(ev, isFirst) {
  235. let touches = ev.touches;
  236. let pageX;
  237. let pageY;
  238. let deltaX = 0;
  239. let deltaY = 0;
  240. if (touches && touches.length) {
  241. pageX = touches[0].pageX;
  242. pageY = touches[0].pageY;
  243. } else {
  244. pageX = ev.pageX;
  245. pageY = ev.pageY;
  246. }
  247. if (isFirst) {
  248. this.origPageX = pageX;
  249. this.origPageY = pageY;
  250. } else {
  251. deltaX = pageX - this.origPageX;
  252. deltaY = pageY - this.origPageY;
  253. }
  254. return {
  255. origEvent: ev,
  256. isTouch: true,
  257. subjectEl: this.subjectEl,
  258. pageX,
  259. pageY,
  260. deltaX,
  261. deltaY
  262. };
  263. }
  264. };
  265. function isPrimaryMouseButton(ev) {
  266. return ev.button === 0 && !ev.ctrlKey;
  267. }
  268. function startIgnoringMouse() {
  269. ignoreMouseDepth += 1;
  270. setTimeout(() => {
  271. ignoreMouseDepth -= 1;
  272. }, config.touchMouseIgnoreWait);
  273. }
  274. function listenerCreated() {
  275. listenerCnt += 1;
  276. if (listenerCnt === 1) {
  277. window.addEventListener("touchmove", onWindowTouchMove, { passive: false });
  278. }
  279. }
  280. function listenerDestroyed() {
  281. listenerCnt -= 1;
  282. if (!listenerCnt) {
  283. window.removeEventListener("touchmove", onWindowTouchMove, { passive: false });
  284. }
  285. }
  286. function onWindowTouchMove(ev) {
  287. if (isWindowTouchMoveCancelled) {
  288. ev.preventDefault();
  289. }
  290. }
  291. var ElementMirror = class {
  292. constructor() {
  293. this.isVisible = false;
  294. this.sourceEl = null;
  295. this.mirrorEl = null;
  296. this.sourceElRect = null;
  297. this.parentNode = document.body;
  298. this.zIndex = 9999;
  299. this.revertDuration = 0;
  300. }
  301. start(sourceEl, pageX, pageY) {
  302. this.sourceEl = sourceEl;
  303. this.sourceElRect = this.sourceEl.getBoundingClientRect();
  304. this.origScreenX = pageX - window.scrollX;
  305. this.origScreenY = pageY - window.scrollY;
  306. this.deltaX = 0;
  307. this.deltaY = 0;
  308. this.updateElPosition();
  309. }
  310. handleMove(pageX, pageY) {
  311. this.deltaX = pageX - window.scrollX - this.origScreenX;
  312. this.deltaY = pageY - window.scrollY - this.origScreenY;
  313. this.updateElPosition();
  314. }
  315. // can be called before start
  316. setIsVisible(bool) {
  317. if (bool) {
  318. if (!this.isVisible) {
  319. if (this.mirrorEl) {
  320. this.mirrorEl.style.display = "";
  321. }
  322. this.isVisible = bool;
  323. this.updateElPosition();
  324. }
  325. } else if (this.isVisible) {
  326. if (this.mirrorEl) {
  327. this.mirrorEl.style.display = "none";
  328. }
  329. this.isVisible = bool;
  330. }
  331. }
  332. // always async
  333. stop(needsRevertAnimation, callback) {
  334. let done = () => {
  335. this.cleanup();
  336. callback();
  337. };
  338. if (needsRevertAnimation && this.mirrorEl && this.isVisible && this.revertDuration && // if 0, transition won't work
  339. (this.deltaX || this.deltaY)) {
  340. this.doRevertAnimation(done, this.revertDuration);
  341. } else {
  342. setTimeout(done, 0);
  343. }
  344. }
  345. doRevertAnimation(callback, revertDuration) {
  346. let mirrorEl = this.mirrorEl;
  347. let finalSourceElRect = this.sourceEl.getBoundingClientRect();
  348. mirrorEl.style.transition = "top " + revertDuration + "ms,left " + revertDuration + "ms";
  349. applyStyle(mirrorEl, {
  350. left: finalSourceElRect.left,
  351. top: finalSourceElRect.top
  352. });
  353. whenTransitionDone(mirrorEl, () => {
  354. mirrorEl.style.transition = "";
  355. callback();
  356. });
  357. }
  358. cleanup() {
  359. if (this.mirrorEl) {
  360. removeElement(this.mirrorEl);
  361. this.mirrorEl = null;
  362. }
  363. this.sourceEl = null;
  364. }
  365. updateElPosition() {
  366. if (this.sourceEl && this.isVisible) {
  367. applyStyle(this.getMirrorEl(), {
  368. left: this.sourceElRect.left + this.deltaX,
  369. top: this.sourceElRect.top + this.deltaY
  370. });
  371. }
  372. }
  373. getMirrorEl() {
  374. let sourceElRect = this.sourceElRect;
  375. let mirrorEl = this.mirrorEl;
  376. if (!mirrorEl) {
  377. mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true);
  378. mirrorEl.style.userSelect = "none";
  379. mirrorEl.style.webkitUserSelect = "none";
  380. mirrorEl.style.pointerEvents = "none";
  381. mirrorEl.classList.add("fc-event-dragging");
  382. applyStyle(mirrorEl, {
  383. position: "fixed",
  384. zIndex: this.zIndex,
  385. visibility: "",
  386. boxSizing: "border-box",
  387. width: sourceElRect.right - sourceElRect.left,
  388. height: sourceElRect.bottom - sourceElRect.top,
  389. right: "auto",
  390. bottom: "auto",
  391. margin: 0
  392. });
  393. this.parentNode.appendChild(mirrorEl);
  394. }
  395. return mirrorEl;
  396. }
  397. };
  398. var ScrollGeomCache = class extends ScrollController {
  399. constructor(scrollController, doesListening) {
  400. super();
  401. this.handleScroll = () => {
  402. this.scrollTop = this.scrollController.getScrollTop();
  403. this.scrollLeft = this.scrollController.getScrollLeft();
  404. this.handleScrollChange();
  405. };
  406. this.scrollController = scrollController;
  407. this.doesListening = doesListening;
  408. this.scrollTop = this.origScrollTop = scrollController.getScrollTop();
  409. this.scrollLeft = this.origScrollLeft = scrollController.getScrollLeft();
  410. this.scrollWidth = scrollController.getScrollWidth();
  411. this.scrollHeight = scrollController.getScrollHeight();
  412. this.clientWidth = scrollController.getClientWidth();
  413. this.clientHeight = scrollController.getClientHeight();
  414. this.clientRect = this.computeClientRect();
  415. if (this.doesListening) {
  416. this.getEventTarget().addEventListener("scroll", this.handleScroll);
  417. }
  418. }
  419. destroy() {
  420. if (this.doesListening) {
  421. this.getEventTarget().removeEventListener("scroll", this.handleScroll);
  422. }
  423. }
  424. getScrollTop() {
  425. return this.scrollTop;
  426. }
  427. getScrollLeft() {
  428. return this.scrollLeft;
  429. }
  430. setScrollTop(top) {
  431. this.scrollController.setScrollTop(top);
  432. if (!this.doesListening) {
  433. this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
  434. this.handleScrollChange();
  435. }
  436. }
  437. setScrollLeft(top) {
  438. this.scrollController.setScrollLeft(top);
  439. if (!this.doesListening) {
  440. this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
  441. this.handleScrollChange();
  442. }
  443. }
  444. getClientWidth() {
  445. return this.clientWidth;
  446. }
  447. getClientHeight() {
  448. return this.clientHeight;
  449. }
  450. getScrollWidth() {
  451. return this.scrollWidth;
  452. }
  453. getScrollHeight() {
  454. return this.scrollHeight;
  455. }
  456. handleScrollChange() {
  457. }
  458. };
  459. var ElementScrollGeomCache = class extends ScrollGeomCache {
  460. constructor(el, doesListening) {
  461. super(new ElementScrollController(el), doesListening);
  462. }
  463. getEventTarget() {
  464. return this.scrollController.el;
  465. }
  466. computeClientRect() {
  467. return computeInnerRect(this.scrollController.el);
  468. }
  469. };
  470. var WindowScrollGeomCache = class extends ScrollGeomCache {
  471. constructor(doesListening) {
  472. super(new WindowScrollController(), doesListening);
  473. }
  474. getEventTarget() {
  475. return window;
  476. }
  477. computeClientRect() {
  478. return {
  479. left: this.scrollLeft,
  480. right: this.scrollLeft + this.clientWidth,
  481. top: this.scrollTop,
  482. bottom: this.scrollTop + this.clientHeight
  483. };
  484. }
  485. // the window is the only scroll object that changes it's rectangle relative
  486. // to the document's topleft as it scrolls
  487. handleScrollChange() {
  488. this.clientRect = this.computeClientRect();
  489. }
  490. };
  491. var getTime = typeof performance === "function" ? performance.now : Date.now;
  492. var AutoScroller = class {
  493. constructor() {
  494. this.isEnabled = true;
  495. this.scrollQuery = [window, ".fc-scroller"];
  496. this.edgeThreshold = 50;
  497. this.maxVelocity = 300;
  498. this.pointerScreenX = null;
  499. this.pointerScreenY = null;
  500. this.isAnimating = false;
  501. this.scrollCaches = null;
  502. this.everMovedUp = false;
  503. this.everMovedDown = false;
  504. this.everMovedLeft = false;
  505. this.everMovedRight = false;
  506. this.animate = () => {
  507. if (this.isAnimating) {
  508. let edge = this.computeBestEdge(this.pointerScreenX + window.scrollX, this.pointerScreenY + window.scrollY);
  509. if (edge) {
  510. let now = getTime();
  511. this.handleSide(edge, (now - this.msSinceRequest) / 1e3);
  512. this.requestAnimation(now);
  513. } else {
  514. this.isAnimating = false;
  515. }
  516. }
  517. };
  518. }
  519. start(pageX, pageY, scrollStartEl) {
  520. if (this.isEnabled) {
  521. this.scrollCaches = this.buildCaches(scrollStartEl);
  522. this.pointerScreenX = null;
  523. this.pointerScreenY = null;
  524. this.everMovedUp = false;
  525. this.everMovedDown = false;
  526. this.everMovedLeft = false;
  527. this.everMovedRight = false;
  528. this.handleMove(pageX, pageY);
  529. }
  530. }
  531. handleMove(pageX, pageY) {
  532. if (this.isEnabled) {
  533. let pointerScreenX = pageX - window.scrollX;
  534. let pointerScreenY = pageY - window.scrollY;
  535. let yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
  536. let xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
  537. if (yDelta < 0) {
  538. this.everMovedUp = true;
  539. } else if (yDelta > 0) {
  540. this.everMovedDown = true;
  541. }
  542. if (xDelta < 0) {
  543. this.everMovedLeft = true;
  544. } else if (xDelta > 0) {
  545. this.everMovedRight = true;
  546. }
  547. this.pointerScreenX = pointerScreenX;
  548. this.pointerScreenY = pointerScreenY;
  549. if (!this.isAnimating) {
  550. this.isAnimating = true;
  551. this.requestAnimation(getTime());
  552. }
  553. }
  554. }
  555. stop() {
  556. if (this.isEnabled) {
  557. this.isAnimating = false;
  558. for (let scrollCache of this.scrollCaches) {
  559. scrollCache.destroy();
  560. }
  561. this.scrollCaches = null;
  562. }
  563. }
  564. requestAnimation(now) {
  565. this.msSinceRequest = now;
  566. requestAnimationFrame(this.animate);
  567. }
  568. handleSide(edge, seconds) {
  569. let { scrollCache } = edge;
  570. let { edgeThreshold } = this;
  571. let invDistance = edgeThreshold - edge.distance;
  572. let velocity = (
  573. // the closer to the edge, the faster we scroll
  574. invDistance * invDistance / (edgeThreshold * edgeThreshold) * // quadratic
  575. this.maxVelocity * seconds
  576. );
  577. let sign = 1;
  578. switch (edge.name) {
  579. case "left":
  580. sign = -1;
  581. case "right":
  582. scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
  583. break;
  584. case "top":
  585. sign = -1;
  586. case "bottom":
  587. scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
  588. break;
  589. }
  590. }
  591. // left/top are relative to document topleft
  592. computeBestEdge(left, top) {
  593. let { edgeThreshold } = this;
  594. let bestSide = null;
  595. let scrollCaches = this.scrollCaches || [];
  596. for (let scrollCache of scrollCaches) {
  597. let rect = scrollCache.clientRect;
  598. let leftDist = left - rect.left;
  599. let rightDist = rect.right - left;
  600. let topDist = top - rect.top;
  601. let bottomDist = rect.bottom - top;
  602. if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
  603. if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && (!bestSide || bestSide.distance > topDist)) {
  604. bestSide = { scrollCache, name: "top", distance: topDist };
  605. }
  606. if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && (!bestSide || bestSide.distance > bottomDist)) {
  607. bestSide = { scrollCache, name: "bottom", distance: bottomDist };
  608. }
  609. if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && (!bestSide || bestSide.distance > leftDist)) {
  610. bestSide = { scrollCache, name: "left", distance: leftDist };
  611. }
  612. if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && (!bestSide || bestSide.distance > rightDist)) {
  613. bestSide = { scrollCache, name: "right", distance: rightDist };
  614. }
  615. }
  616. }
  617. return bestSide;
  618. }
  619. buildCaches(scrollStartEl) {
  620. return this.queryScrollEls(scrollStartEl).map((el) => {
  621. if (el === window) {
  622. return new WindowScrollGeomCache(false);
  623. }
  624. return new ElementScrollGeomCache(el, false);
  625. });
  626. }
  627. queryScrollEls(scrollStartEl) {
  628. let els = [];
  629. for (let query of this.scrollQuery) {
  630. if (typeof query === "object") {
  631. els.push(query);
  632. } else {
  633. els.push(...Array.prototype.slice.call(scrollStartEl.getRootNode().querySelectorAll(query)));
  634. }
  635. }
  636. return els;
  637. }
  638. };
  639. var FeaturefulElementDragging = class extends ElementDragging {
  640. constructor(containerEl, selector) {
  641. super(containerEl);
  642. this.containerEl = containerEl;
  643. this.delay = null;
  644. this.minDistance = 0;
  645. this.touchScrollAllowed = true;
  646. this.mirrorNeedsRevert = false;
  647. this.isInteracting = false;
  648. this.isDragging = false;
  649. this.isDelayEnded = false;
  650. this.isDistanceSurpassed = false;
  651. this.delayTimeoutId = null;
  652. this.onPointerDown = (ev) => {
  653. if (!this.isDragging) {
  654. this.isInteracting = true;
  655. this.isDelayEnded = false;
  656. this.isDistanceSurpassed = false;
  657. preventSelection(document.body);
  658. preventContextMenu(document.body);
  659. if (!ev.isTouch) {
  660. ev.origEvent.preventDefault();
  661. }
  662. this.emitter.trigger("pointerdown", ev);
  663. if (this.isInteracting && // not destroyed via pointerdown handler
  664. !this.pointer.shouldIgnoreMove) {
  665. this.mirror.setIsVisible(false);
  666. this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY);
  667. this.startDelay(ev);
  668. if (!this.minDistance) {
  669. this.handleDistanceSurpassed(ev);
  670. }
  671. }
  672. }
  673. };
  674. this.onPointerMove = (ev) => {
  675. if (this.isInteracting) {
  676. this.emitter.trigger("pointermove", ev);
  677. if (!this.isDistanceSurpassed) {
  678. let minDistance = this.minDistance;
  679. let distanceSq;
  680. let { deltaX, deltaY } = ev;
  681. distanceSq = deltaX * deltaX + deltaY * deltaY;
  682. if (distanceSq >= minDistance * minDistance) {
  683. this.handleDistanceSurpassed(ev);
  684. }
  685. }
  686. if (this.isDragging) {
  687. if (ev.origEvent.type !== "scroll") {
  688. this.mirror.handleMove(ev.pageX, ev.pageY);
  689. this.autoScroller.handleMove(ev.pageX, ev.pageY);
  690. }
  691. this.emitter.trigger("dragmove", ev);
  692. }
  693. }
  694. };
  695. this.onPointerUp = (ev) => {
  696. if (this.isInteracting) {
  697. this.isInteracting = false;
  698. allowSelection(document.body);
  699. allowContextMenu(document.body);
  700. this.emitter.trigger("pointerup", ev);
  701. if (this.isDragging) {
  702. this.autoScroller.stop();
  703. this.tryStopDrag(ev);
  704. }
  705. if (this.delayTimeoutId) {
  706. clearTimeout(this.delayTimeoutId);
  707. this.delayTimeoutId = null;
  708. }
  709. }
  710. };
  711. let pointer = this.pointer = new PointerDragging(containerEl);
  712. pointer.emitter.on("pointerdown", this.onPointerDown);
  713. pointer.emitter.on("pointermove", this.onPointerMove);
  714. pointer.emitter.on("pointerup", this.onPointerUp);
  715. if (selector) {
  716. pointer.selector = selector;
  717. }
  718. this.mirror = new ElementMirror();
  719. this.autoScroller = new AutoScroller();
  720. }
  721. destroy() {
  722. this.pointer.destroy();
  723. this.onPointerUp({});
  724. }
  725. startDelay(ev) {
  726. if (typeof this.delay === "number") {
  727. this.delayTimeoutId = setTimeout(() => {
  728. this.delayTimeoutId = null;
  729. this.handleDelayEnd(ev);
  730. }, this.delay);
  731. } else {
  732. this.handleDelayEnd(ev);
  733. }
  734. }
  735. handleDelayEnd(ev) {
  736. this.isDelayEnded = true;
  737. this.tryStartDrag(ev);
  738. }
  739. handleDistanceSurpassed(ev) {
  740. this.isDistanceSurpassed = true;
  741. this.tryStartDrag(ev);
  742. }
  743. tryStartDrag(ev) {
  744. if (this.isDelayEnded && this.isDistanceSurpassed) {
  745. if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
  746. this.isDragging = true;
  747. this.mirrorNeedsRevert = false;
  748. this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl);
  749. this.emitter.trigger("dragstart", ev);
  750. if (this.touchScrollAllowed === false) {
  751. this.pointer.cancelTouchScroll();
  752. }
  753. }
  754. }
  755. }
  756. tryStopDrag(ev) {
  757. this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));
  758. }
  759. stopDrag(ev) {
  760. this.isDragging = false;
  761. this.emitter.trigger("dragend", ev);
  762. }
  763. // fill in the implementations...
  764. setIgnoreMove(bool) {
  765. this.pointer.shouldIgnoreMove = bool;
  766. }
  767. setMirrorIsVisible(bool) {
  768. this.mirror.setIsVisible(bool);
  769. }
  770. setMirrorNeedsRevert(bool) {
  771. this.mirrorNeedsRevert = bool;
  772. }
  773. setAutoScrollEnabled(bool) {
  774. this.autoScroller.isEnabled = bool;
  775. }
  776. };
  777. var OffsetTracker = class {
  778. constructor(el) {
  779. this.el = el;
  780. this.origRect = computeRect(el);
  781. this.scrollCaches = getClippingParents(el).map((scrollEl) => new ElementScrollGeomCache(scrollEl, true));
  782. }
  783. destroy() {
  784. for (let scrollCache of this.scrollCaches) {
  785. scrollCache.destroy();
  786. }
  787. }
  788. computeLeft() {
  789. let left = this.origRect.left;
  790. for (let scrollCache of this.scrollCaches) {
  791. left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
  792. }
  793. return left;
  794. }
  795. computeTop() {
  796. let top = this.origRect.top;
  797. for (let scrollCache of this.scrollCaches) {
  798. top += scrollCache.origScrollTop - scrollCache.getScrollTop();
  799. }
  800. return top;
  801. }
  802. isWithinClipping(pageX, pageY) {
  803. let point = { left: pageX, top: pageY };
  804. for (let scrollCache of this.scrollCaches) {
  805. if (!isIgnoredClipping(scrollCache.getEventTarget()) && !pointInsideRect(point, scrollCache.clientRect)) {
  806. return false;
  807. }
  808. }
  809. return true;
  810. }
  811. };
  812. function isIgnoredClipping(node) {
  813. let tagName = node.tagName;
  814. return tagName === "HTML" || tagName === "BODY";
  815. }
  816. var HitDragging = class {
  817. constructor(dragging, droppableStore) {
  818. this.useSubjectCenter = false;
  819. this.requireInitial = true;
  820. this.disablePointCheck = false;
  821. this.initialHit = null;
  822. this.movingHit = null;
  823. this.finalHit = null;
  824. this.handlePointerDown = (ev) => {
  825. let { dragging: dragging2 } = this;
  826. this.initialHit = null;
  827. this.movingHit = null;
  828. this.finalHit = null;
  829. this.prepareHits();
  830. this.processFirstCoord(ev);
  831. if (this.initialHit || !this.requireInitial) {
  832. dragging2.setIgnoreMove(false);
  833. this.emitter.trigger("pointerdown", ev);
  834. } else {
  835. dragging2.setIgnoreMove(true);
  836. }
  837. };
  838. this.handleDragStart = (ev) => {
  839. this.emitter.trigger("dragstart", ev);
  840. this.handleMove(ev, true);
  841. };
  842. this.handleDragMove = (ev) => {
  843. this.emitter.trigger("dragmove", ev);
  844. this.handleMove(ev);
  845. };
  846. this.handlePointerUp = (ev) => {
  847. this.releaseHits();
  848. this.emitter.trigger("pointerup", ev);
  849. };
  850. this.handleDragEnd = (ev) => {
  851. if (this.movingHit) {
  852. this.emitter.trigger("hitupdate", null, true, ev);
  853. }
  854. this.finalHit = this.movingHit;
  855. this.movingHit = null;
  856. this.emitter.trigger("dragend", ev);
  857. };
  858. this.droppableStore = droppableStore;
  859. dragging.emitter.on("pointerdown", this.handlePointerDown);
  860. dragging.emitter.on("dragstart", this.handleDragStart);
  861. dragging.emitter.on("dragmove", this.handleDragMove);
  862. dragging.emitter.on("pointerup", this.handlePointerUp);
  863. dragging.emitter.on("dragend", this.handleDragEnd);
  864. this.dragging = dragging;
  865. this.emitter = new Emitter();
  866. }
  867. // sets initialHit
  868. // sets coordAdjust
  869. processFirstCoord(ev) {
  870. let origPoint = { left: ev.pageX, top: ev.pageY };
  871. let adjustedPoint = origPoint;
  872. let subjectEl = ev.subjectEl;
  873. let subjectRect;
  874. if (subjectEl instanceof HTMLElement) {
  875. subjectRect = computeRect(subjectEl);
  876. adjustedPoint = constrainPoint(adjustedPoint, subjectRect);
  877. }
  878. let initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
  879. if (initialHit) {
  880. if (this.useSubjectCenter && subjectRect) {
  881. let slicedSubjectRect = intersectRects(subjectRect, initialHit.rect);
  882. if (slicedSubjectRect) {
  883. adjustedPoint = getRectCenter(slicedSubjectRect);
  884. }
  885. }
  886. this.coordAdjust = diffPoints(adjustedPoint, origPoint);
  887. } else {
  888. this.coordAdjust = { left: 0, top: 0 };
  889. }
  890. }
  891. handleMove(ev, forceHandle) {
  892. let hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
  893. if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
  894. this.movingHit = hit;
  895. this.emitter.trigger("hitupdate", hit, false, ev);
  896. }
  897. }
  898. prepareHits() {
  899. this.offsetTrackers = mapHash(this.droppableStore, (interactionSettings) => {
  900. interactionSettings.component.prepareHits();
  901. return new OffsetTracker(interactionSettings.el);
  902. });
  903. }
  904. releaseHits() {
  905. let { offsetTrackers } = this;
  906. for (let id in offsetTrackers) {
  907. offsetTrackers[id].destroy();
  908. }
  909. this.offsetTrackers = {};
  910. }
  911. queryHitForOffset(offsetLeft, offsetTop) {
  912. let { droppableStore, offsetTrackers } = this;
  913. let bestHit = null;
  914. for (let id in droppableStore) {
  915. let component = droppableStore[id].component;
  916. let offsetTracker = offsetTrackers[id];
  917. if (offsetTracker && // wasn't destroyed mid-drag
  918. offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
  919. let originLeft = offsetTracker.computeLeft();
  920. let originTop = offsetTracker.computeTop();
  921. let positionLeft = offsetLeft - originLeft;
  922. let positionTop = offsetTop - originTop;
  923. let { origRect } = offsetTracker;
  924. let width = origRect.right - origRect.left;
  925. let height = origRect.bottom - origRect.top;
  926. if (
  927. // must be within the element's bounds
  928. positionLeft >= 0 && positionLeft < width && positionTop >= 0 && positionTop < height
  929. ) {
  930. let hit = component.queryHit(positionLeft, positionTop, width, height);
  931. if (hit && // make sure the hit is within activeRange, meaning it's not a dead cell
  932. rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range) && // Ensure the component we are querying for the hit is accessibly my the pointer
  933. // Prevents obscured calendars (ex: under a modal dialog) from accepting hit
  934. // https://github.com/fullcalendar/fullcalendar/issues/5026
  935. (this.disablePointCheck || offsetTracker.el.contains(document.elementFromPoint(
  936. // add-back origins to get coordinate relative to top-left of window viewport
  937. positionLeft + originLeft - window.scrollX,
  938. positionTop + originTop - window.scrollY
  939. ))) && (!bestHit || hit.layer > bestHit.layer)) {
  940. hit.componentId = id;
  941. hit.context = component.context;
  942. hit.rect.left += originLeft;
  943. hit.rect.right += originLeft;
  944. hit.rect.top += originTop;
  945. hit.rect.bottom += originTop;
  946. bestHit = hit;
  947. }
  948. }
  949. }
  950. }
  951. return bestHit;
  952. }
  953. };
  954. function isHitsEqual(hit0, hit1) {
  955. if (!hit0 && !hit1) {
  956. return true;
  957. }
  958. if (Boolean(hit0) !== Boolean(hit1)) {
  959. return false;
  960. }
  961. return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
  962. }
  963. function buildDatePointApiWithContext(dateSpan, context) {
  964. let props = {};
  965. for (let transform of context.pluginHooks.datePointTransforms) {
  966. Object.assign(props, transform(dateSpan, context));
  967. }
  968. Object.assign(props, buildDatePointApi(dateSpan, context.dateEnv));
  969. return props;
  970. }
  971. function buildDatePointApi(span, dateEnv) {
  972. return {
  973. date: dateEnv.toDate(span.range.start),
  974. dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),
  975. allDay: span.allDay
  976. };
  977. }
  978. var DateClicking = class extends Interaction {
  979. constructor(settings) {
  980. super(settings);
  981. this.handlePointerDown = (pev) => {
  982. let { dragging } = this;
  983. let downEl = pev.origEvent.target;
  984. dragging.setIgnoreMove(!this.component.isValidDateDownEl(downEl));
  985. };
  986. this.handleDragEnd = (ev) => {
  987. let { component } = this;
  988. let { pointer } = this.dragging;
  989. if (!pointer.wasTouchScroll) {
  990. let { initialHit, finalHit } = this.hitDragging;
  991. if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
  992. let { context } = component;
  993. let arg = Object.assign(Object.assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });
  994. context.emitter.trigger("dateClick", arg);
  995. }
  996. }
  997. };
  998. this.dragging = new FeaturefulElementDragging(settings.el);
  999. this.dragging.autoScroller.isEnabled = false;
  1000. let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings));
  1001. hitDragging.emitter.on("pointerdown", this.handlePointerDown);
  1002. hitDragging.emitter.on("dragend", this.handleDragEnd);
  1003. }
  1004. destroy() {
  1005. this.dragging.destroy();
  1006. }
  1007. };
  1008. var DateSelecting = class extends Interaction {
  1009. constructor(settings) {
  1010. super(settings);
  1011. this.dragSelection = null;
  1012. this.handlePointerDown = (ev) => {
  1013. let { component: component2, dragging: dragging2 } = this;
  1014. let { options: options2 } = component2.context;
  1015. let canSelect = options2.selectable && component2.isValidDateDownEl(ev.origEvent.target);
  1016. dragging2.setIgnoreMove(!canSelect);
  1017. dragging2.delay = ev.isTouch ? getComponentTouchDelay$1(component2) : null;
  1018. };
  1019. this.handleDragStart = (ev) => {
  1020. this.component.context.calendarApi.unselect(ev);
  1021. };
  1022. this.handleHitUpdate = (hit, isFinal) => {
  1023. let { context } = this.component;
  1024. let dragSelection = null;
  1025. let isInvalid = false;
  1026. if (hit) {
  1027. let initialHit = this.hitDragging.initialHit;
  1028. let disallowed = hit.componentId === initialHit.componentId && this.isHitComboAllowed && !this.isHitComboAllowed(initialHit, hit);
  1029. if (!disallowed) {
  1030. dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers);
  1031. }
  1032. if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) {
  1033. isInvalid = true;
  1034. dragSelection = null;
  1035. }
  1036. }
  1037. if (dragSelection) {
  1038. context.dispatch({ type: "SELECT_DATES", selection: dragSelection });
  1039. } else if (!isFinal) {
  1040. context.dispatch({ type: "UNSELECT_DATES" });
  1041. }
  1042. if (!isInvalid) {
  1043. enableCursor();
  1044. } else {
  1045. disableCursor();
  1046. }
  1047. if (!isFinal) {
  1048. this.dragSelection = dragSelection;
  1049. }
  1050. };
  1051. this.handlePointerUp = (pev) => {
  1052. if (this.dragSelection) {
  1053. triggerDateSelect(this.dragSelection, pev, this.component.context);
  1054. this.dragSelection = null;
  1055. }
  1056. };
  1057. let { component } = settings;
  1058. let { options } = component.context;
  1059. let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
  1060. dragging.touchScrollAllowed = false;
  1061. dragging.minDistance = options.selectMinDistance || 0;
  1062. dragging.autoScroller.isEnabled = options.dragScroll;
  1063. let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings));
  1064. hitDragging.emitter.on("pointerdown", this.handlePointerDown);
  1065. hitDragging.emitter.on("dragstart", this.handleDragStart);
  1066. hitDragging.emitter.on("hitupdate", this.handleHitUpdate);
  1067. hitDragging.emitter.on("pointerup", this.handlePointerUp);
  1068. }
  1069. destroy() {
  1070. this.dragging.destroy();
  1071. }
  1072. };
  1073. function getComponentTouchDelay$1(component) {
  1074. let { options } = component.context;
  1075. let delay = options.selectLongPressDelay;
  1076. if (delay == null) {
  1077. delay = options.longPressDelay;
  1078. }
  1079. return delay;
  1080. }
  1081. function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
  1082. let dateSpan0 = hit0.dateSpan;
  1083. let dateSpan1 = hit1.dateSpan;
  1084. let ms = [
  1085. dateSpan0.range.start,
  1086. dateSpan0.range.end,
  1087. dateSpan1.range.start,
  1088. dateSpan1.range.end
  1089. ];
  1090. ms.sort(compareNumbers);
  1091. let props = {};
  1092. for (let transformer of dateSelectionTransformers) {
  1093. let res = transformer(hit0, hit1);
  1094. if (res === false) {
  1095. return null;
  1096. }
  1097. if (res) {
  1098. Object.assign(props, res);
  1099. }
  1100. }
  1101. props.range = { start: ms[0], end: ms[3] };
  1102. props.allDay = dateSpan0.allDay;
  1103. return props;
  1104. }
  1105. var EventDragging = class _EventDragging extends Interaction {
  1106. constructor(settings) {
  1107. super(settings);
  1108. this.subjectEl = null;
  1109. this.subjectSeg = null;
  1110. this.isDragging = false;
  1111. this.eventRange = null;
  1112. this.relevantEvents = null;
  1113. this.receivingContext = null;
  1114. this.validMutation = null;
  1115. this.mutatedRelevantEvents = null;
  1116. this.handlePointerDown = (ev) => {
  1117. let origTarget = ev.origEvent.target;
  1118. let { component: component2, dragging: dragging2 } = this;
  1119. let { mirror } = dragging2;
  1120. let { options: options2 } = component2.context;
  1121. let initialContext = component2.context;
  1122. this.subjectEl = ev.subjectEl;
  1123. let subjectSeg = this.subjectSeg = getElSeg(ev.subjectEl);
  1124. let eventRange = this.eventRange = subjectSeg.eventRange;
  1125. let eventInstanceId = eventRange.instance.instanceId;
  1126. this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId);
  1127. dragging2.minDistance = ev.isTouch ? 0 : options2.eventDragMinDistance;
  1128. dragging2.delay = // only do a touch delay if touch and this event hasn't been selected yet
  1129. ev.isTouch && eventInstanceId !== component2.props.eventSelection ? getComponentTouchDelay(component2) : null;
  1130. if (options2.fixedMirrorParent) {
  1131. mirror.parentNode = options2.fixedMirrorParent;
  1132. } else {
  1133. mirror.parentNode = elementClosest(origTarget, ".fc");
  1134. }
  1135. mirror.revertDuration = options2.dragRevertDuration;
  1136. let isValid = component2.isValidSegDownEl(origTarget) && !elementClosest(origTarget, ".fc-event-resizer");
  1137. dragging2.setIgnoreMove(!isValid);
  1138. this.isDragging = isValid && ev.subjectEl.classList.contains("fc-event-draggable");
  1139. };
  1140. this.handleDragStart = (ev) => {
  1141. let initialContext = this.component.context;
  1142. let eventRange = this.eventRange;
  1143. let eventInstanceId = eventRange.instance.instanceId;
  1144. if (ev.isTouch) {
  1145. if (eventInstanceId !== this.component.props.eventSelection) {
  1146. initialContext.dispatch({ type: "SELECT_EVENT", eventInstanceId });
  1147. }
  1148. } else {
  1149. initialContext.dispatch({ type: "UNSELECT_EVENT" });
  1150. }
  1151. if (this.isDragging) {
  1152. initialContext.calendarApi.unselect(ev);
  1153. initialContext.emitter.trigger("eventDragStart", {
  1154. el: this.subjectEl,
  1155. event: new EventImpl(initialContext, eventRange.def, eventRange.instance),
  1156. jsEvent: ev.origEvent,
  1157. view: initialContext.viewApi
  1158. });
  1159. }
  1160. };
  1161. this.handleHitUpdate = (hit, isFinal) => {
  1162. if (!this.isDragging) {
  1163. return;
  1164. }
  1165. let relevantEvents = this.relevantEvents;
  1166. let initialHit = this.hitDragging.initialHit;
  1167. let initialContext = this.component.context;
  1168. let receivingContext = null;
  1169. let mutation = null;
  1170. let mutatedRelevantEvents = null;
  1171. let isInvalid = false;
  1172. let interaction = {
  1173. affectedEvents: relevantEvents,
  1174. mutatedEvents: createEmptyEventStore(),
  1175. isEvent: true
  1176. };
  1177. if (hit) {
  1178. receivingContext = hit.context;
  1179. let receivingOptions = receivingContext.options;
  1180. if (initialContext === receivingContext || receivingOptions.editable && receivingOptions.droppable) {
  1181. mutation = computeEventMutation(initialHit, hit, this.eventRange.instance.range.start, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
  1182. if (mutation) {
  1183. mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
  1184. interaction.mutatedEvents = mutatedRelevantEvents;
  1185. if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) {
  1186. isInvalid = true;
  1187. mutation = null;
  1188. mutatedRelevantEvents = null;
  1189. interaction.mutatedEvents = createEmptyEventStore();
  1190. }
  1191. }
  1192. } else {
  1193. receivingContext = null;
  1194. }
  1195. }
  1196. this.displayDrag(receivingContext, interaction);
  1197. if (!isInvalid) {
  1198. enableCursor();
  1199. } else {
  1200. disableCursor();
  1201. }
  1202. if (!isFinal) {
  1203. if (initialContext === receivingContext && // TODO: write test for this
  1204. isHitsEqual(initialHit, hit)) {
  1205. mutation = null;
  1206. }
  1207. this.dragging.setMirrorNeedsRevert(!mutation);
  1208. this.dragging.setMirrorIsVisible(!hit || !this.subjectEl.getRootNode().querySelector(".fc-event-mirror"));
  1209. this.receivingContext = receivingContext;
  1210. this.validMutation = mutation;
  1211. this.mutatedRelevantEvents = mutatedRelevantEvents;
  1212. }
  1213. };
  1214. this.handlePointerUp = () => {
  1215. if (!this.isDragging) {
  1216. this.cleanup();
  1217. }
  1218. };
  1219. this.handleDragEnd = (ev) => {
  1220. if (this.isDragging) {
  1221. let initialContext = this.component.context;
  1222. let initialView = initialContext.viewApi;
  1223. let { receivingContext, validMutation } = this;
  1224. let eventDef = this.eventRange.def;
  1225. let eventInstance = this.eventRange.instance;
  1226. let eventApi = new EventImpl(initialContext, eventDef, eventInstance);
  1227. let relevantEvents = this.relevantEvents;
  1228. let mutatedRelevantEvents = this.mutatedRelevantEvents;
  1229. let { finalHit } = this.hitDragging;
  1230. this.clearDrag();
  1231. initialContext.emitter.trigger("eventDragStop", {
  1232. el: this.subjectEl,
  1233. event: eventApi,
  1234. jsEvent: ev.origEvent,
  1235. view: initialView
  1236. });
  1237. if (validMutation) {
  1238. if (receivingContext === initialContext) {
  1239. let updatedEventApi = new EventImpl(initialContext, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
  1240. initialContext.dispatch({
  1241. type: "MERGE_EVENTS",
  1242. eventStore: mutatedRelevantEvents
  1243. });
  1244. let eventChangeArg = {
  1245. oldEvent: eventApi,
  1246. event: updatedEventApi,
  1247. relatedEvents: buildEventApis(mutatedRelevantEvents, initialContext, eventInstance),
  1248. revert() {
  1249. initialContext.dispatch({
  1250. type: "MERGE_EVENTS",
  1251. eventStore: relevantEvents
  1252. // the pre-change data
  1253. });
  1254. }
  1255. };
  1256. let transformed = {};
  1257. for (let transformer of initialContext.getCurrentData().pluginHooks.eventDropTransformers) {
  1258. Object.assign(transformed, transformer(validMutation, initialContext));
  1259. }
  1260. initialContext.emitter.trigger("eventDrop", Object.assign(Object.assign(Object.assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));
  1261. initialContext.emitter.trigger("eventChange", eventChangeArg);
  1262. } else if (receivingContext) {
  1263. let eventRemoveArg = {
  1264. event: eventApi,
  1265. relatedEvents: buildEventApis(relevantEvents, initialContext, eventInstance),
  1266. revert() {
  1267. initialContext.dispatch({
  1268. type: "MERGE_EVENTS",
  1269. eventStore: relevantEvents
  1270. });
  1271. }
  1272. };
  1273. initialContext.emitter.trigger("eventLeave", Object.assign(Object.assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));
  1274. initialContext.dispatch({
  1275. type: "REMOVE_EVENTS",
  1276. eventStore: relevantEvents
  1277. });
  1278. initialContext.emitter.trigger("eventRemove", eventRemoveArg);
  1279. let addedEventDef = mutatedRelevantEvents.defs[eventDef.defId];
  1280. let addedEventInstance = mutatedRelevantEvents.instances[eventInstance.instanceId];
  1281. let addedEventApi = new EventImpl(receivingContext, addedEventDef, addedEventInstance);
  1282. receivingContext.dispatch({
  1283. type: "MERGE_EVENTS",
  1284. eventStore: mutatedRelevantEvents
  1285. });
  1286. let eventAddArg = {
  1287. event: addedEventApi,
  1288. relatedEvents: buildEventApis(mutatedRelevantEvents, receivingContext, addedEventInstance),
  1289. revert() {
  1290. receivingContext.dispatch({
  1291. type: "REMOVE_EVENTS",
  1292. eventStore: mutatedRelevantEvents
  1293. });
  1294. }
  1295. };
  1296. receivingContext.emitter.trigger("eventAdd", eventAddArg);
  1297. if (ev.isTouch) {
  1298. receivingContext.dispatch({
  1299. type: "SELECT_EVENT",
  1300. eventInstanceId: eventInstance.instanceId
  1301. });
  1302. }
  1303. receivingContext.emitter.trigger("drop", Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi }));
  1304. receivingContext.emitter.trigger("eventReceive", Object.assign(Object.assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi }));
  1305. }
  1306. } else {
  1307. initialContext.emitter.trigger("_noEventDrop");
  1308. }
  1309. }
  1310. this.cleanup();
  1311. };
  1312. let { component } = this;
  1313. let { options } = component.context;
  1314. let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
  1315. dragging.pointer.selector = _EventDragging.SELECTOR;
  1316. dragging.touchScrollAllowed = false;
  1317. dragging.autoScroller.isEnabled = options.dragScroll;
  1318. let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsStore);
  1319. hitDragging.useSubjectCenter = settings.useEventCenter;
  1320. hitDragging.emitter.on("pointerdown", this.handlePointerDown);
  1321. hitDragging.emitter.on("dragstart", this.handleDragStart);
  1322. hitDragging.emitter.on("hitupdate", this.handleHitUpdate);
  1323. hitDragging.emitter.on("pointerup", this.handlePointerUp);
  1324. hitDragging.emitter.on("dragend", this.handleDragEnd);
  1325. }
  1326. destroy() {
  1327. this.dragging.destroy();
  1328. }
  1329. // render a drag state on the next receivingCalendar
  1330. displayDrag(nextContext, state) {
  1331. let initialContext = this.component.context;
  1332. let prevContext = this.receivingContext;
  1333. if (prevContext && prevContext !== nextContext) {
  1334. if (prevContext === initialContext) {
  1335. prevContext.dispatch({
  1336. type: "SET_EVENT_DRAG",
  1337. state: {
  1338. affectedEvents: state.affectedEvents,
  1339. mutatedEvents: createEmptyEventStore(),
  1340. isEvent: true
  1341. }
  1342. });
  1343. } else {
  1344. prevContext.dispatch({ type: "UNSET_EVENT_DRAG" });
  1345. }
  1346. }
  1347. if (nextContext) {
  1348. nextContext.dispatch({ type: "SET_EVENT_DRAG", state });
  1349. }
  1350. }
  1351. clearDrag() {
  1352. let initialCalendar = this.component.context;
  1353. let { receivingContext } = this;
  1354. if (receivingContext) {
  1355. receivingContext.dispatch({ type: "UNSET_EVENT_DRAG" });
  1356. }
  1357. if (initialCalendar !== receivingContext) {
  1358. initialCalendar.dispatch({ type: "UNSET_EVENT_DRAG" });
  1359. }
  1360. }
  1361. cleanup() {
  1362. this.subjectSeg = null;
  1363. this.isDragging = false;
  1364. this.eventRange = null;
  1365. this.relevantEvents = null;
  1366. this.receivingContext = null;
  1367. this.validMutation = null;
  1368. this.mutatedRelevantEvents = null;
  1369. }
  1370. };
  1371. EventDragging.SELECTOR = ".fc-event-draggable, .fc-event-resizable";
  1372. function computeEventMutation(hit0, hit1, eventInstanceStart, massagers) {
  1373. let dateSpan0 = hit0.dateSpan;
  1374. let dateSpan1 = hit1.dateSpan;
  1375. let date0 = dateSpan0.range.start;
  1376. let date1 = dateSpan1.range.start;
  1377. let standardProps = {};
  1378. if (dateSpan0.allDay !== dateSpan1.allDay) {
  1379. standardProps.allDay = dateSpan1.allDay;
  1380. standardProps.hasEnd = hit1.context.options.allDayMaintainDuration;
  1381. if (dateSpan1.allDay) {
  1382. date0 = startOfDay(eventInstanceStart);
  1383. } else {
  1384. date0 = eventInstanceStart;
  1385. }
  1386. }
  1387. let delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? hit0.largeUnit : null);
  1388. if (delta.milliseconds) {
  1389. standardProps.allDay = false;
  1390. }
  1391. let mutation = {
  1392. datesDelta: delta,
  1393. standardProps
  1394. };
  1395. for (let massager of massagers) {
  1396. massager(mutation, hit0, hit1);
  1397. }
  1398. return mutation;
  1399. }
  1400. function getComponentTouchDelay(component) {
  1401. let { options } = component.context;
  1402. let delay = options.eventLongPressDelay;
  1403. if (delay == null) {
  1404. delay = options.longPressDelay;
  1405. }
  1406. return delay;
  1407. }
  1408. var EventResizing = class extends Interaction {
  1409. constructor(settings) {
  1410. super(settings);
  1411. this.draggingSegEl = null;
  1412. this.draggingSeg = null;
  1413. this.eventRange = null;
  1414. this.relevantEvents = null;
  1415. this.validMutation = null;
  1416. this.mutatedRelevantEvents = null;
  1417. this.handlePointerDown = (ev) => {
  1418. let { component: component2 } = this;
  1419. let segEl = this.querySegEl(ev);
  1420. let seg = getElSeg(segEl);
  1421. let eventRange = this.eventRange = seg.eventRange;
  1422. this.dragging.minDistance = component2.context.options.eventDragMinDistance;
  1423. this.dragging.setIgnoreMove(!this.component.isValidSegDownEl(ev.origEvent.target) || ev.isTouch && this.component.props.eventSelection !== eventRange.instance.instanceId);
  1424. };
  1425. this.handleDragStart = (ev) => {
  1426. let { context } = this.component;
  1427. let eventRange = this.eventRange;
  1428. this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, this.eventRange.instance.instanceId);
  1429. let segEl = this.querySegEl(ev);
  1430. this.draggingSegEl = segEl;
  1431. this.draggingSeg = getElSeg(segEl);
  1432. context.calendarApi.unselect();
  1433. context.emitter.trigger("eventResizeStart", {
  1434. el: segEl,
  1435. event: new EventImpl(context, eventRange.def, eventRange.instance),
  1436. jsEvent: ev.origEvent,
  1437. view: context.viewApi
  1438. });
  1439. };
  1440. this.handleHitUpdate = (hit, isFinal, ev) => {
  1441. let { context } = this.component;
  1442. let relevantEvents = this.relevantEvents;
  1443. let initialHit = this.hitDragging.initialHit;
  1444. let eventInstance = this.eventRange.instance;
  1445. let mutation = null;
  1446. let mutatedRelevantEvents = null;
  1447. let isInvalid = false;
  1448. let interaction = {
  1449. affectedEvents: relevantEvents,
  1450. mutatedEvents: createEmptyEventStore(),
  1451. isEvent: true
  1452. };
  1453. if (hit) {
  1454. let disallowed = hit.componentId === initialHit.componentId && this.isHitComboAllowed && !this.isHitComboAllowed(initialHit, hit);
  1455. if (!disallowed) {
  1456. mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains("fc-event-resizer-start"), eventInstance.range);
  1457. }
  1458. }
  1459. if (mutation) {
  1460. mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
  1461. interaction.mutatedEvents = mutatedRelevantEvents;
  1462. if (!isInteractionValid(interaction, hit.dateProfile, context)) {
  1463. isInvalid = true;
  1464. mutation = null;
  1465. mutatedRelevantEvents = null;
  1466. interaction.mutatedEvents = null;
  1467. }
  1468. }
  1469. if (mutatedRelevantEvents) {
  1470. context.dispatch({
  1471. type: "SET_EVENT_RESIZE",
  1472. state: interaction
  1473. });
  1474. } else {
  1475. context.dispatch({ type: "UNSET_EVENT_RESIZE" });
  1476. }
  1477. if (!isInvalid) {
  1478. enableCursor();
  1479. } else {
  1480. disableCursor();
  1481. }
  1482. if (!isFinal) {
  1483. if (mutation && isHitsEqual(initialHit, hit)) {
  1484. mutation = null;
  1485. }
  1486. this.validMutation = mutation;
  1487. this.mutatedRelevantEvents = mutatedRelevantEvents;
  1488. }
  1489. };
  1490. this.handleDragEnd = (ev) => {
  1491. let { context } = this.component;
  1492. let eventDef = this.eventRange.def;
  1493. let eventInstance = this.eventRange.instance;
  1494. let eventApi = new EventImpl(context, eventDef, eventInstance);
  1495. let relevantEvents = this.relevantEvents;
  1496. let mutatedRelevantEvents = this.mutatedRelevantEvents;
  1497. context.emitter.trigger("eventResizeStop", {
  1498. el: this.draggingSegEl,
  1499. event: eventApi,
  1500. jsEvent: ev.origEvent,
  1501. view: context.viewApi
  1502. });
  1503. if (this.validMutation) {
  1504. let updatedEventApi = new EventImpl(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
  1505. context.dispatch({
  1506. type: "MERGE_EVENTS",
  1507. eventStore: mutatedRelevantEvents
  1508. });
  1509. let eventChangeArg = {
  1510. oldEvent: eventApi,
  1511. event: updatedEventApi,
  1512. relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance),
  1513. revert() {
  1514. context.dispatch({
  1515. type: "MERGE_EVENTS",
  1516. eventStore: relevantEvents
  1517. // the pre-change events
  1518. });
  1519. }
  1520. };
  1521. context.emitter.trigger("eventResize", Object.assign(Object.assign({}, eventChangeArg), { el: this.draggingSegEl, startDelta: this.validMutation.startDelta || createDuration(0), endDelta: this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi }));
  1522. context.emitter.trigger("eventChange", eventChangeArg);
  1523. } else {
  1524. context.emitter.trigger("_noEventResize");
  1525. }
  1526. this.draggingSeg = null;
  1527. this.relevantEvents = null;
  1528. this.validMutation = null;
  1529. };
  1530. let { component } = settings;
  1531. let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
  1532. dragging.pointer.selector = ".fc-event-resizer";
  1533. dragging.touchScrollAllowed = false;
  1534. dragging.autoScroller.isEnabled = component.context.options.dragScroll;
  1535. let hitDragging = this.hitDragging = new HitDragging(this.dragging, interactionSettingsToStore(settings));
  1536. hitDragging.emitter.on("pointerdown", this.handlePointerDown);
  1537. hitDragging.emitter.on("dragstart", this.handleDragStart);
  1538. hitDragging.emitter.on("hitupdate", this.handleHitUpdate);
  1539. hitDragging.emitter.on("dragend", this.handleDragEnd);
  1540. }
  1541. destroy() {
  1542. this.dragging.destroy();
  1543. }
  1544. querySegEl(ev) {
  1545. return elementClosest(ev.subjectEl, ".fc-event");
  1546. }
  1547. };
  1548. function computeMutation(hit0, hit1, isFromStart, instanceRange) {
  1549. let dateEnv = hit0.context.dateEnv;
  1550. let date0 = hit0.dateSpan.range.start;
  1551. let date1 = hit1.dateSpan.range.start;
  1552. let delta = diffDates(date0, date1, dateEnv, hit0.largeUnit);
  1553. if (isFromStart) {
  1554. if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
  1555. return { startDelta: delta };
  1556. }
  1557. } else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
  1558. return { endDelta: delta };
  1559. }
  1560. return null;
  1561. }
  1562. var UnselectAuto = class {
  1563. constructor(context) {
  1564. this.context = context;
  1565. this.isRecentPointerDateSelect = false;
  1566. this.matchesCancel = false;
  1567. this.matchesEvent = false;
  1568. this.onSelect = (selectInfo) => {
  1569. if (selectInfo.jsEvent) {
  1570. this.isRecentPointerDateSelect = true;
  1571. }
  1572. };
  1573. this.onDocumentPointerDown = (pev) => {
  1574. let unselectCancel = this.context.options.unselectCancel;
  1575. let downEl = getEventTargetViaRoot(pev.origEvent);
  1576. this.matchesCancel = !!elementClosest(downEl, unselectCancel);
  1577. this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR);
  1578. };
  1579. this.onDocumentPointerUp = (pev) => {
  1580. let { context: context2 } = this;
  1581. let { documentPointer: documentPointer2 } = this;
  1582. let calendarState = context2.getCurrentData();
  1583. if (!documentPointer2.wasTouchScroll) {
  1584. if (calendarState.dateSelection && // an existing date selection?
  1585. !this.isRecentPointerDateSelect) {
  1586. let unselectAuto = context2.options.unselectAuto;
  1587. if (unselectAuto && (!unselectAuto || !this.matchesCancel)) {
  1588. context2.calendarApi.unselect(pev);
  1589. }
  1590. }
  1591. if (calendarState.eventSelection && // an existing event selected?
  1592. !this.matchesEvent) {
  1593. context2.dispatch({ type: "UNSELECT_EVENT" });
  1594. }
  1595. }
  1596. this.isRecentPointerDateSelect = false;
  1597. };
  1598. let documentPointer = this.documentPointer = new PointerDragging(document);
  1599. documentPointer.shouldIgnoreMove = true;
  1600. documentPointer.shouldWatchScroll = false;
  1601. documentPointer.emitter.on("pointerdown", this.onDocumentPointerDown);
  1602. documentPointer.emitter.on("pointerup", this.onDocumentPointerUp);
  1603. context.emitter.on("select", this.onSelect);
  1604. }
  1605. destroy() {
  1606. this.context.emitter.off("select", this.onSelect);
  1607. this.documentPointer.destroy();
  1608. }
  1609. };
  1610. var OPTION_REFINERS = {
  1611. fixedMirrorParent: identity
  1612. };
  1613. var LISTENER_REFINERS = {
  1614. dateClick: identity,
  1615. eventDragStart: identity,
  1616. eventDragStop: identity,
  1617. eventDrop: identity,
  1618. eventResizeStart: identity,
  1619. eventResizeStop: identity,
  1620. eventResize: identity,
  1621. drop: identity,
  1622. eventReceive: identity,
  1623. eventLeave: identity
  1624. };
  1625. var ExternalElementDragging = class {
  1626. constructor(dragging, suppliedDragMeta) {
  1627. this.receivingContext = null;
  1628. this.droppableEvent = null;
  1629. this.suppliedDragMeta = null;
  1630. this.dragMeta = null;
  1631. this.handleDragStart = (ev) => {
  1632. this.dragMeta = this.buildDragMeta(ev.subjectEl);
  1633. };
  1634. this.handleHitUpdate = (hit, isFinal, ev) => {
  1635. let { dragging: dragging2 } = this.hitDragging;
  1636. let receivingContext = null;
  1637. let droppableEvent = null;
  1638. let isInvalid = false;
  1639. let interaction = {
  1640. affectedEvents: createEmptyEventStore(),
  1641. mutatedEvents: createEmptyEventStore(),
  1642. isEvent: this.dragMeta.create
  1643. };
  1644. if (hit) {
  1645. receivingContext = hit.context;
  1646. if (this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
  1647. droppableEvent = computeEventForDateSpan(hit.dateSpan, this.dragMeta, receivingContext);
  1648. interaction.mutatedEvents = eventTupleToStore(droppableEvent);
  1649. isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext);
  1650. if (isInvalid) {
  1651. interaction.mutatedEvents = createEmptyEventStore();
  1652. droppableEvent = null;
  1653. }
  1654. }
  1655. }
  1656. this.displayDrag(receivingContext, interaction);
  1657. dragging2.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector(".fc-event-mirror"));
  1658. if (!isInvalid) {
  1659. enableCursor();
  1660. } else {
  1661. disableCursor();
  1662. }
  1663. if (!isFinal) {
  1664. dragging2.setMirrorNeedsRevert(!droppableEvent);
  1665. this.receivingContext = receivingContext;
  1666. this.droppableEvent = droppableEvent;
  1667. }
  1668. };
  1669. this.handleDragEnd = (pev) => {
  1670. let { receivingContext, droppableEvent } = this;
  1671. this.clearDrag();
  1672. if (receivingContext && droppableEvent) {
  1673. let finalHit = this.hitDragging.finalHit;
  1674. let finalView = finalHit.context.viewApi;
  1675. let dragMeta = this.dragMeta;
  1676. receivingContext.emitter.trigger("drop", Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));
  1677. if (dragMeta.create) {
  1678. let addingEvents = eventTupleToStore(droppableEvent);
  1679. receivingContext.dispatch({
  1680. type: "MERGE_EVENTS",
  1681. eventStore: addingEvents
  1682. });
  1683. if (pev.isTouch) {
  1684. receivingContext.dispatch({
  1685. type: "SELECT_EVENT",
  1686. eventInstanceId: droppableEvent.instance.instanceId
  1687. });
  1688. }
  1689. receivingContext.emitter.trigger("eventReceive", {
  1690. event: new EventImpl(receivingContext, droppableEvent.def, droppableEvent.instance),
  1691. relatedEvents: [],
  1692. revert() {
  1693. receivingContext.dispatch({
  1694. type: "REMOVE_EVENTS",
  1695. eventStore: addingEvents
  1696. });
  1697. },
  1698. draggedEl: pev.subjectEl,
  1699. view: finalView
  1700. });
  1701. }
  1702. }
  1703. this.receivingContext = null;
  1704. this.droppableEvent = null;
  1705. };
  1706. let hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore);
  1707. hitDragging.requireInitial = false;
  1708. hitDragging.emitter.on("dragstart", this.handleDragStart);
  1709. hitDragging.emitter.on("hitupdate", this.handleHitUpdate);
  1710. hitDragging.emitter.on("dragend", this.handleDragEnd);
  1711. this.suppliedDragMeta = suppliedDragMeta;
  1712. }
  1713. buildDragMeta(subjectEl) {
  1714. if (typeof this.suppliedDragMeta === "object") {
  1715. return parseDragMeta(this.suppliedDragMeta);
  1716. }
  1717. if (typeof this.suppliedDragMeta === "function") {
  1718. return parseDragMeta(this.suppliedDragMeta(subjectEl));
  1719. }
  1720. return getDragMetaFromEl(subjectEl);
  1721. }
  1722. displayDrag(nextContext, state) {
  1723. let prevContext = this.receivingContext;
  1724. if (prevContext && prevContext !== nextContext) {
  1725. prevContext.dispatch({ type: "UNSET_EVENT_DRAG" });
  1726. }
  1727. if (nextContext) {
  1728. nextContext.dispatch({ type: "SET_EVENT_DRAG", state });
  1729. }
  1730. }
  1731. clearDrag() {
  1732. if (this.receivingContext) {
  1733. this.receivingContext.dispatch({ type: "UNSET_EVENT_DRAG" });
  1734. }
  1735. }
  1736. canDropElOnCalendar(el, receivingContext) {
  1737. let dropAccept = receivingContext.options.dropAccept;
  1738. if (typeof dropAccept === "function") {
  1739. return dropAccept.call(receivingContext.calendarApi, el);
  1740. }
  1741. if (typeof dropAccept === "string" && dropAccept) {
  1742. return Boolean(elementMatches(el, dropAccept));
  1743. }
  1744. return true;
  1745. }
  1746. };
  1747. function computeEventForDateSpan(dateSpan, dragMeta, context) {
  1748. let defProps = Object.assign({}, dragMeta.leftoverProps);
  1749. for (let transform of context.pluginHooks.externalDefTransforms) {
  1750. Object.assign(defProps, transform(dateSpan, dragMeta));
  1751. }
  1752. let { refined, extra } = refineEventDef(defProps, context);
  1753. let def = parseEventDef(
  1754. refined,
  1755. extra,
  1756. dragMeta.sourceId,
  1757. dateSpan.allDay,
  1758. context.options.forceEventDuration || Boolean(dragMeta.duration),
  1759. // hasEnd
  1760. context
  1761. );
  1762. let start = dateSpan.range.start;
  1763. if (dateSpan.allDay && dragMeta.startTime) {
  1764. start = context.dateEnv.add(start, dragMeta.startTime);
  1765. }
  1766. let end = dragMeta.duration ? context.dateEnv.add(start, dragMeta.duration) : getDefaultEventEnd(dateSpan.allDay, start, context);
  1767. let instance = createEventInstance(def.defId, { start, end });
  1768. return { def, instance };
  1769. }
  1770. function getDragMetaFromEl(el) {
  1771. let str = getEmbeddedElData(el, "event");
  1772. let obj = str ? JSON.parse(str) : { create: false };
  1773. return parseDragMeta(obj);
  1774. }
  1775. config.dataAttrPrefix = "";
  1776. function getEmbeddedElData(el, name) {
  1777. let prefix = config.dataAttrPrefix;
  1778. let prefixedName = (prefix ? prefix + "-" : "") + name;
  1779. return el.getAttribute("data-" + prefixedName) || "";
  1780. }
  1781. var ExternalDraggable = class {
  1782. constructor(el, settings = {}) {
  1783. this.handlePointerDown = (ev) => {
  1784. let { dragging: dragging2 } = this;
  1785. let { minDistance, longPressDelay } = this.settings;
  1786. dragging2.minDistance = minDistance != null ? minDistance : ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance;
  1787. dragging2.delay = ev.isTouch ? (
  1788. // TODO: eventually read eventLongPressDelay instead vvv
  1789. longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay
  1790. ) : 0;
  1791. };
  1792. this.handleDragStart = (ev) => {
  1793. if (ev.isTouch && this.dragging.delay && ev.subjectEl.classList.contains("fc-event")) {
  1794. this.dragging.mirror.getMirrorEl().classList.add("fc-event-selected");
  1795. }
  1796. };
  1797. this.settings = settings;
  1798. let dragging = this.dragging = new FeaturefulElementDragging(el);
  1799. dragging.touchScrollAllowed = false;
  1800. if (settings.itemSelector != null) {
  1801. dragging.pointer.selector = settings.itemSelector;
  1802. }
  1803. if (settings.appendTo != null) {
  1804. dragging.mirror.parentNode = settings.appendTo;
  1805. }
  1806. dragging.emitter.on("pointerdown", this.handlePointerDown);
  1807. dragging.emitter.on("dragstart", this.handleDragStart);
  1808. new ExternalElementDragging(dragging, settings.eventData);
  1809. }
  1810. destroy() {
  1811. this.dragging.destroy();
  1812. }
  1813. };
  1814. var InferredElementDragging = class extends ElementDragging {
  1815. constructor(containerEl) {
  1816. super(containerEl);
  1817. this.shouldIgnoreMove = false;
  1818. this.mirrorSelector = "";
  1819. this.currentMirrorEl = null;
  1820. this.handlePointerDown = (ev) => {
  1821. this.emitter.trigger("pointerdown", ev);
  1822. if (!this.shouldIgnoreMove) {
  1823. this.emitter.trigger("dragstart", ev);
  1824. }
  1825. };
  1826. this.handlePointerMove = (ev) => {
  1827. if (!this.shouldIgnoreMove) {
  1828. this.emitter.trigger("dragmove", ev);
  1829. }
  1830. };
  1831. this.handlePointerUp = (ev) => {
  1832. this.emitter.trigger("pointerup", ev);
  1833. if (!this.shouldIgnoreMove) {
  1834. this.emitter.trigger("dragend", ev);
  1835. }
  1836. };
  1837. let pointer = this.pointer = new PointerDragging(containerEl);
  1838. pointer.emitter.on("pointerdown", this.handlePointerDown);
  1839. pointer.emitter.on("pointermove", this.handlePointerMove);
  1840. pointer.emitter.on("pointerup", this.handlePointerUp);
  1841. }
  1842. destroy() {
  1843. this.pointer.destroy();
  1844. }
  1845. setIgnoreMove(bool) {
  1846. this.shouldIgnoreMove = bool;
  1847. }
  1848. setMirrorIsVisible(bool) {
  1849. if (bool) {
  1850. if (this.currentMirrorEl) {
  1851. this.currentMirrorEl.style.visibility = "";
  1852. this.currentMirrorEl = null;
  1853. }
  1854. } else {
  1855. let mirrorEl = this.mirrorSelector ? document.querySelector(this.mirrorSelector) : null;
  1856. if (mirrorEl) {
  1857. this.currentMirrorEl = mirrorEl;
  1858. mirrorEl.style.visibility = "hidden";
  1859. }
  1860. }
  1861. }
  1862. };
  1863. var ThirdPartyDraggable = class {
  1864. constructor(containerOrSettings, settings) {
  1865. let containerEl = document;
  1866. if (
  1867. // wish we could just test instanceof EventTarget, but doesn't work in IE11
  1868. containerOrSettings === document || containerOrSettings instanceof Element
  1869. ) {
  1870. containerEl = containerOrSettings;
  1871. settings = settings || {};
  1872. } else {
  1873. settings = containerOrSettings || {};
  1874. }
  1875. let dragging = this.dragging = new InferredElementDragging(containerEl);
  1876. if (typeof settings.itemSelector === "string") {
  1877. dragging.pointer.selector = settings.itemSelector;
  1878. } else if (containerEl === document) {
  1879. dragging.pointer.selector = "[data-event]";
  1880. }
  1881. if (typeof settings.mirrorSelector === "string") {
  1882. dragging.mirrorSelector = settings.mirrorSelector;
  1883. }
  1884. let externalDragging = new ExternalElementDragging(dragging, settings.eventData);
  1885. externalDragging.hitDragging.disablePointCheck = true;
  1886. }
  1887. destroy() {
  1888. this.dragging.destroy();
  1889. }
  1890. };
  1891. var index = createPlugin({
  1892. name: "@fullcalendar/interaction",
  1893. componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
  1894. calendarInteractions: [UnselectAuto],
  1895. elementDraggingImpl: FeaturefulElementDragging,
  1896. optionRefiners: OPTION_REFINERS,
  1897. listenerRefiners: LISTENER_REFINERS
  1898. });
  1899. export {
  1900. ExternalDraggable as Draggable,
  1901. ThirdPartyDraggable,
  1902. index as default
  1903. };
  1904. //# sourceMappingURL=@fullcalendar_interaction.js.map