full_calendar 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +49 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +20 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +102 -0
  8. data/Rakefile +2 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/full_calendar.gemspec +28 -0
  12. data/lib/.DS_Store +0 -0
  13. data/lib/full_calendar/engine.rb +9 -0
  14. data/lib/full_calendar/version.rb +3 -0
  15. data/lib/full_calendar.rb +73 -0
  16. data/lib/generators/.DS_Store +0 -0
  17. data/lib/generators/fullcalendar/.DS_Store +0 -0
  18. data/lib/generators/fullcalendar/install_generator.rb +61 -0
  19. data/lib/generators/fullcalendar/templates/default.js.tt +13 -0
  20. data/lib/generators/fullcalendar/templates/default.scss.tt +7 -0
  21. data/vendor/.DS_Store +0 -0
  22. data/vendor/assets/.DS_Store +0 -0
  23. data/vendor/assets/javascripts/.DS_Store +0 -0
  24. data/vendor/assets/javascripts/fullcalendar/.DS_Store +0 -0
  25. data/vendor/assets/javascripts/fullcalendar/bootstrap/.DS_Store +0 -0
  26. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.js +90 -0
  27. data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.js +20 -0
  28. data/vendor/assets/javascripts/fullcalendar/core/.DS_Store +0 -0
  29. data/vendor/assets/javascripts/fullcalendar/core/locales/af.js +30 -0
  30. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-dz.js +31 -0
  31. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-kw.js +31 -0
  32. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ly.js +31 -0
  33. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ma.js +31 -0
  34. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-sa.js +31 -0
  35. data/vendor/assets/javascripts/fullcalendar/core/locales/ar-tn.js +31 -0
  36. data/vendor/assets/javascripts/fullcalendar/core/locales/ar.js +31 -0
  37. data/vendor/assets/javascripts/fullcalendar/core/locales/bg.js +31 -0
  38. data/vendor/assets/javascripts/fullcalendar/core/locales/bs.js +32 -0
  39. data/vendor/assets/javascripts/fullcalendar/core/locales/ca.js +30 -0
  40. data/vendor/assets/javascripts/fullcalendar/core/locales/cs.js +32 -0
  41. data/vendor/assets/javascripts/fullcalendar/core/locales/da.js +30 -0
  42. data/vendor/assets/javascripts/fullcalendar/core/locales/de.js +33 -0
  43. data/vendor/assets/javascripts/fullcalendar/core/locales/el.js +30 -0
  44. data/vendor/assets/javascripts/fullcalendar/core/locales/en-au.js +17 -0
  45. data/vendor/assets/javascripts/fullcalendar/core/locales/en-gb.js +17 -0
  46. data/vendor/assets/javascripts/fullcalendar/core/locales/en-nz.js +17 -0
  47. data/vendor/assets/javascripts/fullcalendar/core/locales/es-us.js +30 -0
  48. data/vendor/assets/javascripts/fullcalendar/core/locales/es.js +30 -0
  49. data/vendor/assets/javascripts/fullcalendar/core/locales/et.js +32 -0
  50. data/vendor/assets/javascripts/fullcalendar/core/locales/eu.js +30 -0
  51. data/vendor/assets/javascripts/fullcalendar/core/locales/fa.js +33 -0
  52. data/vendor/assets/javascripts/fullcalendar/core/locales/fi.js +30 -0
  53. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ca.js +27 -0
  54. data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ch.js +31 -0
  55. data/vendor/assets/javascripts/fullcalendar/core/locales/fr.js +31 -0
  56. data/vendor/assets/javascripts/fullcalendar/core/locales/gl.js +30 -0
  57. data/vendor/assets/javascripts/fullcalendar/core/locales/he.js +27 -0
  58. data/vendor/assets/javascripts/fullcalendar/core/locales/hi.js +32 -0
  59. data/vendor/assets/javascripts/fullcalendar/core/locales/hr.js +32 -0
  60. data/vendor/assets/javascripts/fullcalendar/core/locales/hu.js +30 -0
  61. data/vendor/assets/javascripts/fullcalendar/core/locales/id.js +30 -0
  62. data/vendor/assets/javascripts/fullcalendar/core/locales/is.js +30 -0
  63. data/vendor/assets/javascripts/fullcalendar/core/locales/it.js +32 -0
  64. data/vendor/assets/javascripts/fullcalendar/core/locales/ja.js +28 -0
  65. data/vendor/assets/javascripts/fullcalendar/core/locales/ka.js +32 -0
  66. data/vendor/assets/javascripts/fullcalendar/core/locales/kk.js +32 -0
  67. data/vendor/assets/javascripts/fullcalendar/core/locales/ko.js +26 -0
  68. data/vendor/assets/javascripts/fullcalendar/core/locales/lb.js +30 -0
  69. data/vendor/assets/javascripts/fullcalendar/core/locales/lt.js +30 -0
  70. data/vendor/assets/javascripts/fullcalendar/core/locales/lv.js +32 -0
  71. data/vendor/assets/javascripts/fullcalendar/core/locales/mk.js +28 -0
  72. data/vendor/assets/javascripts/fullcalendar/core/locales/ms.js +32 -0
  73. data/vendor/assets/javascripts/fullcalendar/core/locales/nb.js +30 -0
  74. data/vendor/assets/javascripts/fullcalendar/core/locales/nl.js +30 -0
  75. data/vendor/assets/javascripts/fullcalendar/core/locales/nn.js +30 -0
  76. data/vendor/assets/javascripts/fullcalendar/core/locales/pl.js +30 -0
  77. data/vendor/assets/javascripts/fullcalendar/core/locales/pt-br.js +28 -0
  78. data/vendor/assets/javascripts/fullcalendar/core/locales/pt.js +30 -0
  79. data/vendor/assets/javascripts/fullcalendar/core/locales/ro.js +32 -0
  80. data/vendor/assets/javascripts/fullcalendar/core/locales/ru.js +32 -0
  81. data/vendor/assets/javascripts/fullcalendar/core/locales/sk.js +32 -0
  82. data/vendor/assets/javascripts/fullcalendar/core/locales/sl.js +30 -0
  83. data/vendor/assets/javascripts/fullcalendar/core/locales/sq.js +32 -0
  84. data/vendor/assets/javascripts/fullcalendar/core/locales/sr-cyrl.js +32 -0
  85. data/vendor/assets/javascripts/fullcalendar/core/locales/sr.js +32 -0
  86. data/vendor/assets/javascripts/fullcalendar/core/locales/sv.js +30 -0
  87. data/vendor/assets/javascripts/fullcalendar/core/locales/th.js +25 -0
  88. data/vendor/assets/javascripts/fullcalendar/core/locales/tr.js +30 -0
  89. data/vendor/assets/javascripts/fullcalendar/core/locales/uk.js +32 -0
  90. data/vendor/assets/javascripts/fullcalendar/core/locales/vi.js +32 -0
  91. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-cn.js +33 -0
  92. data/vendor/assets/javascripts/fullcalendar/core/locales/zh-tw.js +26 -0
  93. data/vendor/assets/javascripts/fullcalendar/core/locales-all.js +1353 -0
  94. data/vendor/assets/javascripts/fullcalendar/core/locales-all.min.js +6 -0
  95. data/vendor/assets/javascripts/fullcalendar/core/main.js +8679 -0
  96. data/vendor/assets/javascripts/fullcalendar/core/main.min.js +9 -0
  97. data/vendor/assets/javascripts/fullcalendar/daygrid/.DS_Store +0 -0
  98. data/vendor/assets/javascripts/fullcalendar/daygrid/main.js +1639 -0
  99. data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.js +20 -0
  100. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.js +169 -0
  101. data/vendor/assets/javascripts/fullcalendar/google-calendar/main.min.js +20 -0
  102. data/vendor/assets/javascripts/fullcalendar/interaction/main.js +2143 -0
  103. data/vendor/assets/javascripts/fullcalendar/interaction/main.min.js +21 -0
  104. data/vendor/assets/javascripts/fullcalendar/list/.DS_Store +0 -0
  105. data/vendor/assets/javascripts/fullcalendar/list/main.js +341 -0
  106. data/vendor/assets/javascripts/fullcalendar/list/main.min.js +20 -0
  107. data/vendor/assets/javascripts/fullcalendar/luxon/main.js +162 -0
  108. data/vendor/assets/javascripts/fullcalendar/luxon/main.min.js +20 -0
  109. data/vendor/assets/javascripts/fullcalendar/moment/main.js +103 -0
  110. data/vendor/assets/javascripts/fullcalendar/moment/main.min.js +6 -0
  111. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.js +64 -0
  112. data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.min.js +20 -0
  113. data/vendor/assets/javascripts/fullcalendar/rrule/main.js +127 -0
  114. data/vendor/assets/javascripts/fullcalendar/rrule/main.min.js +20 -0
  115. data/vendor/assets/javascripts/fullcalendar/timegrid/.DS_Store +0 -0
  116. data/vendor/assets/javascripts/fullcalendar/timegrid/main.js +1354 -0
  117. data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.js +20 -0
  118. data/vendor/assets/stylesheets/.DS_Store +0 -0
  119. data/vendor/assets/stylesheets/fullcalendar/.DS_Store +0 -0
  120. data/vendor/assets/stylesheets/fullcalendar/bootstrap/.DS_Store +0 -0
  121. data/vendor/assets/stylesheets/fullcalendar/bootstrap/main.css +33 -0
  122. data/vendor/assets/stylesheets/fullcalendar/bootstrap/main.min.css +5 -0
  123. data/vendor/assets/stylesheets/fullcalendar/core/.DS_Store +0 -0
  124. data/vendor/assets/stylesheets/fullcalendar/core/main.css +900 -0
  125. data/vendor/assets/stylesheets/fullcalendar/core/main.min.css +5 -0
  126. data/vendor/assets/stylesheets/fullcalendar/daygrid/.DS_Store +0 -0
  127. data/vendor/assets/stylesheets/fullcalendar/daygrid/main.css +69 -0
  128. data/vendor/assets/stylesheets/fullcalendar/daygrid/main.min.css +5 -0
  129. data/vendor/assets/stylesheets/fullcalendar/list/.DS_Store +0 -0
  130. data/vendor/assets/stylesheets/fullcalendar/list/main.css +101 -0
  131. data/vendor/assets/stylesheets/fullcalendar/list/main.min.css +5 -0
  132. data/vendor/assets/stylesheets/fullcalendar/timegrid/.DS_Store +0 -0
  133. data/vendor/assets/stylesheets/fullcalendar/timegrid/main.css +266 -0
  134. data/vendor/assets/stylesheets/fullcalendar/timegrid/main.min.css +5 -0
  135. metadata +219 -0
@@ -0,0 +1,2143 @@
1
+ /*!
2
+ FullCalendar Interaction Plugin v4.2.0
3
+ Docs & License: https://fullcalendar.io/
4
+ (c) 2019 Adam Shaw
5
+ */
6
+ (function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
8
+ typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
9
+ (global = global || self, factory(global.FullCalendarInteraction = {}, global.FullCalendar));
10
+ }(this, function (exports, core) { 'use strict';
11
+
12
+ /*! *****************************************************************************
13
+ Copyright (c) Microsoft Corporation. All rights reserved.
14
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
15
+ this file except in compliance with the License. You may obtain a copy of the
16
+ License at http://www.apache.org/licenses/LICENSE-2.0
17
+
18
+ THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
20
+ WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
21
+ MERCHANTABLITY OR NON-INFRINGEMENT.
22
+
23
+ See the Apache Version 2.0 License for specific language governing permissions
24
+ and limitations under the License.
25
+ ***************************************************************************** */
26
+ /* global Reflect, Promise */
27
+
28
+ var extendStatics = function(d, b) {
29
+ extendStatics = Object.setPrototypeOf ||
30
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
31
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
32
+ return extendStatics(d, b);
33
+ };
34
+
35
+ function __extends(d, b) {
36
+ extendStatics(d, b);
37
+ function __() { this.constructor = d; }
38
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
39
+ }
40
+
41
+ var __assign = function() {
42
+ __assign = Object.assign || function __assign(t) {
43
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
44
+ s = arguments[i];
45
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
46
+ }
47
+ return t;
48
+ };
49
+ return __assign.apply(this, arguments);
50
+ };
51
+
52
+ core.config.touchMouseIgnoreWait = 500;
53
+ var ignoreMouseDepth = 0;
54
+ var listenerCnt = 0;
55
+ var isWindowTouchMoveCancelled = false;
56
+ /*
57
+ Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
58
+ Tracks when the pointer "drags" on a certain element, meaning down+move+up.
59
+
60
+ Also, tracks if there was touch-scrolling.
61
+ Also, can prevent touch-scrolling from happening.
62
+ Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.
63
+
64
+ emits:
65
+ - pointerdown
66
+ - pointermove
67
+ - pointerup
68
+ */
69
+ var PointerDragging = /** @class */ (function () {
70
+ function PointerDragging(containerEl) {
71
+ var _this = this;
72
+ this.subjectEl = null;
73
+ this.downEl = null;
74
+ // options that can be directly assigned by caller
75
+ this.selector = ''; // will cause subjectEl in all emitted events to be this element
76
+ this.handleSelector = '';
77
+ this.shouldIgnoreMove = false;
78
+ this.shouldWatchScroll = true; // for simulating pointermove on scroll
79
+ // internal states
80
+ this.isDragging = false;
81
+ this.isTouchDragging = false;
82
+ this.wasTouchScroll = false;
83
+ // Mouse
84
+ // ----------------------------------------------------------------------------------------------------
85
+ this.handleMouseDown = function (ev) {
86
+ if (!_this.shouldIgnoreMouse() &&
87
+ isPrimaryMouseButton(ev) &&
88
+ _this.tryStart(ev)) {
89
+ var pev = _this.createEventFromMouse(ev, true);
90
+ _this.emitter.trigger('pointerdown', pev);
91
+ _this.initScrollWatch(pev);
92
+ if (!_this.shouldIgnoreMove) {
93
+ document.addEventListener('mousemove', _this.handleMouseMove);
94
+ }
95
+ document.addEventListener('mouseup', _this.handleMouseUp);
96
+ }
97
+ };
98
+ this.handleMouseMove = function (ev) {
99
+ var pev = _this.createEventFromMouse(ev);
100
+ _this.recordCoords(pev);
101
+ _this.emitter.trigger('pointermove', pev);
102
+ };
103
+ this.handleMouseUp = function (ev) {
104
+ document.removeEventListener('mousemove', _this.handleMouseMove);
105
+ document.removeEventListener('mouseup', _this.handleMouseUp);
106
+ _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev));
107
+ _this.cleanup(); // call last so that pointerup has access to props
108
+ };
109
+ // Touch
110
+ // ----------------------------------------------------------------------------------------------------
111
+ this.handleTouchStart = function (ev) {
112
+ if (_this.tryStart(ev)) {
113
+ _this.isTouchDragging = true;
114
+ var pev = _this.createEventFromTouch(ev, true);
115
+ _this.emitter.trigger('pointerdown', pev);
116
+ _this.initScrollWatch(pev);
117
+ // unlike mouse, need to attach to target, not document
118
+ // https://stackoverflow.com/a/45760014
119
+ var target = ev.target;
120
+ if (!_this.shouldIgnoreMove) {
121
+ target.addEventListener('touchmove', _this.handleTouchMove);
122
+ }
123
+ target.addEventListener('touchend', _this.handleTouchEnd);
124
+ target.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end
125
+ // attach a handler to get called when ANY scroll action happens on the page.
126
+ // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
127
+ // http://stackoverflow.com/a/32954565/96342
128
+ window.addEventListener('scroll', _this.handleTouchScroll, true // useCapture
129
+ );
130
+ }
131
+ };
132
+ this.handleTouchMove = function (ev) {
133
+ var pev = _this.createEventFromTouch(ev);
134
+ _this.recordCoords(pev);
135
+ _this.emitter.trigger('pointermove', pev);
136
+ };
137
+ this.handleTouchEnd = function (ev) {
138
+ if (_this.isDragging) { // done to guard against touchend followed by touchcancel
139
+ var target = ev.target;
140
+ target.removeEventListener('touchmove', _this.handleTouchMove);
141
+ target.removeEventListener('touchend', _this.handleTouchEnd);
142
+ target.removeEventListener('touchcancel', _this.handleTouchEnd);
143
+ window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true
144
+ _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev));
145
+ _this.cleanup(); // call last so that pointerup has access to props
146
+ _this.isTouchDragging = false;
147
+ startIgnoringMouse();
148
+ }
149
+ };
150
+ this.handleTouchScroll = function () {
151
+ _this.wasTouchScroll = true;
152
+ };
153
+ this.handleScroll = function (ev) {
154
+ if (!_this.shouldIgnoreMove) {
155
+ var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX;
156
+ var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY;
157
+ _this.emitter.trigger('pointermove', {
158
+ origEvent: ev,
159
+ isTouch: _this.isTouchDragging,
160
+ subjectEl: _this.subjectEl,
161
+ pageX: pageX,
162
+ pageY: pageY,
163
+ deltaX: pageX - _this.origPageX,
164
+ deltaY: pageY - _this.origPageY
165
+ });
166
+ }
167
+ };
168
+ this.containerEl = containerEl;
169
+ this.emitter = new core.EmitterMixin();
170
+ containerEl.addEventListener('mousedown', this.handleMouseDown);
171
+ containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });
172
+ listenerCreated();
173
+ }
174
+ PointerDragging.prototype.destroy = function () {
175
+ this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
176
+ this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
177
+ listenerDestroyed();
178
+ };
179
+ PointerDragging.prototype.tryStart = function (ev) {
180
+ var subjectEl = this.querySubjectEl(ev);
181
+ var downEl = ev.target;
182
+ if (subjectEl &&
183
+ (!this.handleSelector || core.elementClosest(downEl, this.handleSelector))) {
184
+ this.subjectEl = subjectEl;
185
+ this.downEl = downEl;
186
+ this.isDragging = true; // do this first so cancelTouchScroll will work
187
+ this.wasTouchScroll = false;
188
+ return true;
189
+ }
190
+ return false;
191
+ };
192
+ PointerDragging.prototype.cleanup = function () {
193
+ isWindowTouchMoveCancelled = false;
194
+ this.isDragging = false;
195
+ this.subjectEl = null;
196
+ this.downEl = null;
197
+ // keep wasTouchScroll around for later access
198
+ this.destroyScrollWatch();
199
+ };
200
+ PointerDragging.prototype.querySubjectEl = function (ev) {
201
+ if (this.selector) {
202
+ return core.elementClosest(ev.target, this.selector);
203
+ }
204
+ else {
205
+ return this.containerEl;
206
+ }
207
+ };
208
+ PointerDragging.prototype.shouldIgnoreMouse = function () {
209
+ return ignoreMouseDepth || this.isTouchDragging;
210
+ };
211
+ // can be called by user of this class, to cancel touch-based scrolling for the current drag
212
+ PointerDragging.prototype.cancelTouchScroll = function () {
213
+ if (this.isDragging) {
214
+ isWindowTouchMoveCancelled = true;
215
+ }
216
+ };
217
+ // Scrolling that simulates pointermoves
218
+ // ----------------------------------------------------------------------------------------------------
219
+ PointerDragging.prototype.initScrollWatch = function (ev) {
220
+ if (this.shouldWatchScroll) {
221
+ this.recordCoords(ev);
222
+ window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
223
+ }
224
+ };
225
+ PointerDragging.prototype.recordCoords = function (ev) {
226
+ if (this.shouldWatchScroll) {
227
+ this.prevPageX = ev.pageX;
228
+ this.prevPageY = ev.pageY;
229
+ this.prevScrollX = window.pageXOffset;
230
+ this.prevScrollY = window.pageYOffset;
231
+ }
232
+ };
233
+ PointerDragging.prototype.destroyScrollWatch = function () {
234
+ if (this.shouldWatchScroll) {
235
+ window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
236
+ }
237
+ };
238
+ // Event Normalization
239
+ // ----------------------------------------------------------------------------------------------------
240
+ PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) {
241
+ var deltaX = 0;
242
+ var deltaY = 0;
243
+ // TODO: repeat code
244
+ if (isFirst) {
245
+ this.origPageX = ev.pageX;
246
+ this.origPageY = ev.pageY;
247
+ }
248
+ else {
249
+ deltaX = ev.pageX - this.origPageX;
250
+ deltaY = ev.pageY - this.origPageY;
251
+ }
252
+ return {
253
+ origEvent: ev,
254
+ isTouch: false,
255
+ subjectEl: this.subjectEl,
256
+ pageX: ev.pageX,
257
+ pageY: ev.pageY,
258
+ deltaX: deltaX,
259
+ deltaY: deltaY
260
+ };
261
+ };
262
+ PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) {
263
+ var touches = ev.touches;
264
+ var pageX;
265
+ var pageY;
266
+ var deltaX = 0;
267
+ var deltaY = 0;
268
+ // if touch coords available, prefer,
269
+ // because FF would give bad ev.pageX ev.pageY
270
+ if (touches && touches.length) {
271
+ pageX = touches[0].pageX;
272
+ pageY = touches[0].pageY;
273
+ }
274
+ else {
275
+ pageX = ev.pageX;
276
+ pageY = ev.pageY;
277
+ }
278
+ // TODO: repeat code
279
+ if (isFirst) {
280
+ this.origPageX = pageX;
281
+ this.origPageY = pageY;
282
+ }
283
+ else {
284
+ deltaX = pageX - this.origPageX;
285
+ deltaY = pageY - this.origPageY;
286
+ }
287
+ return {
288
+ origEvent: ev,
289
+ isTouch: true,
290
+ subjectEl: this.subjectEl,
291
+ pageX: pageX,
292
+ pageY: pageY,
293
+ deltaX: deltaX,
294
+ deltaY: deltaY
295
+ };
296
+ };
297
+ return PointerDragging;
298
+ }());
299
+ // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
300
+ function isPrimaryMouseButton(ev) {
301
+ return ev.button === 0 && !ev.ctrlKey;
302
+ }
303
+ // Ignoring fake mouse events generated by touch
304
+ // ----------------------------------------------------------------------------------------------------
305
+ function startIgnoringMouse() {
306
+ ignoreMouseDepth++;
307
+ setTimeout(function () {
308
+ ignoreMouseDepth--;
309
+ }, core.config.touchMouseIgnoreWait);
310
+ }
311
+ // We want to attach touchmove as early as possible for Safari
312
+ // ----------------------------------------------------------------------------------------------------
313
+ function listenerCreated() {
314
+ if (!(listenerCnt++)) {
315
+ window.addEventListener('touchmove', onWindowTouchMove, { passive: false });
316
+ }
317
+ }
318
+ function listenerDestroyed() {
319
+ if (!(--listenerCnt)) {
320
+ window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });
321
+ }
322
+ }
323
+ function onWindowTouchMove(ev) {
324
+ if (isWindowTouchMoveCancelled) {
325
+ ev.preventDefault();
326
+ }
327
+ }
328
+
329
+ /*
330
+ An effect in which an element follows the movement of a pointer across the screen.
331
+ The moving element is a clone of some other element.
332
+ Must call start + handleMove + stop.
333
+ */
334
+ var ElementMirror = /** @class */ (function () {
335
+ function ElementMirror() {
336
+ this.isVisible = false; // must be explicitly enabled
337
+ this.sourceEl = null;
338
+ this.mirrorEl = null;
339
+ this.sourceElRect = null; // screen coords relative to viewport
340
+ // options that can be set directly by caller
341
+ this.parentNode = document.body;
342
+ this.zIndex = 9999;
343
+ this.revertDuration = 0;
344
+ }
345
+ ElementMirror.prototype.start = function (sourceEl, pageX, pageY) {
346
+ this.sourceEl = sourceEl;
347
+ this.sourceElRect = this.sourceEl.getBoundingClientRect();
348
+ this.origScreenX = pageX - window.pageXOffset;
349
+ this.origScreenY = pageY - window.pageYOffset;
350
+ this.deltaX = 0;
351
+ this.deltaY = 0;
352
+ this.updateElPosition();
353
+ };
354
+ ElementMirror.prototype.handleMove = function (pageX, pageY) {
355
+ this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;
356
+ this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;
357
+ this.updateElPosition();
358
+ };
359
+ // can be called before start
360
+ ElementMirror.prototype.setIsVisible = function (bool) {
361
+ if (bool) {
362
+ if (!this.isVisible) {
363
+ if (this.mirrorEl) {
364
+ this.mirrorEl.style.display = '';
365
+ }
366
+ this.isVisible = bool; // needs to happen before updateElPosition
367
+ this.updateElPosition(); // because was not updating the position while invisible
368
+ }
369
+ }
370
+ else {
371
+ if (this.isVisible) {
372
+ if (this.mirrorEl) {
373
+ this.mirrorEl.style.display = 'none';
374
+ }
375
+ this.isVisible = bool;
376
+ }
377
+ }
378
+ };
379
+ // always async
380
+ ElementMirror.prototype.stop = function (needsRevertAnimation, callback) {
381
+ var _this = this;
382
+ var done = function () {
383
+ _this.cleanup();
384
+ callback();
385
+ };
386
+ if (needsRevertAnimation &&
387
+ this.mirrorEl &&
388
+ this.isVisible &&
389
+ this.revertDuration && // if 0, transition won't work
390
+ (this.deltaX || this.deltaY) // if same coords, transition won't work
391
+ ) {
392
+ this.doRevertAnimation(done, this.revertDuration);
393
+ }
394
+ else {
395
+ setTimeout(done, 0);
396
+ }
397
+ };
398
+ ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) {
399
+ var mirrorEl = this.mirrorEl;
400
+ var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
401
+ mirrorEl.style.transition =
402
+ 'top ' + revertDuration + 'ms,' +
403
+ 'left ' + revertDuration + 'ms';
404
+ core.applyStyle(mirrorEl, {
405
+ left: finalSourceElRect.left,
406
+ top: finalSourceElRect.top
407
+ });
408
+ core.whenTransitionDone(mirrorEl, function () {
409
+ mirrorEl.style.transition = '';
410
+ callback();
411
+ });
412
+ };
413
+ ElementMirror.prototype.cleanup = function () {
414
+ if (this.mirrorEl) {
415
+ core.removeElement(this.mirrorEl);
416
+ this.mirrorEl = null;
417
+ }
418
+ this.sourceEl = null;
419
+ };
420
+ ElementMirror.prototype.updateElPosition = function () {
421
+ if (this.sourceEl && this.isVisible) {
422
+ core.applyStyle(this.getMirrorEl(), {
423
+ left: this.sourceElRect.left + this.deltaX,
424
+ top: this.sourceElRect.top + this.deltaY
425
+ });
426
+ }
427
+ };
428
+ ElementMirror.prototype.getMirrorEl = function () {
429
+ var sourceElRect = this.sourceElRect;
430
+ var mirrorEl = this.mirrorEl;
431
+ if (!mirrorEl) {
432
+ mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
433
+ // we don't want long taps or any mouse interaction causing selection/menus.
434
+ // would use preventSelection(), but that prevents selectstart, causing problems.
435
+ mirrorEl.classList.add('fc-unselectable');
436
+ mirrorEl.classList.add('fc-dragging');
437
+ core.applyStyle(mirrorEl, {
438
+ position: 'fixed',
439
+ zIndex: this.zIndex,
440
+ visibility: '',
441
+ boxSizing: 'border-box',
442
+ width: sourceElRect.right - sourceElRect.left,
443
+ height: sourceElRect.bottom - sourceElRect.top,
444
+ right: 'auto',
445
+ bottom: 'auto',
446
+ margin: 0
447
+ });
448
+ this.parentNode.appendChild(mirrorEl);
449
+ }
450
+ return mirrorEl;
451
+ };
452
+ return ElementMirror;
453
+ }());
454
+
455
+ /*
456
+ Is a cache for a given element's scroll information (all the info that ScrollController stores)
457
+ in addition the "client rectangle" of the element.. the area within the scrollbars.
458
+
459
+ The cache can be in one of two modes:
460
+ - doesListening:false - ignores when the container is scrolled by someone else
461
+ - doesListening:true - watch for scrolling and update the cache
462
+ */
463
+ var ScrollGeomCache = /** @class */ (function (_super) {
464
+ __extends(ScrollGeomCache, _super);
465
+ function ScrollGeomCache(scrollController, doesListening) {
466
+ var _this = _super.call(this) || this;
467
+ _this.handleScroll = function () {
468
+ _this.scrollTop = _this.scrollController.getScrollTop();
469
+ _this.scrollLeft = _this.scrollController.getScrollLeft();
470
+ _this.handleScrollChange();
471
+ };
472
+ _this.scrollController = scrollController;
473
+ _this.doesListening = doesListening;
474
+ _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop();
475
+ _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
476
+ _this.scrollWidth = scrollController.getScrollWidth();
477
+ _this.scrollHeight = scrollController.getScrollHeight();
478
+ _this.clientWidth = scrollController.getClientWidth();
479
+ _this.clientHeight = scrollController.getClientHeight();
480
+ _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values
481
+ if (_this.doesListening) {
482
+ _this.getEventTarget().addEventListener('scroll', _this.handleScroll);
483
+ }
484
+ return _this;
485
+ }
486
+ ScrollGeomCache.prototype.destroy = function () {
487
+ if (this.doesListening) {
488
+ this.getEventTarget().removeEventListener('scroll', this.handleScroll);
489
+ }
490
+ };
491
+ ScrollGeomCache.prototype.getScrollTop = function () {
492
+ return this.scrollTop;
493
+ };
494
+ ScrollGeomCache.prototype.getScrollLeft = function () {
495
+ return this.scrollLeft;
496
+ };
497
+ ScrollGeomCache.prototype.setScrollTop = function (top) {
498
+ this.scrollController.setScrollTop(top);
499
+ if (!this.doesListening) {
500
+ // we are not relying on the element to normalize out-of-bounds scroll values
501
+ // so we need to sanitize ourselves
502
+ this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
503
+ this.handleScrollChange();
504
+ }
505
+ };
506
+ ScrollGeomCache.prototype.setScrollLeft = function (top) {
507
+ this.scrollController.setScrollLeft(top);
508
+ if (!this.doesListening) {
509
+ // we are not relying on the element to normalize out-of-bounds scroll values
510
+ // so we need to sanitize ourselves
511
+ this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
512
+ this.handleScrollChange();
513
+ }
514
+ };
515
+ ScrollGeomCache.prototype.getClientWidth = function () {
516
+ return this.clientWidth;
517
+ };
518
+ ScrollGeomCache.prototype.getClientHeight = function () {
519
+ return this.clientHeight;
520
+ };
521
+ ScrollGeomCache.prototype.getScrollWidth = function () {
522
+ return this.scrollWidth;
523
+ };
524
+ ScrollGeomCache.prototype.getScrollHeight = function () {
525
+ return this.scrollHeight;
526
+ };
527
+ ScrollGeomCache.prototype.handleScrollChange = function () {
528
+ };
529
+ return ScrollGeomCache;
530
+ }(core.ScrollController));
531
+ var ElementScrollGeomCache = /** @class */ (function (_super) {
532
+ __extends(ElementScrollGeomCache, _super);
533
+ function ElementScrollGeomCache(el, doesListening) {
534
+ return _super.call(this, new core.ElementScrollController(el), doesListening) || this;
535
+ }
536
+ ElementScrollGeomCache.prototype.getEventTarget = function () {
537
+ return this.scrollController.el;
538
+ };
539
+ ElementScrollGeomCache.prototype.computeClientRect = function () {
540
+ return core.computeInnerRect(this.scrollController.el);
541
+ };
542
+ return ElementScrollGeomCache;
543
+ }(ScrollGeomCache));
544
+ var WindowScrollGeomCache = /** @class */ (function (_super) {
545
+ __extends(WindowScrollGeomCache, _super);
546
+ function WindowScrollGeomCache(doesListening) {
547
+ return _super.call(this, new core.WindowScrollController(), doesListening) || this;
548
+ }
549
+ WindowScrollGeomCache.prototype.getEventTarget = function () {
550
+ return window;
551
+ };
552
+ WindowScrollGeomCache.prototype.computeClientRect = function () {
553
+ return {
554
+ left: this.scrollLeft,
555
+ right: this.scrollLeft + this.clientWidth,
556
+ top: this.scrollTop,
557
+ bottom: this.scrollTop + this.clientHeight
558
+ };
559
+ };
560
+ // the window is the only scroll object that changes it's rectangle relative
561
+ // to the document's topleft as it scrolls
562
+ WindowScrollGeomCache.prototype.handleScrollChange = function () {
563
+ this.clientRect = this.computeClientRect();
564
+ };
565
+ return WindowScrollGeomCache;
566
+ }(ScrollGeomCache));
567
+
568
+ // If available we are using native "performance" API instead of "Date"
569
+ // Read more about it on MDN:
570
+ // https://developer.mozilla.org/en-US/docs/Web/API/Performance
571
+ var getTime = typeof performance === 'function' ? performance.now : Date.now;
572
+ /*
573
+ For a pointer interaction, automatically scrolls certain scroll containers when the pointer
574
+ approaches the edge.
575
+
576
+ The caller must call start + handleMove + stop.
577
+ */
578
+ var AutoScroller = /** @class */ (function () {
579
+ function AutoScroller() {
580
+ var _this = this;
581
+ // options that can be set by caller
582
+ this.isEnabled = true;
583
+ this.scrollQuery = [window, '.fc-scroller'];
584
+ this.edgeThreshold = 50; // pixels
585
+ this.maxVelocity = 300; // pixels per second
586
+ // internal state
587
+ this.pointerScreenX = null;
588
+ this.pointerScreenY = null;
589
+ this.isAnimating = false;
590
+ this.scrollCaches = null;
591
+ // protect against the initial pointerdown being too close to an edge and starting the scroll
592
+ this.everMovedUp = false;
593
+ this.everMovedDown = false;
594
+ this.everMovedLeft = false;
595
+ this.everMovedRight = false;
596
+ this.animate = function () {
597
+ if (_this.isAnimating) { // wasn't cancelled between animation calls
598
+ var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset);
599
+ if (edge) {
600
+ var now = getTime();
601
+ _this.handleSide(edge, (now - _this.msSinceRequest) / 1000);
602
+ _this.requestAnimation(now);
603
+ }
604
+ else {
605
+ _this.isAnimating = false; // will stop animation
606
+ }
607
+ }
608
+ };
609
+ }
610
+ AutoScroller.prototype.start = function (pageX, pageY) {
611
+ if (this.isEnabled) {
612
+ this.scrollCaches = this.buildCaches();
613
+ this.pointerScreenX = null;
614
+ this.pointerScreenY = null;
615
+ this.everMovedUp = false;
616
+ this.everMovedDown = false;
617
+ this.everMovedLeft = false;
618
+ this.everMovedRight = false;
619
+ this.handleMove(pageX, pageY);
620
+ }
621
+ };
622
+ AutoScroller.prototype.handleMove = function (pageX, pageY) {
623
+ if (this.isEnabled) {
624
+ var pointerScreenX = pageX - window.pageXOffset;
625
+ var pointerScreenY = pageY - window.pageYOffset;
626
+ var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
627
+ var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
628
+ if (yDelta < 0) {
629
+ this.everMovedUp = true;
630
+ }
631
+ else if (yDelta > 0) {
632
+ this.everMovedDown = true;
633
+ }
634
+ if (xDelta < 0) {
635
+ this.everMovedLeft = true;
636
+ }
637
+ else if (xDelta > 0) {
638
+ this.everMovedRight = true;
639
+ }
640
+ this.pointerScreenX = pointerScreenX;
641
+ this.pointerScreenY = pointerScreenY;
642
+ if (!this.isAnimating) {
643
+ this.isAnimating = true;
644
+ this.requestAnimation(getTime());
645
+ }
646
+ }
647
+ };
648
+ AutoScroller.prototype.stop = function () {
649
+ if (this.isEnabled) {
650
+ this.isAnimating = false; // will stop animation
651
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
652
+ var scrollCache = _a[_i];
653
+ scrollCache.destroy();
654
+ }
655
+ this.scrollCaches = null;
656
+ }
657
+ };
658
+ AutoScroller.prototype.requestAnimation = function (now) {
659
+ this.msSinceRequest = now;
660
+ requestAnimationFrame(this.animate);
661
+ };
662
+ AutoScroller.prototype.handleSide = function (edge, seconds) {
663
+ var scrollCache = edge.scrollCache;
664
+ var edgeThreshold = this.edgeThreshold;
665
+ var invDistance = edgeThreshold - edge.distance;
666
+ var velocity = // the closer to the edge, the faster we scroll
667
+ (invDistance * invDistance) / (edgeThreshold * edgeThreshold) * // quadratic
668
+ this.maxVelocity * seconds;
669
+ var sign = 1;
670
+ switch (edge.name) {
671
+ case 'left':
672
+ sign = -1;
673
+ // falls through
674
+ case 'right':
675
+ scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
676
+ break;
677
+ case 'top':
678
+ sign = -1;
679
+ // falls through
680
+ case 'bottom':
681
+ scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
682
+ break;
683
+ }
684
+ };
685
+ // left/top are relative to document topleft
686
+ AutoScroller.prototype.computeBestEdge = function (left, top) {
687
+ var edgeThreshold = this.edgeThreshold;
688
+ var bestSide = null;
689
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
690
+ var scrollCache = _a[_i];
691
+ var rect = scrollCache.clientRect;
692
+ var leftDist = left - rect.left;
693
+ var rightDist = rect.right - left;
694
+ var topDist = top - rect.top;
695
+ var bottomDist = rect.bottom - top;
696
+ // completely within the rect?
697
+ if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
698
+ if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&
699
+ (!bestSide || bestSide.distance > topDist)) {
700
+ bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist };
701
+ }
702
+ if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&
703
+ (!bestSide || bestSide.distance > bottomDist)) {
704
+ bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist };
705
+ }
706
+ if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&
707
+ (!bestSide || bestSide.distance > leftDist)) {
708
+ bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist };
709
+ }
710
+ if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&
711
+ (!bestSide || bestSide.distance > rightDist)) {
712
+ bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist };
713
+ }
714
+ }
715
+ }
716
+ return bestSide;
717
+ };
718
+ AutoScroller.prototype.buildCaches = function () {
719
+ return this.queryScrollEls().map(function (el) {
720
+ if (el === window) {
721
+ return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
722
+ }
723
+ else {
724
+ return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
725
+ }
726
+ });
727
+ };
728
+ AutoScroller.prototype.queryScrollEls = function () {
729
+ var els = [];
730
+ for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) {
731
+ var query = _a[_i];
732
+ if (typeof query === 'object') {
733
+ els.push(query);
734
+ }
735
+ else {
736
+ els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query)));
737
+ }
738
+ }
739
+ return els;
740
+ };
741
+ return AutoScroller;
742
+ }());
743
+
744
+ /*
745
+ Monitors dragging on an element. Has a number of high-level features:
746
+ - minimum distance required before dragging
747
+ - minimum wait time ("delay") before dragging
748
+ - a mirror element that follows the pointer
749
+ */
750
+ var FeaturefulElementDragging = /** @class */ (function (_super) {
751
+ __extends(FeaturefulElementDragging, _super);
752
+ function FeaturefulElementDragging(containerEl) {
753
+ var _this = _super.call(this, containerEl) || this;
754
+ // options that can be directly set by caller
755
+ // the caller can also set the PointerDragging's options as well
756
+ _this.delay = null;
757
+ _this.minDistance = 0;
758
+ _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
759
+ _this.mirrorNeedsRevert = false;
760
+ _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
761
+ _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
762
+ _this.isDelayEnded = false;
763
+ _this.isDistanceSurpassed = false;
764
+ _this.delayTimeoutId = null;
765
+ _this.onPointerDown = function (ev) {
766
+ if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going
767
+ _this.isInteracting = true;
768
+ _this.isDelayEnded = false;
769
+ _this.isDistanceSurpassed = false;
770
+ core.preventSelection(document.body);
771
+ core.preventContextMenu(document.body);
772
+ // prevent links from being visited if there's an eventual drag.
773
+ // also prevents selection in older browsers (maybe?).
774
+ // not necessary for touch, besides, browser would complain about passiveness.
775
+ if (!ev.isTouch) {
776
+ ev.origEvent.preventDefault();
777
+ }
778
+ _this.emitter.trigger('pointerdown', ev);
779
+ if (!_this.pointer.shouldIgnoreMove) {
780
+ // actions related to initiating dragstart+dragmove+dragend...
781
+ _this.mirror.setIsVisible(false); // reset. caller must set-visible
782
+ _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
783
+ _this.startDelay(ev);
784
+ if (!_this.minDistance) {
785
+ _this.handleDistanceSurpassed(ev);
786
+ }
787
+ }
788
+ }
789
+ };
790
+ _this.onPointerMove = function (ev) {
791
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
792
+ _this.emitter.trigger('pointermove', ev);
793
+ if (!_this.isDistanceSurpassed) {
794
+ var minDistance = _this.minDistance;
795
+ var distanceSq = void 0; // current distance from the origin, squared
796
+ var deltaX = ev.deltaX, deltaY = ev.deltaY;
797
+ distanceSq = deltaX * deltaX + deltaY * deltaY;
798
+ if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
799
+ _this.handleDistanceSurpassed(ev);
800
+ }
801
+ }
802
+ if (_this.isDragging) {
803
+ // a real pointer move? (not one simulated by scrolling)
804
+ if (ev.origEvent.type !== 'scroll') {
805
+ _this.mirror.handleMove(ev.pageX, ev.pageY);
806
+ _this.autoScroller.handleMove(ev.pageX, ev.pageY);
807
+ }
808
+ _this.emitter.trigger('dragmove', ev);
809
+ }
810
+ }
811
+ };
812
+ _this.onPointerUp = function (ev) {
813
+ if (_this.isInteracting) { // if false, still waiting for previous drag's revert
814
+ _this.isInteracting = false;
815
+ core.allowSelection(document.body);
816
+ core.allowContextMenu(document.body);
817
+ _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
818
+ if (_this.isDragging) {
819
+ _this.autoScroller.stop();
820
+ _this.tryStopDrag(ev); // which will stop the mirror
821
+ }
822
+ if (_this.delayTimeoutId) {
823
+ clearTimeout(_this.delayTimeoutId);
824
+ _this.delayTimeoutId = null;
825
+ }
826
+ }
827
+ };
828
+ var pointer = _this.pointer = new PointerDragging(containerEl);
829
+ pointer.emitter.on('pointerdown', _this.onPointerDown);
830
+ pointer.emitter.on('pointermove', _this.onPointerMove);
831
+ pointer.emitter.on('pointerup', _this.onPointerUp);
832
+ _this.mirror = new ElementMirror();
833
+ _this.autoScroller = new AutoScroller();
834
+ return _this;
835
+ }
836
+ FeaturefulElementDragging.prototype.destroy = function () {
837
+ this.pointer.destroy();
838
+ };
839
+ FeaturefulElementDragging.prototype.startDelay = function (ev) {
840
+ var _this = this;
841
+ if (typeof this.delay === 'number') {
842
+ this.delayTimeoutId = setTimeout(function () {
843
+ _this.delayTimeoutId = null;
844
+ _this.handleDelayEnd(ev);
845
+ }, this.delay);
846
+ }
847
+ else {
848
+ this.handleDelayEnd(ev);
849
+ }
850
+ };
851
+ FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) {
852
+ this.isDelayEnded = true;
853
+ this.tryStartDrag(ev);
854
+ };
855
+ FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) {
856
+ this.isDistanceSurpassed = true;
857
+ this.tryStartDrag(ev);
858
+ };
859
+ FeaturefulElementDragging.prototype.tryStartDrag = function (ev) {
860
+ if (this.isDelayEnded && this.isDistanceSurpassed) {
861
+ if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
862
+ this.isDragging = true;
863
+ this.mirrorNeedsRevert = false;
864
+ this.autoScroller.start(ev.pageX, ev.pageY);
865
+ this.emitter.trigger('dragstart', ev);
866
+ if (this.touchScrollAllowed === false) {
867
+ this.pointer.cancelTouchScroll();
868
+ }
869
+ }
870
+ }
871
+ };
872
+ FeaturefulElementDragging.prototype.tryStopDrag = function (ev) {
873
+ // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
874
+ // that come from the document to fire beforehand. much more convenient this way.
875
+ this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev) // bound with args
876
+ );
877
+ };
878
+ FeaturefulElementDragging.prototype.stopDrag = function (ev) {
879
+ this.isDragging = false;
880
+ this.emitter.trigger('dragend', ev);
881
+ };
882
+ // fill in the implementations...
883
+ FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) {
884
+ this.pointer.shouldIgnoreMove = bool;
885
+ };
886
+ FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) {
887
+ this.mirror.setIsVisible(bool);
888
+ };
889
+ FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) {
890
+ this.mirrorNeedsRevert = bool;
891
+ };
892
+ FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) {
893
+ this.autoScroller.isEnabled = bool;
894
+ };
895
+ return FeaturefulElementDragging;
896
+ }(core.ElementDragging));
897
+
898
+ /*
899
+ When this class is instantiated, it records the offset of an element (relative to the document topleft),
900
+ and continues to monitor scrolling, updating the cached coordinates if it needs to.
901
+ Does not access the DOM after instantiation, so highly performant.
902
+
903
+ Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
904
+ and an determine if a given point is inside the combined clipping rectangle.
905
+ */
906
+ var OffsetTracker = /** @class */ (function () {
907
+ function OffsetTracker(el) {
908
+ this.origRect = core.computeRect(el);
909
+ // will work fine for divs that have overflow:hidden
910
+ this.scrollCaches = core.getClippingParents(el).map(function (el) {
911
+ return new ElementScrollGeomCache(el, true); // listen=true
912
+ });
913
+ }
914
+ OffsetTracker.prototype.destroy = function () {
915
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
916
+ var scrollCache = _a[_i];
917
+ scrollCache.destroy();
918
+ }
919
+ };
920
+ OffsetTracker.prototype.computeLeft = function () {
921
+ var left = this.origRect.left;
922
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
923
+ var scrollCache = _a[_i];
924
+ left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
925
+ }
926
+ return left;
927
+ };
928
+ OffsetTracker.prototype.computeTop = function () {
929
+ var top = this.origRect.top;
930
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
931
+ var scrollCache = _a[_i];
932
+ top += scrollCache.origScrollTop - scrollCache.getScrollTop();
933
+ }
934
+ return top;
935
+ };
936
+ OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) {
937
+ var point = { left: pageX, top: pageY };
938
+ for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) {
939
+ var scrollCache = _a[_i];
940
+ if (!isIgnoredClipping(scrollCache.getEventTarget()) &&
941
+ !core.pointInsideRect(point, scrollCache.clientRect)) {
942
+ return false;
943
+ }
944
+ }
945
+ return true;
946
+ };
947
+ return OffsetTracker;
948
+ }());
949
+ // certain clipping containers should never constrain interactions, like <html> and <body>
950
+ // https://github.com/fullcalendar/fullcalendar/issues/3615
951
+ function isIgnoredClipping(node) {
952
+ var tagName = node.tagName;
953
+ return tagName === 'HTML' || tagName === 'BODY';
954
+ }
955
+
956
+ /*
957
+ Tracks movement over multiple droppable areas (aka "hits")
958
+ that exist in one or more DateComponents.
959
+ Relies on an existing draggable.
960
+
961
+ emits:
962
+ - pointerdown
963
+ - dragstart
964
+ - hitchange - fires initially, even if not over a hit
965
+ - pointerup
966
+ - (hitchange - again, to null, if ended over a hit)
967
+ - dragend
968
+ */
969
+ var HitDragging = /** @class */ (function () {
970
+ function HitDragging(dragging, droppableStore) {
971
+ var _this = this;
972
+ // options that can be set by caller
973
+ this.useSubjectCenter = false;
974
+ this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
975
+ this.initialHit = null;
976
+ this.movingHit = null;
977
+ this.finalHit = null; // won't ever be populated if shouldIgnoreMove
978
+ this.handlePointerDown = function (ev) {
979
+ var dragging = _this.dragging;
980
+ _this.initialHit = null;
981
+ _this.movingHit = null;
982
+ _this.finalHit = null;
983
+ _this.prepareHits();
984
+ _this.processFirstCoord(ev);
985
+ if (_this.initialHit || !_this.requireInitial) {
986
+ dragging.setIgnoreMove(false);
987
+ _this.emitter.trigger('pointerdown', ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
988
+ }
989
+ else {
990
+ dragging.setIgnoreMove(true);
991
+ }
992
+ };
993
+ this.handleDragStart = function (ev) {
994
+ _this.emitter.trigger('dragstart', ev);
995
+ _this.handleMove(ev, true); // force = fire even if initially null
996
+ };
997
+ this.handleDragMove = function (ev) {
998
+ _this.emitter.trigger('dragmove', ev);
999
+ _this.handleMove(ev);
1000
+ };
1001
+ this.handlePointerUp = function (ev) {
1002
+ _this.releaseHits();
1003
+ _this.emitter.trigger('pointerup', ev);
1004
+ };
1005
+ this.handleDragEnd = function (ev) {
1006
+ if (_this.movingHit) {
1007
+ _this.emitter.trigger('hitupdate', null, true, ev);
1008
+ }
1009
+ _this.finalHit = _this.movingHit;
1010
+ _this.movingHit = null;
1011
+ _this.emitter.trigger('dragend', ev);
1012
+ };
1013
+ this.droppableStore = droppableStore;
1014
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
1015
+ dragging.emitter.on('dragstart', this.handleDragStart);
1016
+ dragging.emitter.on('dragmove', this.handleDragMove);
1017
+ dragging.emitter.on('pointerup', this.handlePointerUp);
1018
+ dragging.emitter.on('dragend', this.handleDragEnd);
1019
+ this.dragging = dragging;
1020
+ this.emitter = new core.EmitterMixin();
1021
+ }
1022
+ // sets initialHit
1023
+ // sets coordAdjust
1024
+ HitDragging.prototype.processFirstCoord = function (ev) {
1025
+ var origPoint = { left: ev.pageX, top: ev.pageY };
1026
+ var adjustedPoint = origPoint;
1027
+ var subjectEl = ev.subjectEl;
1028
+ var subjectRect;
1029
+ if (subjectEl !== document) {
1030
+ subjectRect = core.computeRect(subjectEl);
1031
+ adjustedPoint = core.constrainPoint(adjustedPoint, subjectRect);
1032
+ }
1033
+ var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
1034
+ if (initialHit) {
1035
+ if (this.useSubjectCenter && subjectRect) {
1036
+ var slicedSubjectRect = core.intersectRects(subjectRect, initialHit.rect);
1037
+ if (slicedSubjectRect) {
1038
+ adjustedPoint = core.getRectCenter(slicedSubjectRect);
1039
+ }
1040
+ }
1041
+ this.coordAdjust = core.diffPoints(adjustedPoint, origPoint);
1042
+ }
1043
+ else {
1044
+ this.coordAdjust = { left: 0, top: 0 };
1045
+ }
1046
+ };
1047
+ HitDragging.prototype.handleMove = function (ev, forceHandle) {
1048
+ var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
1049
+ if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
1050
+ this.movingHit = hit;
1051
+ this.emitter.trigger('hitupdate', hit, false, ev);
1052
+ }
1053
+ };
1054
+ HitDragging.prototype.prepareHits = function () {
1055
+ this.offsetTrackers = core.mapHash(this.droppableStore, function (interactionSettings) {
1056
+ interactionSettings.component.buildPositionCaches();
1057
+ return new OffsetTracker(interactionSettings.el);
1058
+ });
1059
+ };
1060
+ HitDragging.prototype.releaseHits = function () {
1061
+ var offsetTrackers = this.offsetTrackers;
1062
+ for (var id in offsetTrackers) {
1063
+ offsetTrackers[id].destroy();
1064
+ }
1065
+ this.offsetTrackers = {};
1066
+ };
1067
+ HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) {
1068
+ var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers;
1069
+ var bestHit = null;
1070
+ for (var id in droppableStore) {
1071
+ var component = droppableStore[id].component;
1072
+ var offsetTracker = offsetTrackers[id];
1073
+ if (offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
1074
+ var originLeft = offsetTracker.computeLeft();
1075
+ var originTop = offsetTracker.computeTop();
1076
+ var positionLeft = offsetLeft - originLeft;
1077
+ var positionTop = offsetTop - originTop;
1078
+ var origRect = offsetTracker.origRect;
1079
+ var width = origRect.right - origRect.left;
1080
+ var height = origRect.bottom - origRect.top;
1081
+ if (
1082
+ // must be within the element's bounds
1083
+ positionLeft >= 0 && positionLeft < width &&
1084
+ positionTop >= 0 && positionTop < height) {
1085
+ var hit = component.queryHit(positionLeft, positionTop, width, height);
1086
+ if (hit &&
1087
+ (
1088
+ // make sure the hit is within activeRange, meaning it's not a deal cell
1089
+ !component.props.dateProfile || // hack for DayTile
1090
+ core.rangeContainsRange(component.props.dateProfile.activeRange, hit.dateSpan.range)) &&
1091
+ (!bestHit || hit.layer > bestHit.layer)) {
1092
+ // TODO: better way to re-orient rectangle
1093
+ hit.rect.left += originLeft;
1094
+ hit.rect.right += originLeft;
1095
+ hit.rect.top += originTop;
1096
+ hit.rect.bottom += originTop;
1097
+ bestHit = hit;
1098
+ }
1099
+ }
1100
+ }
1101
+ }
1102
+ return bestHit;
1103
+ };
1104
+ return HitDragging;
1105
+ }());
1106
+ function isHitsEqual(hit0, hit1) {
1107
+ if (!hit0 && !hit1) {
1108
+ return true;
1109
+ }
1110
+ if (Boolean(hit0) !== Boolean(hit1)) {
1111
+ return false;
1112
+ }
1113
+ return core.isDateSpansEqual(hit0.dateSpan, hit1.dateSpan);
1114
+ }
1115
+
1116
+ /*
1117
+ Monitors when the user clicks on a specific date/time of a component.
1118
+ A pointerdown+pointerup on the same "hit" constitutes a click.
1119
+ */
1120
+ var DateClicking = /** @class */ (function (_super) {
1121
+ __extends(DateClicking, _super);
1122
+ function DateClicking(settings) {
1123
+ var _this = _super.call(this, settings) || this;
1124
+ _this.handlePointerDown = function (ev) {
1125
+ var dragging = _this.dragging;
1126
+ // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
1127
+ dragging.setIgnoreMove(!_this.component.isValidDateDownEl(dragging.pointer.downEl));
1128
+ };
1129
+ // won't even fire if moving was ignored
1130
+ _this.handleDragEnd = function (ev) {
1131
+ var component = _this.component;
1132
+ var pointer = _this.dragging.pointer;
1133
+ if (!pointer.wasTouchScroll) {
1134
+ var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit;
1135
+ if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
1136
+ component.calendar.triggerDateClick(initialHit.dateSpan, initialHit.dayEl, component.view, ev.origEvent);
1137
+ }
1138
+ }
1139
+ };
1140
+ var component = settings.component;
1141
+ // we DO want to watch pointer moves because otherwise finalHit won't get populated
1142
+ _this.dragging = new FeaturefulElementDragging(component.el);
1143
+ _this.dragging.autoScroller.isEnabled = false;
1144
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1145
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1146
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1147
+ return _this;
1148
+ }
1149
+ DateClicking.prototype.destroy = function () {
1150
+ this.dragging.destroy();
1151
+ };
1152
+ return DateClicking;
1153
+ }(core.Interaction));
1154
+
1155
+ /*
1156
+ Tracks when the user selects a portion of time of a component,
1157
+ constituted by a drag over date cells, with a possible delay at the beginning of the drag.
1158
+ */
1159
+ var DateSelecting = /** @class */ (function (_super) {
1160
+ __extends(DateSelecting, _super);
1161
+ function DateSelecting(settings) {
1162
+ var _this = _super.call(this, settings) || this;
1163
+ _this.dragSelection = null;
1164
+ _this.handlePointerDown = function (ev) {
1165
+ var _a = _this, component = _a.component, dragging = _a.dragging;
1166
+ var canSelect = component.opt('selectable') &&
1167
+ component.isValidDateDownEl(ev.origEvent.target);
1168
+ // don't bother to watch expensive moves if component won't do selection
1169
+ dragging.setIgnoreMove(!canSelect);
1170
+ // if touch, require user to hold down
1171
+ dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null;
1172
+ };
1173
+ _this.handleDragStart = function (ev) {
1174
+ _this.component.calendar.unselect(ev); // unselect previous selections
1175
+ };
1176
+ _this.handleHitUpdate = function (hit, isFinal) {
1177
+ var calendar = _this.component.calendar;
1178
+ var dragSelection = null;
1179
+ var isInvalid = false;
1180
+ if (hit) {
1181
+ dragSelection = joinHitsIntoSelection(_this.hitDragging.initialHit, hit, calendar.pluginSystem.hooks.dateSelectionTransformers);
1182
+ if (!dragSelection || !_this.component.isDateSelectionValid(dragSelection)) {
1183
+ isInvalid = true;
1184
+ dragSelection = null;
1185
+ }
1186
+ }
1187
+ if (dragSelection) {
1188
+ calendar.dispatch({ type: 'SELECT_DATES', selection: dragSelection });
1189
+ }
1190
+ else if (!isFinal) { // only unselect if moved away while dragging
1191
+ calendar.dispatch({ type: 'UNSELECT_DATES' });
1192
+ }
1193
+ if (!isInvalid) {
1194
+ core.enableCursor();
1195
+ }
1196
+ else {
1197
+ core.disableCursor();
1198
+ }
1199
+ if (!isFinal) {
1200
+ _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
1201
+ }
1202
+ };
1203
+ _this.handlePointerUp = function (pev) {
1204
+ if (_this.dragSelection) {
1205
+ // selection is already rendered, so just need to report selection
1206
+ _this.component.calendar.triggerDateSelect(_this.dragSelection, pev);
1207
+ _this.dragSelection = null;
1208
+ }
1209
+ };
1210
+ var component = settings.component;
1211
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1212
+ dragging.touchScrollAllowed = false;
1213
+ dragging.minDistance = component.opt('selectMinDistance') || 0;
1214
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1215
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1216
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1217
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1218
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1219
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
1220
+ return _this;
1221
+ }
1222
+ DateSelecting.prototype.destroy = function () {
1223
+ this.dragging.destroy();
1224
+ };
1225
+ return DateSelecting;
1226
+ }(core.Interaction));
1227
+ function getComponentTouchDelay(component) {
1228
+ var delay = component.opt('selectLongPressDelay');
1229
+ if (delay == null) {
1230
+ delay = component.opt('longPressDelay');
1231
+ }
1232
+ return delay;
1233
+ }
1234
+ function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
1235
+ var dateSpan0 = hit0.dateSpan;
1236
+ var dateSpan1 = hit1.dateSpan;
1237
+ var ms = [
1238
+ dateSpan0.range.start,
1239
+ dateSpan0.range.end,
1240
+ dateSpan1.range.start,
1241
+ dateSpan1.range.end
1242
+ ];
1243
+ ms.sort(core.compareNumbers);
1244
+ var props = {};
1245
+ for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) {
1246
+ var transformer = dateSelectionTransformers_1[_i];
1247
+ var res = transformer(hit0, hit1);
1248
+ if (res === false) {
1249
+ return null;
1250
+ }
1251
+ else if (res) {
1252
+ __assign(props, res);
1253
+ }
1254
+ }
1255
+ props.range = { start: ms[0], end: ms[3] };
1256
+ props.allDay = dateSpan0.allDay;
1257
+ return props;
1258
+ }
1259
+
1260
+ var EventDragging = /** @class */ (function (_super) {
1261
+ __extends(EventDragging, _super);
1262
+ function EventDragging(settings) {
1263
+ var _this = _super.call(this, settings) || this;
1264
+ // internal state
1265
+ _this.subjectSeg = null; // the seg being selected/dragged
1266
+ _this.isDragging = false;
1267
+ _this.eventRange = null;
1268
+ _this.relevantEvents = null; // the events being dragged
1269
+ _this.receivingCalendar = null;
1270
+ _this.validMutation = null;
1271
+ _this.mutatedRelevantEvents = null;
1272
+ _this.handlePointerDown = function (ev) {
1273
+ var origTarget = ev.origEvent.target;
1274
+ var _a = _this, component = _a.component, dragging = _a.dragging;
1275
+ var mirror = dragging.mirror;
1276
+ var initialCalendar = component.calendar;
1277
+ var subjectSeg = _this.subjectSeg = core.getElSeg(ev.subjectEl);
1278
+ var eventRange = _this.eventRange = subjectSeg.eventRange;
1279
+ var eventInstanceId = eventRange.instance.instanceId;
1280
+ _this.relevantEvents = core.getRelevantEvents(initialCalendar.state.eventStore, eventInstanceId);
1281
+ dragging.minDistance = ev.isTouch ? 0 : component.opt('eventDragMinDistance');
1282
+ dragging.delay =
1283
+ // only do a touch delay if touch and this event hasn't been selected yet
1284
+ (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?
1285
+ getComponentTouchDelay$1(component) :
1286
+ null;
1287
+ mirror.parentNode = initialCalendar.el;
1288
+ mirror.revertDuration = component.opt('dragRevertDuration');
1289
+ var isValid = component.isValidSegDownEl(origTarget) &&
1290
+ !core.elementClosest(origTarget, '.fc-resizer');
1291
+ dragging.setIgnoreMove(!isValid);
1292
+ // disable dragging for elements that are resizable (ie, selectable)
1293
+ // but are not draggable
1294
+ _this.isDragging = isValid &&
1295
+ ev.subjectEl.classList.contains('fc-draggable');
1296
+ };
1297
+ _this.handleDragStart = function (ev) {
1298
+ var initialCalendar = _this.component.calendar;
1299
+ var eventRange = _this.eventRange;
1300
+ var eventInstanceId = eventRange.instance.instanceId;
1301
+ if (ev.isTouch) {
1302
+ // need to select a different event?
1303
+ if (eventInstanceId !== _this.component.props.eventSelection) {
1304
+ initialCalendar.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId });
1305
+ }
1306
+ }
1307
+ else {
1308
+ // if now using mouse, but was previous touch interaction, clear selected event
1309
+ initialCalendar.dispatch({ type: 'UNSELECT_EVENT' });
1310
+ }
1311
+ if (_this.isDragging) {
1312
+ initialCalendar.unselect(ev); // unselect *date* selection
1313
+ initialCalendar.publiclyTrigger('eventDragStart', [
1314
+ {
1315
+ el: _this.subjectSeg.el,
1316
+ event: new core.EventApi(initialCalendar, eventRange.def, eventRange.instance),
1317
+ jsEvent: ev.origEvent,
1318
+ view: _this.component.view
1319
+ }
1320
+ ]);
1321
+ }
1322
+ };
1323
+ _this.handleHitUpdate = function (hit, isFinal) {
1324
+ if (!_this.isDragging) {
1325
+ return;
1326
+ }
1327
+ var relevantEvents = _this.relevantEvents;
1328
+ var initialHit = _this.hitDragging.initialHit;
1329
+ var initialCalendar = _this.component.calendar;
1330
+ // states based on new hit
1331
+ var receivingCalendar = null;
1332
+ var mutation = null;
1333
+ var mutatedRelevantEvents = null;
1334
+ var isInvalid = false;
1335
+ var interaction = {
1336
+ affectedEvents: relevantEvents,
1337
+ mutatedEvents: core.createEmptyEventStore(),
1338
+ isEvent: true,
1339
+ origSeg: _this.subjectSeg
1340
+ };
1341
+ if (hit) {
1342
+ var receivingComponent = hit.component;
1343
+ receivingCalendar = receivingComponent.calendar;
1344
+ if (initialCalendar === receivingCalendar ||
1345
+ receivingComponent.opt('editable') && receivingComponent.opt('droppable')) {
1346
+ mutation = computeEventMutation(initialHit, hit, receivingCalendar.pluginSystem.hooks.eventDragMutationMassagers);
1347
+ if (mutation) {
1348
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, receivingCalendar.eventUiBases, mutation, receivingCalendar);
1349
+ interaction.mutatedEvents = mutatedRelevantEvents;
1350
+ if (!receivingComponent.isInteractionValid(interaction)) {
1351
+ isInvalid = true;
1352
+ mutation = null;
1353
+ mutatedRelevantEvents = null;
1354
+ interaction.mutatedEvents = core.createEmptyEventStore();
1355
+ }
1356
+ }
1357
+ }
1358
+ else {
1359
+ receivingCalendar = null;
1360
+ }
1361
+ }
1362
+ _this.displayDrag(receivingCalendar, interaction);
1363
+ if (!isInvalid) {
1364
+ core.enableCursor();
1365
+ }
1366
+ else {
1367
+ core.disableCursor();
1368
+ }
1369
+ if (!isFinal) {
1370
+ if (initialCalendar === receivingCalendar && // TODO: write test for this
1371
+ isHitsEqual(initialHit, hit)) {
1372
+ mutation = null;
1373
+ }
1374
+ _this.dragging.setMirrorNeedsRevert(!mutation);
1375
+ // render the mirror if no already-rendered mirror
1376
+ // TODO: wish we could somehow wait for dispatch to guarantee render
1377
+ _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-mirror'));
1378
+ // assign states based on new hit
1379
+ _this.receivingCalendar = receivingCalendar;
1380
+ _this.validMutation = mutation;
1381
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
1382
+ }
1383
+ };
1384
+ _this.handlePointerUp = function () {
1385
+ if (!_this.isDragging) {
1386
+ _this.cleanup(); // because handleDragEnd won't fire
1387
+ }
1388
+ };
1389
+ _this.handleDragEnd = function (ev) {
1390
+ if (_this.isDragging) {
1391
+ var initialCalendar_1 = _this.component.calendar;
1392
+ var initialView = _this.component.view;
1393
+ var receivingCalendar = _this.receivingCalendar;
1394
+ var eventDef = _this.eventRange.def;
1395
+ var eventInstance = _this.eventRange.instance;
1396
+ var eventApi = new core.EventApi(initialCalendar_1, eventDef, eventInstance);
1397
+ var relevantEvents_1 = _this.relevantEvents;
1398
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
1399
+ var finalHit = _this.hitDragging.finalHit;
1400
+ _this.clearDrag(); // must happen after revert animation
1401
+ initialCalendar_1.publiclyTrigger('eventDragStop', [
1402
+ {
1403
+ el: _this.subjectSeg.el,
1404
+ event: eventApi,
1405
+ jsEvent: ev.origEvent,
1406
+ view: initialView
1407
+ }
1408
+ ]);
1409
+ if (_this.validMutation) {
1410
+ // dropped within same calendar
1411
+ if (receivingCalendar === initialCalendar_1) {
1412
+ initialCalendar_1.dispatch({
1413
+ type: 'MERGE_EVENTS',
1414
+ eventStore: mutatedRelevantEvents
1415
+ });
1416
+ var transformed = {};
1417
+ for (var _i = 0, _a = initialCalendar_1.pluginSystem.hooks.eventDropTransformers; _i < _a.length; _i++) {
1418
+ var transformer = _a[_i];
1419
+ __assign(transformed, transformer(_this.validMutation, initialCalendar_1));
1420
+ }
1421
+ var eventDropArg = __assign({}, transformed, { el: ev.subjectEl, delta: _this.validMutation.startDelta, oldEvent: eventApi, event: new core.EventApi(// the data AFTER the mutation
1422
+ initialCalendar_1, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null), revert: function () {
1423
+ initialCalendar_1.dispatch({
1424
+ type: 'MERGE_EVENTS',
1425
+ eventStore: relevantEvents_1
1426
+ });
1427
+ }, jsEvent: ev.origEvent, view: initialView });
1428
+ initialCalendar_1.publiclyTrigger('eventDrop', [eventDropArg]);
1429
+ // dropped in different calendar
1430
+ }
1431
+ else if (receivingCalendar) {
1432
+ initialCalendar_1.publiclyTrigger('eventLeave', [
1433
+ {
1434
+ draggedEl: ev.subjectEl,
1435
+ event: eventApi,
1436
+ view: initialView
1437
+ }
1438
+ ]);
1439
+ initialCalendar_1.dispatch({
1440
+ type: 'REMOVE_EVENT_INSTANCES',
1441
+ instances: _this.mutatedRelevantEvents.instances
1442
+ });
1443
+ receivingCalendar.dispatch({
1444
+ type: 'MERGE_EVENTS',
1445
+ eventStore: _this.mutatedRelevantEvents
1446
+ });
1447
+ if (ev.isTouch) {
1448
+ receivingCalendar.dispatch({
1449
+ type: 'SELECT_EVENT',
1450
+ eventInstanceId: eventInstance.instanceId
1451
+ });
1452
+ }
1453
+ var dropArg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.component // should this be finalHit.component.view? See #4644
1454
+ });
1455
+ receivingCalendar.publiclyTrigger('drop', [dropArg]);
1456
+ receivingCalendar.publiclyTrigger('eventReceive', [
1457
+ {
1458
+ draggedEl: ev.subjectEl,
1459
+ event: new core.EventApi(// the data AFTER the mutation
1460
+ receivingCalendar, mutatedRelevantEvents.defs[eventDef.defId], mutatedRelevantEvents.instances[eventInstance.instanceId]),
1461
+ view: finalHit.component // should this be finalHit.component.view? See #4644
1462
+ }
1463
+ ]);
1464
+ }
1465
+ }
1466
+ else {
1467
+ initialCalendar_1.publiclyTrigger('_noEventDrop');
1468
+ }
1469
+ }
1470
+ _this.cleanup();
1471
+ };
1472
+ var component = _this.component;
1473
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1474
+ dragging.pointer.selector = EventDragging.SELECTOR;
1475
+ dragging.touchScrollAllowed = false;
1476
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1477
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsStore);
1478
+ hitDragging.useSubjectCenter = settings.useEventCenter;
1479
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1480
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1481
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1482
+ hitDragging.emitter.on('pointerup', _this.handlePointerUp);
1483
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1484
+ return _this;
1485
+ }
1486
+ EventDragging.prototype.destroy = function () {
1487
+ this.dragging.destroy();
1488
+ };
1489
+ // render a drag state on the next receivingCalendar
1490
+ EventDragging.prototype.displayDrag = function (nextCalendar, state) {
1491
+ var initialCalendar = this.component.calendar;
1492
+ var prevCalendar = this.receivingCalendar;
1493
+ // does the previous calendar need to be cleared?
1494
+ if (prevCalendar && prevCalendar !== nextCalendar) {
1495
+ // does the initial calendar need to be cleared?
1496
+ // if so, don't clear all the way. we still need to to hide the affectedEvents
1497
+ if (prevCalendar === initialCalendar) {
1498
+ prevCalendar.dispatch({
1499
+ type: 'SET_EVENT_DRAG',
1500
+ state: {
1501
+ affectedEvents: state.affectedEvents,
1502
+ mutatedEvents: core.createEmptyEventStore(),
1503
+ isEvent: true,
1504
+ origSeg: state.origSeg
1505
+ }
1506
+ });
1507
+ // completely clear the old calendar if it wasn't the initial
1508
+ }
1509
+ else {
1510
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1511
+ }
1512
+ }
1513
+ if (nextCalendar) {
1514
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
1515
+ }
1516
+ };
1517
+ EventDragging.prototype.clearDrag = function () {
1518
+ var initialCalendar = this.component.calendar;
1519
+ var receivingCalendar = this.receivingCalendar;
1520
+ if (receivingCalendar) {
1521
+ receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1522
+ }
1523
+ // the initial calendar might have an dummy drag state from displayDrag
1524
+ if (initialCalendar !== receivingCalendar) {
1525
+ initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1526
+ }
1527
+ };
1528
+ EventDragging.prototype.cleanup = function () {
1529
+ this.subjectSeg = null;
1530
+ this.isDragging = false;
1531
+ this.eventRange = null;
1532
+ this.relevantEvents = null;
1533
+ this.receivingCalendar = null;
1534
+ this.validMutation = null;
1535
+ this.mutatedRelevantEvents = null;
1536
+ };
1537
+ EventDragging.SELECTOR = '.fc-draggable, .fc-resizable'; // TODO: test this in IE11
1538
+ return EventDragging;
1539
+ }(core.Interaction));
1540
+ function computeEventMutation(hit0, hit1, massagers) {
1541
+ var dateSpan0 = hit0.dateSpan;
1542
+ var dateSpan1 = hit1.dateSpan;
1543
+ var date0 = dateSpan0.range.start;
1544
+ var date1 = dateSpan1.range.start;
1545
+ var standardProps = {};
1546
+ if (dateSpan0.allDay !== dateSpan1.allDay) {
1547
+ standardProps.allDay = dateSpan1.allDay;
1548
+ standardProps.hasEnd = hit1.component.opt('allDayMaintainDuration');
1549
+ if (dateSpan1.allDay) {
1550
+ // means date1 is already start-of-day,
1551
+ // but date0 needs to be converted
1552
+ date0 = core.startOfDay(date0);
1553
+ }
1554
+ }
1555
+ var delta = core.diffDates(date0, date1, hit0.component.dateEnv, hit0.component === hit1.component ?
1556
+ hit0.component.largeUnit :
1557
+ null);
1558
+ if (delta.milliseconds) { // has hours/minutes/seconds
1559
+ standardProps.allDay = false;
1560
+ }
1561
+ var mutation = {
1562
+ startDelta: delta,
1563
+ endDelta: delta,
1564
+ standardProps: standardProps
1565
+ };
1566
+ for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) {
1567
+ var massager = massagers_1[_i];
1568
+ massager(mutation, hit0, hit1);
1569
+ }
1570
+ return mutation;
1571
+ }
1572
+ function getComponentTouchDelay$1(component) {
1573
+ var delay = component.opt('eventLongPressDelay');
1574
+ if (delay == null) {
1575
+ delay = component.opt('longPressDelay');
1576
+ }
1577
+ return delay;
1578
+ }
1579
+
1580
+ var EventDragging$1 = /** @class */ (function (_super) {
1581
+ __extends(EventDragging, _super);
1582
+ function EventDragging(settings) {
1583
+ var _this = _super.call(this, settings) || this;
1584
+ // internal state
1585
+ _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
1586
+ _this.eventRange = null;
1587
+ _this.relevantEvents = null;
1588
+ _this.validMutation = null;
1589
+ _this.mutatedRelevantEvents = null;
1590
+ _this.handlePointerDown = function (ev) {
1591
+ var component = _this.component;
1592
+ var seg = _this.querySeg(ev);
1593
+ var eventRange = _this.eventRange = seg.eventRange;
1594
+ _this.dragging.minDistance = component.opt('eventDragMinDistance');
1595
+ // if touch, need to be working with a selected event
1596
+ _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) ||
1597
+ (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId));
1598
+ };
1599
+ _this.handleDragStart = function (ev) {
1600
+ var calendar = _this.component.calendar;
1601
+ var eventRange = _this.eventRange;
1602
+ _this.relevantEvents = core.getRelevantEvents(calendar.state.eventStore, _this.eventRange.instance.instanceId);
1603
+ _this.draggingSeg = _this.querySeg(ev);
1604
+ calendar.unselect();
1605
+ calendar.publiclyTrigger('eventResizeStart', [
1606
+ {
1607
+ el: _this.draggingSeg.el,
1608
+ event: new core.EventApi(calendar, eventRange.def, eventRange.instance),
1609
+ jsEvent: ev.origEvent,
1610
+ view: _this.component.view
1611
+ }
1612
+ ]);
1613
+ };
1614
+ _this.handleHitUpdate = function (hit, isFinal, ev) {
1615
+ var calendar = _this.component.calendar;
1616
+ var relevantEvents = _this.relevantEvents;
1617
+ var initialHit = _this.hitDragging.initialHit;
1618
+ var eventInstance = _this.eventRange.instance;
1619
+ var mutation = null;
1620
+ var mutatedRelevantEvents = null;
1621
+ var isInvalid = false;
1622
+ var interaction = {
1623
+ affectedEvents: relevantEvents,
1624
+ mutatedEvents: core.createEmptyEventStore(),
1625
+ isEvent: true,
1626
+ origSeg: _this.draggingSeg
1627
+ };
1628
+ if (hit) {
1629
+ mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-start-resizer'), eventInstance.range, calendar.pluginSystem.hooks.eventResizeJoinTransforms);
1630
+ }
1631
+ if (mutation) {
1632
+ mutatedRelevantEvents = core.applyMutationToEventStore(relevantEvents, calendar.eventUiBases, mutation, calendar);
1633
+ interaction.mutatedEvents = mutatedRelevantEvents;
1634
+ if (!_this.component.isInteractionValid(interaction)) {
1635
+ isInvalid = true;
1636
+ mutation = null;
1637
+ mutatedRelevantEvents = null;
1638
+ interaction.mutatedEvents = null;
1639
+ }
1640
+ }
1641
+ if (mutatedRelevantEvents) {
1642
+ calendar.dispatch({
1643
+ type: 'SET_EVENT_RESIZE',
1644
+ state: interaction
1645
+ });
1646
+ }
1647
+ else {
1648
+ calendar.dispatch({ type: 'UNSET_EVENT_RESIZE' });
1649
+ }
1650
+ if (!isInvalid) {
1651
+ core.enableCursor();
1652
+ }
1653
+ else {
1654
+ core.disableCursor();
1655
+ }
1656
+ if (!isFinal) {
1657
+ if (mutation && isHitsEqual(initialHit, hit)) {
1658
+ mutation = null;
1659
+ }
1660
+ _this.validMutation = mutation;
1661
+ _this.mutatedRelevantEvents = mutatedRelevantEvents;
1662
+ }
1663
+ };
1664
+ _this.handleDragEnd = function (ev) {
1665
+ var calendar = _this.component.calendar;
1666
+ var view = _this.component.view;
1667
+ var eventDef = _this.eventRange.def;
1668
+ var eventInstance = _this.eventRange.instance;
1669
+ var eventApi = new core.EventApi(calendar, eventDef, eventInstance);
1670
+ var relevantEvents = _this.relevantEvents;
1671
+ var mutatedRelevantEvents = _this.mutatedRelevantEvents;
1672
+ calendar.publiclyTrigger('eventResizeStop', [
1673
+ {
1674
+ el: _this.draggingSeg.el,
1675
+ event: eventApi,
1676
+ jsEvent: ev.origEvent,
1677
+ view: view
1678
+ }
1679
+ ]);
1680
+ if (_this.validMutation) {
1681
+ calendar.dispatch({
1682
+ type: 'MERGE_EVENTS',
1683
+ eventStore: mutatedRelevantEvents
1684
+ });
1685
+ calendar.publiclyTrigger('eventResize', [
1686
+ {
1687
+ el: _this.draggingSeg.el,
1688
+ startDelta: _this.validMutation.startDelta || core.createDuration(0),
1689
+ endDelta: _this.validMutation.endDelta || core.createDuration(0),
1690
+ prevEvent: eventApi,
1691
+ event: new core.EventApi(// the data AFTER the mutation
1692
+ calendar, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null),
1693
+ revert: function () {
1694
+ calendar.dispatch({
1695
+ type: 'MERGE_EVENTS',
1696
+ eventStore: relevantEvents
1697
+ });
1698
+ },
1699
+ jsEvent: ev.origEvent,
1700
+ view: view
1701
+ }
1702
+ ]);
1703
+ }
1704
+ else {
1705
+ calendar.publiclyTrigger('_noEventResize');
1706
+ }
1707
+ // reset all internal state
1708
+ _this.draggingSeg = null;
1709
+ _this.relevantEvents = null;
1710
+ _this.validMutation = null;
1711
+ // okay to keep eventInstance around. useful to set it in handlePointerDown
1712
+ };
1713
+ var component = settings.component;
1714
+ var dragging = _this.dragging = new FeaturefulElementDragging(component.el);
1715
+ dragging.pointer.selector = '.fc-resizer';
1716
+ dragging.touchScrollAllowed = false;
1717
+ dragging.autoScroller.isEnabled = component.opt('dragScroll');
1718
+ var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, core.interactionSettingsToStore(settings));
1719
+ hitDragging.emitter.on('pointerdown', _this.handlePointerDown);
1720
+ hitDragging.emitter.on('dragstart', _this.handleDragStart);
1721
+ hitDragging.emitter.on('hitupdate', _this.handleHitUpdate);
1722
+ hitDragging.emitter.on('dragend', _this.handleDragEnd);
1723
+ return _this;
1724
+ }
1725
+ EventDragging.prototype.destroy = function () {
1726
+ this.dragging.destroy();
1727
+ };
1728
+ EventDragging.prototype.querySeg = function (ev) {
1729
+ return core.getElSeg(core.elementClosest(ev.subjectEl, this.component.fgSegSelector));
1730
+ };
1731
+ return EventDragging;
1732
+ }(core.Interaction));
1733
+ function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) {
1734
+ var dateEnv = hit0.component.dateEnv;
1735
+ var date0 = hit0.dateSpan.range.start;
1736
+ var date1 = hit1.dateSpan.range.start;
1737
+ var delta = core.diffDates(date0, date1, dateEnv, hit0.component.largeUnit);
1738
+ var props = {};
1739
+ for (var _i = 0, transforms_1 = transforms; _i < transforms_1.length; _i++) {
1740
+ var transform = transforms_1[_i];
1741
+ var res = transform(hit0, hit1);
1742
+ if (res === false) {
1743
+ return null;
1744
+ }
1745
+ else if (res) {
1746
+ __assign(props, res);
1747
+ }
1748
+ }
1749
+ if (isFromStart) {
1750
+ if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
1751
+ props.startDelta = delta;
1752
+ return props;
1753
+ }
1754
+ }
1755
+ else {
1756
+ if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
1757
+ props.endDelta = delta;
1758
+ return props;
1759
+ }
1760
+ }
1761
+ return null;
1762
+ }
1763
+
1764
+ var UnselectAuto = /** @class */ (function () {
1765
+ function UnselectAuto(calendar) {
1766
+ var _this = this;
1767
+ this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
1768
+ this.onSelect = function (selectInfo) {
1769
+ if (selectInfo.jsEvent) {
1770
+ _this.isRecentPointerDateSelect = true;
1771
+ }
1772
+ };
1773
+ this.onDocumentPointerUp = function (pev) {
1774
+ var _a = _this, calendar = _a.calendar, documentPointer = _a.documentPointer;
1775
+ var state = calendar.state;
1776
+ // touch-scrolling should never unfocus any type of selection
1777
+ if (!documentPointer.wasTouchScroll) {
1778
+ if (state.dateSelection && // an existing date selection?
1779
+ !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
1780
+ ) {
1781
+ var unselectAuto = calendar.viewOpt('unselectAuto');
1782
+ var unselectCancel = calendar.viewOpt('unselectCancel');
1783
+ if (unselectAuto && (!unselectAuto || !core.elementClosest(documentPointer.downEl, unselectCancel))) {
1784
+ calendar.unselect(pev);
1785
+ }
1786
+ }
1787
+ if (state.eventSelection && // an existing event selected?
1788
+ !core.elementClosest(documentPointer.downEl, EventDragging.SELECTOR) // interaction DIDN'T start on an event
1789
+ ) {
1790
+ calendar.dispatch({ type: 'UNSELECT_EVENT' });
1791
+ }
1792
+ }
1793
+ _this.isRecentPointerDateSelect = false;
1794
+ };
1795
+ this.calendar = calendar;
1796
+ var documentPointer = this.documentPointer = new PointerDragging(document);
1797
+ documentPointer.shouldIgnoreMove = true;
1798
+ documentPointer.shouldWatchScroll = false;
1799
+ documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
1800
+ /*
1801
+ TODO: better way to know about whether there was a selection with the pointer
1802
+ */
1803
+ calendar.on('select', this.onSelect);
1804
+ }
1805
+ UnselectAuto.prototype.destroy = function () {
1806
+ this.calendar.off('select', this.onSelect);
1807
+ this.documentPointer.destroy();
1808
+ };
1809
+ return UnselectAuto;
1810
+ }());
1811
+
1812
+ /*
1813
+ Given an already instantiated draggable object for one-or-more elements,
1814
+ Interprets any dragging as an attempt to drag an events that lives outside
1815
+ of a calendar onto a calendar.
1816
+ */
1817
+ var ExternalElementDragging = /** @class */ (function () {
1818
+ function ExternalElementDragging(dragging, suppliedDragMeta) {
1819
+ var _this = this;
1820
+ this.receivingCalendar = null;
1821
+ this.droppableEvent = null; // will exist for all drags, even if create:false
1822
+ this.suppliedDragMeta = null;
1823
+ this.dragMeta = null;
1824
+ this.handleDragStart = function (ev) {
1825
+ _this.dragMeta = _this.buildDragMeta(ev.subjectEl);
1826
+ };
1827
+ this.handleHitUpdate = function (hit, isFinal, ev) {
1828
+ var dragging = _this.hitDragging.dragging;
1829
+ var receivingCalendar = null;
1830
+ var droppableEvent = null;
1831
+ var isInvalid = false;
1832
+ var interaction = {
1833
+ affectedEvents: core.createEmptyEventStore(),
1834
+ mutatedEvents: core.createEmptyEventStore(),
1835
+ isEvent: _this.dragMeta.create,
1836
+ origSeg: null
1837
+ };
1838
+ if (hit) {
1839
+ receivingCalendar = hit.component.calendar;
1840
+ if (_this.canDropElOnCalendar(ev.subjectEl, receivingCalendar)) {
1841
+ droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingCalendar);
1842
+ interaction.mutatedEvents = core.eventTupleToStore(droppableEvent);
1843
+ isInvalid = !core.isInteractionValid(interaction, receivingCalendar);
1844
+ if (isInvalid) {
1845
+ interaction.mutatedEvents = core.createEmptyEventStore();
1846
+ droppableEvent = null;
1847
+ }
1848
+ }
1849
+ }
1850
+ _this.displayDrag(receivingCalendar, interaction);
1851
+ // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
1852
+ // TODO: wish we could somehow wait for dispatch to guarantee render
1853
+ dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-mirror'));
1854
+ if (!isInvalid) {
1855
+ core.enableCursor();
1856
+ }
1857
+ else {
1858
+ core.disableCursor();
1859
+ }
1860
+ if (!isFinal) {
1861
+ dragging.setMirrorNeedsRevert(!droppableEvent);
1862
+ _this.receivingCalendar = receivingCalendar;
1863
+ _this.droppableEvent = droppableEvent;
1864
+ }
1865
+ };
1866
+ this.handleDragEnd = function (pev) {
1867
+ var _a = _this, receivingCalendar = _a.receivingCalendar, droppableEvent = _a.droppableEvent;
1868
+ _this.clearDrag();
1869
+ if (receivingCalendar && droppableEvent) {
1870
+ var finalHit = _this.hitDragging.finalHit;
1871
+ var finalView = finalHit.component.view;
1872
+ var dragMeta = _this.dragMeta;
1873
+ var arg = __assign({}, receivingCalendar.buildDatePointApi(finalHit.dateSpan), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView });
1874
+ receivingCalendar.publiclyTrigger('drop', [arg]);
1875
+ if (dragMeta.create) {
1876
+ receivingCalendar.dispatch({
1877
+ type: 'MERGE_EVENTS',
1878
+ eventStore: core.eventTupleToStore(droppableEvent)
1879
+ });
1880
+ if (pev.isTouch) {
1881
+ receivingCalendar.dispatch({
1882
+ type: 'SELECT_EVENT',
1883
+ eventInstanceId: droppableEvent.instance.instanceId
1884
+ });
1885
+ }
1886
+ // signal that an external event landed
1887
+ receivingCalendar.publiclyTrigger('eventReceive', [
1888
+ {
1889
+ draggedEl: pev.subjectEl,
1890
+ event: new core.EventApi(receivingCalendar, droppableEvent.def, droppableEvent.instance),
1891
+ view: finalView
1892
+ }
1893
+ ]);
1894
+ }
1895
+ }
1896
+ _this.receivingCalendar = null;
1897
+ _this.droppableEvent = null;
1898
+ };
1899
+ var hitDragging = this.hitDragging = new HitDragging(dragging, core.interactionSettingsStore);
1900
+ hitDragging.requireInitial = false; // will start outside of a component
1901
+ hitDragging.emitter.on('dragstart', this.handleDragStart);
1902
+ hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
1903
+ hitDragging.emitter.on('dragend', this.handleDragEnd);
1904
+ this.suppliedDragMeta = suppliedDragMeta;
1905
+ }
1906
+ ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) {
1907
+ if (typeof this.suppliedDragMeta === 'object') {
1908
+ return core.parseDragMeta(this.suppliedDragMeta);
1909
+ }
1910
+ else if (typeof this.suppliedDragMeta === 'function') {
1911
+ return core.parseDragMeta(this.suppliedDragMeta(subjectEl));
1912
+ }
1913
+ else {
1914
+ return getDragMetaFromEl(subjectEl);
1915
+ }
1916
+ };
1917
+ ExternalElementDragging.prototype.displayDrag = function (nextCalendar, state) {
1918
+ var prevCalendar = this.receivingCalendar;
1919
+ if (prevCalendar && prevCalendar !== nextCalendar) {
1920
+ prevCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1921
+ }
1922
+ if (nextCalendar) {
1923
+ nextCalendar.dispatch({ type: 'SET_EVENT_DRAG', state: state });
1924
+ }
1925
+ };
1926
+ ExternalElementDragging.prototype.clearDrag = function () {
1927
+ if (this.receivingCalendar) {
1928
+ this.receivingCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });
1929
+ }
1930
+ };
1931
+ ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingCalendar) {
1932
+ var dropAccept = receivingCalendar.opt('dropAccept');
1933
+ if (typeof dropAccept === 'function') {
1934
+ return dropAccept(el);
1935
+ }
1936
+ else if (typeof dropAccept === 'string' && dropAccept) {
1937
+ return Boolean(core.elementMatches(el, dropAccept));
1938
+ }
1939
+ return true;
1940
+ };
1941
+ return ExternalElementDragging;
1942
+ }());
1943
+ // Utils for computing event store from the DragMeta
1944
+ // ----------------------------------------------------------------------------------------------------
1945
+ function computeEventForDateSpan(dateSpan, dragMeta, calendar) {
1946
+ var defProps = __assign({}, dragMeta.leftoverProps);
1947
+ for (var _i = 0, _a = calendar.pluginSystem.hooks.externalDefTransforms; _i < _a.length; _i++) {
1948
+ var transform = _a[_i];
1949
+ __assign(defProps, transform(dateSpan, dragMeta));
1950
+ }
1951
+ var def = core.parseEventDef(defProps, dragMeta.sourceId, dateSpan.allDay, calendar.opt('forceEventDuration') || Boolean(dragMeta.duration), // hasEnd
1952
+ calendar);
1953
+ var start = dateSpan.range.start;
1954
+ // only rely on time info if drop zone is all-day,
1955
+ // otherwise, we already know the time
1956
+ if (dateSpan.allDay && dragMeta.startTime) {
1957
+ start = calendar.dateEnv.add(start, dragMeta.startTime);
1958
+ }
1959
+ var end = dragMeta.duration ?
1960
+ calendar.dateEnv.add(start, dragMeta.duration) :
1961
+ calendar.getDefaultEventEnd(dateSpan.allDay, start);
1962
+ var instance = core.createEventInstance(def.defId, { start: start, end: end });
1963
+ return { def: def, instance: instance };
1964
+ }
1965
+ // Utils for extracting data from element
1966
+ // ----------------------------------------------------------------------------------------------------
1967
+ function getDragMetaFromEl(el) {
1968
+ var str = getEmbeddedElData(el, 'event');
1969
+ var obj = str ?
1970
+ JSON.parse(str) :
1971
+ { create: false }; // if no embedded data, assume no event creation
1972
+ return core.parseDragMeta(obj);
1973
+ }
1974
+ core.config.dataAttrPrefix = '';
1975
+ function getEmbeddedElData(el, name) {
1976
+ var prefix = core.config.dataAttrPrefix;
1977
+ var prefixedName = (prefix ? prefix + '-' : '') + name;
1978
+ return el.getAttribute('data-' + prefixedName) || '';
1979
+ }
1980
+
1981
+ /*
1982
+ Makes an element (that is *external* to any calendar) draggable.
1983
+ Can pass in data that determines how an event will be created when dropped onto a calendar.
1984
+ Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
1985
+ */
1986
+ var ExternalDraggable = /** @class */ (function () {
1987
+ function ExternalDraggable(el, settings) {
1988
+ var _this = this;
1989
+ if (settings === void 0) { settings = {}; }
1990
+ this.handlePointerDown = function (ev) {
1991
+ var dragging = _this.dragging;
1992
+ var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay;
1993
+ dragging.minDistance =
1994
+ minDistance != null ?
1995
+ minDistance :
1996
+ (ev.isTouch ? 0 : core.globalDefaults.eventDragMinDistance);
1997
+ dragging.delay =
1998
+ ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv
1999
+ (longPressDelay != null ? longPressDelay : core.globalDefaults.longPressDelay) :
2000
+ 0;
2001
+ };
2002
+ this.handleDragStart = function (ev) {
2003
+ if (ev.isTouch &&
2004
+ _this.dragging.delay &&
2005
+ ev.subjectEl.classList.contains('fc-event')) {
2006
+ _this.dragging.mirror.getMirrorEl().classList.add('fc-selected');
2007
+ }
2008
+ };
2009
+ this.settings = settings;
2010
+ var dragging = this.dragging = new FeaturefulElementDragging(el);
2011
+ dragging.touchScrollAllowed = false;
2012
+ if (settings.itemSelector != null) {
2013
+ dragging.pointer.selector = settings.itemSelector;
2014
+ }
2015
+ if (settings.appendTo != null) {
2016
+ dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
2017
+ }
2018
+ dragging.emitter.on('pointerdown', this.handlePointerDown);
2019
+ dragging.emitter.on('dragstart', this.handleDragStart);
2020
+ new ExternalElementDragging(dragging, settings.eventData);
2021
+ }
2022
+ ExternalDraggable.prototype.destroy = function () {
2023
+ this.dragging.destroy();
2024
+ };
2025
+ return ExternalDraggable;
2026
+ }());
2027
+
2028
+ /*
2029
+ Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
2030
+ The third-party system is responsible for drawing the visuals effects of the drag.
2031
+ This class simply monitors for pointer movements and fires events.
2032
+ It also has the ability to hide the moving element (the "mirror") during the drag.
2033
+ */
2034
+ var InferredElementDragging = /** @class */ (function (_super) {
2035
+ __extends(InferredElementDragging, _super);
2036
+ function InferredElementDragging(containerEl) {
2037
+ var _this = _super.call(this, containerEl) || this;
2038
+ _this.shouldIgnoreMove = false;
2039
+ _this.mirrorSelector = '';
2040
+ _this.currentMirrorEl = null;
2041
+ _this.handlePointerDown = function (ev) {
2042
+ _this.emitter.trigger('pointerdown', ev);
2043
+ if (!_this.shouldIgnoreMove) {
2044
+ // fire dragstart right away. does not support delay or min-distance
2045
+ _this.emitter.trigger('dragstart', ev);
2046
+ }
2047
+ };
2048
+ _this.handlePointerMove = function (ev) {
2049
+ if (!_this.shouldIgnoreMove) {
2050
+ _this.emitter.trigger('dragmove', ev);
2051
+ }
2052
+ };
2053
+ _this.handlePointerUp = function (ev) {
2054
+ _this.emitter.trigger('pointerup', ev);
2055
+ if (!_this.shouldIgnoreMove) {
2056
+ // fire dragend right away. does not support a revert animation
2057
+ _this.emitter.trigger('dragend', ev);
2058
+ }
2059
+ };
2060
+ var pointer = _this.pointer = new PointerDragging(containerEl);
2061
+ pointer.emitter.on('pointerdown', _this.handlePointerDown);
2062
+ pointer.emitter.on('pointermove', _this.handlePointerMove);
2063
+ pointer.emitter.on('pointerup', _this.handlePointerUp);
2064
+ return _this;
2065
+ }
2066
+ InferredElementDragging.prototype.destroy = function () {
2067
+ this.pointer.destroy();
2068
+ };
2069
+ InferredElementDragging.prototype.setIgnoreMove = function (bool) {
2070
+ this.shouldIgnoreMove = bool;
2071
+ };
2072
+ InferredElementDragging.prototype.setMirrorIsVisible = function (bool) {
2073
+ if (bool) {
2074
+ // restore a previously hidden element.
2075
+ // use the reference in case the selector class has already been removed.
2076
+ if (this.currentMirrorEl) {
2077
+ this.currentMirrorEl.style.visibility = '';
2078
+ this.currentMirrorEl = null;
2079
+ }
2080
+ }
2081
+ else {
2082
+ var mirrorEl = this.mirrorSelector ?
2083
+ document.querySelector(this.mirrorSelector) :
2084
+ null;
2085
+ if (mirrorEl) {
2086
+ this.currentMirrorEl = mirrorEl;
2087
+ mirrorEl.style.visibility = 'hidden';
2088
+ }
2089
+ }
2090
+ };
2091
+ return InferredElementDragging;
2092
+ }(core.ElementDragging));
2093
+
2094
+ /*
2095
+ Bridges third-party drag-n-drop systems with FullCalendar.
2096
+ Must be instantiated and destroyed by caller.
2097
+ */
2098
+ var ThirdPartyDraggable = /** @class */ (function () {
2099
+ function ThirdPartyDraggable(containerOrSettings, settings) {
2100
+ var containerEl = document;
2101
+ if (
2102
+ // wish we could just test instanceof EventTarget, but doesn't work in IE11
2103
+ containerOrSettings === document ||
2104
+ containerOrSettings instanceof Element) {
2105
+ containerEl = containerOrSettings;
2106
+ settings = settings || {};
2107
+ }
2108
+ else {
2109
+ settings = (containerOrSettings || {});
2110
+ }
2111
+ var dragging = this.dragging = new InferredElementDragging(containerEl);
2112
+ if (typeof settings.itemSelector === 'string') {
2113
+ dragging.pointer.selector = settings.itemSelector;
2114
+ }
2115
+ else if (containerEl === document) {
2116
+ dragging.pointer.selector = '[data-event]';
2117
+ }
2118
+ if (typeof settings.mirrorSelector === 'string') {
2119
+ dragging.mirrorSelector = settings.mirrorSelector;
2120
+ }
2121
+ new ExternalElementDragging(dragging, settings.eventData);
2122
+ }
2123
+ ThirdPartyDraggable.prototype.destroy = function () {
2124
+ this.dragging.destroy();
2125
+ };
2126
+ return ThirdPartyDraggable;
2127
+ }());
2128
+
2129
+ var main = core.createPlugin({
2130
+ componentInteractions: [DateClicking, DateSelecting, EventDragging, EventDragging$1],
2131
+ calendarInteractions: [UnselectAuto],
2132
+ elementDraggingImpl: FeaturefulElementDragging
2133
+ });
2134
+
2135
+ exports.Draggable = ExternalDraggable;
2136
+ exports.FeaturefulElementDragging = FeaturefulElementDragging;
2137
+ exports.PointerDragging = PointerDragging;
2138
+ exports.ThirdPartyDraggable = ThirdPartyDraggable;
2139
+ exports.default = main;
2140
+
2141
+ Object.defineProperty(exports, '__esModule', { value: true });
2142
+
2143
+ }));