full_calendar 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +49 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +20 -0
- data/LICENSE.txt +21 -0
- data/README.md +102 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/full_calendar.gemspec +28 -0
- data/lib/.DS_Store +0 -0
- data/lib/full_calendar/engine.rb +9 -0
- data/lib/full_calendar/version.rb +3 -0
- data/lib/full_calendar.rb +73 -0
- data/lib/generators/.DS_Store +0 -0
- data/lib/generators/fullcalendar/.DS_Store +0 -0
- data/lib/generators/fullcalendar/install_generator.rb +61 -0
- data/lib/generators/fullcalendar/templates/default.js.tt +13 -0
- data/lib/generators/fullcalendar/templates/default.scss.tt +7 -0
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/bootstrap/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/bootstrap/main.js +90 -0
- data/vendor/assets/javascripts/fullcalendar/bootstrap/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/core/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/af.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-dz.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-kw.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ly.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-ma.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-sa.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar-tn.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ar.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/bg.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/bs.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ca.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/cs.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/da.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/de.js +33 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/el.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/en-au.js +17 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/en-gb.js +17 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/en-nz.js +17 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/es-us.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/es.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/et.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/eu.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/fa.js +33 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/fi.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ca.js +27 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/fr-ch.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/fr.js +31 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/gl.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/he.js +27 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/hi.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/hr.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/hu.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/id.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/is.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/it.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ja.js +28 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ka.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/kk.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ko.js +26 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/lb.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/lt.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/lv.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/mk.js +28 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ms.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/nb.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/nl.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/nn.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/pl.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/pt-br.js +28 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/pt.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ro.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/ru.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sk.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sl.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sq.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sr-cyrl.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sr.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/sv.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/th.js +25 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/tr.js +30 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/uk.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/vi.js +32 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/zh-cn.js +33 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales/zh-tw.js +26 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales-all.js +1353 -0
- data/vendor/assets/javascripts/fullcalendar/core/locales-all.min.js +6 -0
- data/vendor/assets/javascripts/fullcalendar/core/main.js +8679 -0
- data/vendor/assets/javascripts/fullcalendar/core/main.min.js +9 -0
- data/vendor/assets/javascripts/fullcalendar/daygrid/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/daygrid/main.js +1639 -0
- data/vendor/assets/javascripts/fullcalendar/daygrid/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/google-calendar/main.js +169 -0
- data/vendor/assets/javascripts/fullcalendar/google-calendar/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/interaction/main.js +2143 -0
- data/vendor/assets/javascripts/fullcalendar/interaction/main.min.js +21 -0
- data/vendor/assets/javascripts/fullcalendar/list/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/list/main.js +341 -0
- data/vendor/assets/javascripts/fullcalendar/list/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/luxon/main.js +162 -0
- data/vendor/assets/javascripts/fullcalendar/luxon/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/moment/main.js +103 -0
- data/vendor/assets/javascripts/fullcalendar/moment/main.min.js +6 -0
- data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.js +64 -0
- data/vendor/assets/javascripts/fullcalendar/moment-timezone/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/rrule/main.js +127 -0
- data/vendor/assets/javascripts/fullcalendar/rrule/main.min.js +20 -0
- data/vendor/assets/javascripts/fullcalendar/timegrid/.DS_Store +0 -0
- data/vendor/assets/javascripts/fullcalendar/timegrid/main.js +1354 -0
- data/vendor/assets/javascripts/fullcalendar/timegrid/main.min.js +20 -0
- data/vendor/assets/stylesheets/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/bootstrap/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/bootstrap/main.css +33 -0
- data/vendor/assets/stylesheets/fullcalendar/bootstrap/main.min.css +5 -0
- data/vendor/assets/stylesheets/fullcalendar/core/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/core/main.css +900 -0
- data/vendor/assets/stylesheets/fullcalendar/core/main.min.css +5 -0
- data/vendor/assets/stylesheets/fullcalendar/daygrid/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/daygrid/main.css +69 -0
- data/vendor/assets/stylesheets/fullcalendar/daygrid/main.min.css +5 -0
- data/vendor/assets/stylesheets/fullcalendar/list/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/list/main.css +101 -0
- data/vendor/assets/stylesheets/fullcalendar/list/main.min.css +5 -0
- data/vendor/assets/stylesheets/fullcalendar/timegrid/.DS_Store +0 -0
- data/vendor/assets/stylesheets/fullcalendar/timegrid/main.css +266 -0
- data/vendor/assets/stylesheets/fullcalendar/timegrid/main.min.css +5 -0
- 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
|
+
}));
|