3 * Docs & License: https://fullcalendar.io/
6 (function webpackUniversalModuleDefinition(root
, factory
) {
7 if(typeof exports
=== 'object' && typeof module
=== 'object')
8 module
.exports
= factory(require("moment"), require("jquery"));
9 else if(typeof define
=== 'function' && define
.amd
)
10 define(["moment", "jquery"], factory
);
11 else if(typeof exports
=== 'object')
12 exports
["FullCalendar"] = factory(require("moment"), require("jquery"));
14 root
["FullCalendar"] = factory(root
["moment"], root
["jQuery"]);
15 })(typeof self
!== 'undefined' ? self
: this, function(__WEBPACK_EXTERNAL_MODULE_0__
, __WEBPACK_EXTERNAL_MODULE_3__
) {
16 return /******/ (function(modules
) { // webpackBootstrap
17 /******/ // The module cache
18 /******/ var installedModules
= {};
20 /******/ // The require function
21 /******/ function __webpack_require__(moduleId
) {
23 /******/ // Check if module is in cache
24 /******/ if(installedModules
[moduleId
]) {
25 /******/ return installedModules
[moduleId
].exports
;
27 /******/ // Create a new module (and put it into the cache)
28 /******/ var module
= installedModules
[moduleId
] = {
34 /******/ // Execute the module function
35 /******/ modules
[moduleId
].call(module
.exports
, module
, module
.exports
, __webpack_require__
);
37 /******/ // Flag the module as loaded
38 /******/ module
.l
= true;
40 /******/ // Return the exports of the module
41 /******/ return module
.exports
;
45 /******/ // expose the modules object (__webpack_modules__)
46 /******/ __webpack_require__
.m
= modules
;
48 /******/ // expose the module cache
49 /******/ __webpack_require__
.c
= installedModules
;
51 /******/ // define getter function for harmony exports
52 /******/ __webpack_require__
.d = function(exports
, name
, getter
) {
53 /******/ if(!__webpack_require__
.o(exports
, name
)) {
54 /******/ Object
.defineProperty(exports
, name
, {
55 /******/ configurable
: false,
56 /******/ enumerable
: true,
62 /******/ // getDefaultExport function for compatibility with non-harmony modules
63 /******/ __webpack_require__
.n = function(module
) {
64 /******/ var getter
= module
&& module
.__esModule
?
65 /******/ function getDefault() { return module
['default']; } :
66 /******/ function getModuleExports() { return module
; };
67 /******/ __webpack_require__
.d(getter
, 'a', getter
);
68 /******/ return getter
;
71 /******/ // Object.prototype.hasOwnProperty.call
72 /******/ __webpack_require__
.o = function(object
, property
) { return Object
.prototype.hasOwnProperty
.call(object
, property
); };
74 /******/ // __webpack_public_path__
75 /******/ __webpack_require__
.p
= "";
77 /******/ // Load entry module and return exports
78 /******/ return __webpack_require__(__webpack_require__
.s
= 236);
80 /************************************************************************/
83 /***/ (function(module
, exports
) {
85 module
.exports
= __WEBPACK_EXTERNAL_MODULE_0__
;
90 /***/ (function(module
, exports
) {
94 https://github.com/Microsoft/tslib/blob/v1.6.0/tslib.js
96 only include the helpers we need, to keep down filesize
98 var extendStatics
= Object
.setPrototypeOf
||
99 ({ __proto__
: [] } instanceof Array
&& function (d
, b
) { d
.__proto__
= b
; }) ||
100 function (d
, b
) { for (var p
in b
)
101 if (b
.hasOwnProperty(p
))
103 exports
.__extends = function (d
, b
) {
105 function __() { this.constructor = d
; }
106 d
.prototype = b
=== null ? Object
.create(b
) : (__
.prototype = b
.prototype, new __());
112 /***/ (function(module
, exports
) {
114 module
.exports
= __WEBPACK_EXTERNAL_MODULE_3__
;
118 /***/ (function(module
, exports
, __webpack_require__
) {
120 Object
.defineProperty(exports
, "__esModule", { value
: true });
121 var moment
= __webpack_require__(0);
122 var $ = __webpack_require__(3);
123 /* FullCalendar-specific DOM Utilities
124 ----------------------------------------------------------------------------------------------------------------------*/
125 // Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
126 // and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
127 function compensateScroll(rowEls
, scrollbarWidths
) {
128 if (scrollbarWidths
.left
) {
130 'border-left-width': 1,
131 'margin-left': scrollbarWidths
.left
- 1
134 if (scrollbarWidths
.right
) {
136 'border-right-width': 1,
137 'margin-right': scrollbarWidths
.right
- 1
141 exports
.compensateScroll
= compensateScroll
;
142 // Undoes compensateScroll and restores all borders/margins
143 function uncompensateScroll(rowEls
) {
147 'border-left-width': '',
148 'border-right-width': ''
151 exports
.uncompensateScroll
= uncompensateScroll
;
152 // Make the mouse cursor express that an event is not allowed in the current area
153 function disableCursor() {
154 $('body').addClass('fc-not-allowed');
156 exports
.disableCursor
= disableCursor
;
157 // Returns the mouse cursor to its original look
158 function enableCursor() {
159 $('body').removeClass('fc-not-allowed');
161 exports
.enableCursor
= enableCursor
;
162 // Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
163 // By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
164 // any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
165 // reduces the available height.
166 function distributeHeight(els
, availableHeight
, shouldRedistribute
) {
167 // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
168 // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
169 var minOffset1
= Math
.floor(availableHeight
/ els
.length
); // for non-last element
170 var minOffset2
= Math
.floor(availableHeight
- minOffset1
* (els
.length
- 1)); // for last element *FLOORING NOTE*
171 var flexEls
= []; // elements that are allowed to expand. array of DOM nodes
172 var flexOffsets
= []; // amount of vertical space it takes up
173 var flexHeights
= []; // actual css height
175 undistributeHeight(els
); // give all elements their natural height
176 // find elements that are below the recommended height (expandable).
177 // important to query for heights in a single first pass (to avoid reflow oscillation).
178 els
.each(function (i
, el
) {
179 var minOffset
= i
=== els
.length
- 1 ? minOffset2
: minOffset1
;
180 var naturalOffset
= $(el
).outerHeight(true);
181 if (naturalOffset
< minOffset
) {
183 flexOffsets
.push(naturalOffset
);
184 flexHeights
.push($(el
).height());
187 // this element stretches past recommended height (non-expandable). mark the space as occupied.
188 usedHeight
+= naturalOffset
;
191 // readjust the recommended height to only consider the height available to non-maxed-out rows.
192 if (shouldRedistribute
) {
193 availableHeight
-= usedHeight
;
194 minOffset1
= Math
.floor(availableHeight
/ flexEls
.length
);
195 minOffset2
= Math
.floor(availableHeight
- minOffset1
* (flexEls
.length
- 1)); // *FLOORING NOTE*
197 // assign heights to all expandable elements
198 $(flexEls
).each(function (i
, el
) {
199 var minOffset
= i
=== flexEls
.length
- 1 ? minOffset2
: minOffset1
;
200 var naturalOffset
= flexOffsets
[i
];
201 var naturalHeight
= flexHeights
[i
];
202 var newHeight
= minOffset
- (naturalOffset
- naturalHeight
); // subtract the margin/padding
203 if (naturalOffset
< minOffset
) {
204 $(el
).height(newHeight
);
208 exports
.distributeHeight
= distributeHeight
;
209 // Undoes distrubuteHeight, restoring all els to their natural height
210 function undistributeHeight(els
) {
213 exports
.undistributeHeight
= undistributeHeight
;
214 // Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the
215 // cells to be that width.
216 // PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
217 function matchCellWidths(els
) {
218 var maxInnerWidth
= 0;
219 els
.find('> *').each(function (i
, innerEl
) {
220 var innerWidth
= $(innerEl
).outerWidth();
221 if (innerWidth
> maxInnerWidth
) {
222 maxInnerWidth
= innerWidth
;
225 maxInnerWidth
++; // sometimes not accurate of width the text needs to stay on one line. insurance
226 els
.width(maxInnerWidth
);
227 return maxInnerWidth
;
229 exports
.matchCellWidths
= matchCellWidths
;
230 // Given one element that resides inside another,
231 // Subtracts the height of the inner element from the outer element.
232 function subtractInnerElHeight(outerEl
, innerEl
) {
233 var both
= outerEl
.add(innerEl
);
235 // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
237 position
: 'relative',
238 left
: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
240 diff
= outerEl
.outerHeight() - innerEl
.outerHeight(); // grab the dimensions
241 both
.css({ position
: '', left
: '' }); // undo hack
244 exports
.subtractInnerElHeight
= subtractInnerElHeight
;
245 /* Element Geom Utilities
246 ----------------------------------------------------------------------------------------------------------------------*/
247 // borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51
248 function getScrollParent(el
) {
249 var position
= el
.css('position');
250 var scrollParent
= el
.parents().filter(function () {
251 var parent
= $(this);
252 return (/(auto|scroll)/).test(parent
.css('overflow') + parent
.css('overflow-y') + parent
.css('overflow-x'));
254 return position
=== 'fixed' || !scrollParent
.length
? $(el
[0].ownerDocument
|| document
) : scrollParent
;
256 exports
.getScrollParent
= getScrollParent
;
257 // Queries the outer bounding area of a jQuery element.
258 // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
259 // Origin is optional.
260 function getOuterRect(el
, origin
) {
261 var offset
= el
.offset();
262 var left
= offset
.left
- (origin
? origin
.left
: 0);
263 var top
= offset
.top
- (origin
? origin
.top
: 0);
266 right
: left
+ el
.outerWidth(),
268 bottom
: top
+ el
.outerHeight()
271 exports
.getOuterRect
= getOuterRect
;
272 // Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.
273 // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
274 // Origin is optional.
275 // WARNING: given element can't have borders
276 // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
277 function getClientRect(el
, origin
) {
278 var offset
= el
.offset();
279 var scrollbarWidths
= getScrollbarWidths(el
);
280 var left
= offset
.left
+ getCssFloat(el
, 'border-left-width') + scrollbarWidths
.left
- (origin
? origin
.left
: 0);
281 var top
= offset
.top
+ getCssFloat(el
, 'border-top-width') + scrollbarWidths
.top
- (origin
? origin
.top
: 0);
284 right
: left
+ el
[0].clientWidth
,
286 bottom
: top
+ el
[0].clientHeight
// clientHeight includes padding but NOT scrollbars
289 exports
.getClientRect
= getClientRect
;
290 // Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.
291 // Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
292 // Origin is optional.
293 function getContentRect(el
, origin
) {
294 var offset
= el
.offset(); // just outside of border, margin not included
295 var left
= offset
.left
+ getCssFloat(el
, 'border-left-width') + getCssFloat(el
, 'padding-left') -
296 (origin
? origin
.left
: 0);
297 var top
= offset
.top
+ getCssFloat(el
, 'border-top-width') + getCssFloat(el
, 'padding-top') -
298 (origin
? origin
.top
: 0);
301 right
: left
+ el
.width(),
303 bottom
: top
+ el
.height()
306 exports
.getContentRect
= getContentRect
;
307 // Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.
308 // WARNING: given element can't have borders (which will cause offsetWidth/offsetHeight to be larger).
309 // NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
310 function getScrollbarWidths(el
) {
311 var leftRightWidth
= el
[0].offsetWidth
- el
[0].clientWidth
;
312 var bottomWidth
= el
[0].offsetHeight
- el
[0].clientHeight
;
314 leftRightWidth
= sanitizeScrollbarWidth(leftRightWidth
);
315 bottomWidth
= sanitizeScrollbarWidth(bottomWidth
);
316 widths
= { left
: 0, right
: 0, top
: 0, bottom
: bottomWidth
};
317 if (getIsLeftRtlScrollbars() && el
.css('direction') === 'rtl') {
318 widths
.left
= leftRightWidth
;
321 widths
.right
= leftRightWidth
;
325 exports
.getScrollbarWidths
= getScrollbarWidths
;
326 // The scrollbar width computations in getScrollbarWidths are sometimes flawed when it comes to
327 // retina displays, rounding, and IE11. Massage them into a usable value.
328 function sanitizeScrollbarWidth(width
) {
329 width
= Math
.max(0, width
); // no negatives
330 width
= Math
.round(width
);
333 // Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
334 var _isLeftRtlScrollbars
= null;
335 function getIsLeftRtlScrollbars() {
336 if (_isLeftRtlScrollbars
=== null) {
337 _isLeftRtlScrollbars
= computeIsLeftRtlScrollbars();
339 return _isLeftRtlScrollbars
;
341 function computeIsLeftRtlScrollbars() {
342 var el
= $('<div><div/></div>')
344 position
: 'absolute',
353 var innerEl
= el
.children();
354 var res
= innerEl
.offset().left
> el
.offset().left
; // is the inner div shifted to accommodate a left scrollbar?
358 // Retrieves a jQuery element's computed CSS value as a floating-point number.
359 // If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero.
360 function getCssFloat(el
, prop
) {
361 return parseFloat(el
.css(prop
)) || 0;
363 /* Mouse / Touch Utilities
364 ----------------------------------------------------------------------------------------------------------------------*/
365 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
366 function isPrimaryMouseButton(ev
) {
367 return ev
.which
=== 1 && !ev
.ctrlKey
;
369 exports
.isPrimaryMouseButton
= isPrimaryMouseButton
;
370 function getEvX(ev
) {
371 var touches
= ev
.originalEvent
.touches
;
372 // on mobile FF, pageX for touch events is present, but incorrect,
373 // so, look at touch coordinates first.
374 if (touches
&& touches
.length
) {
375 return touches
[0].pageX
;
379 exports
.getEvX
= getEvX
;
380 function getEvY(ev
) {
381 var touches
= ev
.originalEvent
.touches
;
382 // on mobile FF, pageX for touch events is present, but incorrect,
383 // so, look at touch coordinates first.
384 if (touches
&& touches
.length
) {
385 return touches
[0].pageY
;
389 exports
.getEvY
= getEvY
;
390 function getEvIsTouch(ev
) {
391 return /^touch/.test(ev
.type
);
393 exports
.getEvIsTouch
= getEvIsTouch
;
394 function preventSelection(el
) {
395 el
.addClass('fc-unselectable')
396 .on('selectstart', preventDefault
);
398 exports
.preventSelection
= preventSelection
;
399 function allowSelection(el
) {
400 el
.removeClass('fc-unselectable')
401 .off('selectstart', preventDefault
);
403 exports
.allowSelection
= allowSelection
;
404 // Stops a mouse/touch event from doing it's native browser action
405 function preventDefault(ev
) {
408 exports
.preventDefault
= preventDefault
;
409 /* General Geometry Utils
410 ----------------------------------------------------------------------------------------------------------------------*/
411 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
412 function intersectRects(rect1
, rect2
) {
414 left
: Math
.max(rect1
.left
, rect2
.left
),
415 right
: Math
.min(rect1
.right
, rect2
.right
),
416 top
: Math
.max(rect1
.top
, rect2
.top
),
417 bottom
: Math
.min(rect1
.bottom
, rect2
.bottom
)
419 if (res
.left
< res
.right
&& res
.top
< res
.bottom
) {
424 exports
.intersectRects
= intersectRects
;
425 // Returns a new point that will have been moved to reside within the given rectangle
426 function constrainPoint(point
, rect
) {
428 left
: Math
.min(Math
.max(point
.left
, rect
.left
), rect
.right
),
429 top
: Math
.min(Math
.max(point
.top
, rect
.top
), rect
.bottom
)
432 exports
.constrainPoint
= constrainPoint
;
433 // Returns a point that is the center of the given rectangle
434 function getRectCenter(rect
) {
436 left
: (rect
.left
+ rect
.right
) / 2,
437 top
: (rect
.top
+ rect
.bottom
) / 2
440 exports
.getRectCenter
= getRectCenter
;
441 // Subtracts point2's coordinates from point1's coordinates, returning a delta
442 function diffPoints(point1
, point2
) {
444 left
: point1
.left
- point2
.left
,
445 top
: point1
.top
- point2
.top
448 exports
.diffPoints
= diffPoints
;
449 /* Object Ordering by Field
450 ----------------------------------------------------------------------------------------------------------------------*/
451 function parseFieldSpecs(input
) {
456 if (typeof input
=== 'string') {
457 tokens
= input
.split(/\s*,\s*/);
459 else if (typeof input
=== 'function') {
462 else if ($.isArray(input
)) {
465 for (i
= 0; i
< tokens
.length
; i
++) {
467 if (typeof token
=== 'string') {
468 specs
.push(token
.charAt(0) === '-' ?
469 { field
: token
.substring(1), order
: -1 } :
470 { field
: token
, order
: 1 });
472 else if (typeof token
=== 'function') {
473 specs
.push({ func
: token
});
478 exports
.parseFieldSpecs
= parseFieldSpecs
;
479 function compareByFieldSpecs(obj1
, obj2
, fieldSpecs
, obj1fallback
, obj2fallback
) {
482 for (i
= 0; i
< fieldSpecs
.length
; i
++) {
483 cmp
= compareByFieldSpec(obj1
, obj2
, fieldSpecs
[i
], obj1fallback
, obj2fallback
);
490 exports
.compareByFieldSpecs
= compareByFieldSpecs
;
491 function compareByFieldSpec(obj1
, obj2
, fieldSpec
, obj1fallback
, obj2fallback
) {
492 if (fieldSpec
.func
) {
493 return fieldSpec
.func(obj1
, obj2
);
495 var val1
= obj1
[fieldSpec
.field
];
496 var val2
= obj2
[fieldSpec
.field
];
497 if (val1
== null && obj1fallback
) {
498 val1
= obj1fallback
[fieldSpec
.field
];
500 if (val2
== null && obj2fallback
) {
501 val2
= obj2fallback
[fieldSpec
.field
];
503 return flexibleCompare(val1
, val2
) * (fieldSpec
.order
|| 1);
505 exports
.compareByFieldSpec
= compareByFieldSpec
;
506 function flexibleCompare(a
, b
) {
516 if ($.type(a
) === 'string' || $.type(b
) === 'string') {
517 return String(a
).localeCompare(String(b
));
521 exports
.flexibleCompare
= flexibleCompare
;
523 ----------------------------------------------------------------------------------------------------------------------*/
524 exports
.dayIDs
= ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
525 exports
.unitsDesc
= ['year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; // descending
526 // Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.
527 // Moments will have their timezones normalized.
528 function diffDayTime(a
, b
) {
529 return moment
.duration({
530 days
: a
.clone().stripTime().diff(b
.clone().stripTime(), 'days'),
531 ms
: a
.time() - b
.time() // time-of-day from day start. disregards timezone
534 exports
.diffDayTime
= diffDayTime
;
535 // Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.
536 function diffDay(a
, b
) {
537 return moment
.duration({
538 days
: a
.clone().stripTime().diff(b
.clone().stripTime(), 'days')
541 exports
.diffDay
= diffDay
;
542 // Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding.
543 function diffByUnit(a
, b
, unit
) {
544 return moment
.duration(Math
.round(a
.diff(b
, unit
, true)), // returnFloat=true
547 exports
.diffByUnit
= diffByUnit
;
548 // Computes the unit name of the largest whole-unit period of time.
549 // For example, 48 hours will be "days" whereas 49 hours will be "hours".
550 // Accepts start/end, a range object, or an original duration object.
551 function computeGreatestUnit(start
, end
) {
555 for (i
= 0; i
< exports
.unitsDesc
.length
; i
++) {
556 unit
= exports
.unitsDesc
[i
];
557 val
= computeRangeAs(unit
, start
, end
);
558 if (val
>= 1 && isInt(val
)) {
562 return unit
; // will be "milliseconds" if nothing else matches
564 exports
.computeGreatestUnit
= computeGreatestUnit
;
565 // like computeGreatestUnit, but has special abilities to interpret the source input for clues
566 function computeDurationGreatestUnit(duration
, durationInput
) {
567 var unit
= computeGreatestUnit(duration
);
568 // prevent days:7 from being interpreted as a week
569 if (unit
=== 'week' && typeof durationInput
=== 'object' && durationInput
.days
) {
574 exports
.computeDurationGreatestUnit
= computeDurationGreatestUnit
;
575 // Computes the number of units (like "hours") in the given range.
576 // Range can be a {start,end} object, separate start/end args, or a Duration.
577 // Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling
578 // of month-diffing logic (which tends to vary from version to version).
579 function computeRangeAs(unit
, start
, end
) {
581 return end
.diff(start
, unit
, true);
583 else if (moment
.isDuration(start
)) {
584 return start
.as(unit
);
587 return start
.end
.diff(start
.start
, unit
, true);
590 // Intelligently divides a range (specified by a start/end params) by a duration
591 function divideRangeByDuration(start
, end
, dur
) {
593 if (durationHasTime(dur
)) {
594 return (end
- start
) / dur
;
596 months
= dur
.asMonths();
597 if (Math
.abs(months
) >= 1 && isInt(months
)) {
598 return end
.diff(start
, 'months', true) / months
;
600 return end
.diff(start
, 'days', true) / dur
.asDays();
602 exports
.divideRangeByDuration
= divideRangeByDuration
;
603 // Intelligently divides one duration by another
604 function divideDurationByDuration(dur1
, dur2
) {
607 if (durationHasTime(dur1
) || durationHasTime(dur2
)) {
610 months1
= dur1
.asMonths();
611 months2
= dur2
.asMonths();
612 if (Math
.abs(months1
) >= 1 && isInt(months1
) &&
613 Math
.abs(months2
) >= 1 && isInt(months2
)) {
614 return months1
/ months2
;
616 return dur1
.asDays() / dur2
.asDays();
618 exports
.divideDurationByDuration
= divideDurationByDuration
;
619 // Intelligently multiplies a duration by a number
620 function multiplyDuration(dur
, n
) {
622 if (durationHasTime(dur
)) {
623 return moment
.duration(dur
* n
);
625 months
= dur
.asMonths();
626 if (Math
.abs(months
) >= 1 && isInt(months
)) {
627 return moment
.duration({ months
: months
* n
});
629 return moment
.duration({ days
: dur
.asDays() * n
});
631 exports
.multiplyDuration
= multiplyDuration
;
632 // Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)
633 function durationHasTime(dur
) {
634 return Boolean(dur
.hours() || dur
.minutes() || dur
.seconds() || dur
.milliseconds());
636 exports
.durationHasTime
= durationHasTime
;
637 function isNativeDate(input
) {
638 return Object
.prototype.toString
.call(input
) === '[object Date]' || input
instanceof Date
;
640 exports
.isNativeDate
= isNativeDate
;
641 // Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00"
642 function isTimeString(str
) {
643 return typeof str
=== 'string' &&
644 /^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(str
);
646 exports
.isTimeString
= isTimeString
;
648 ----------------------------------------------------------------------------------------------------------------------*/
651 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
652 args
[_i
] = arguments
[_i
];
654 var console
= window
.console
;
655 if (console
&& console
.log
) {
656 return console
.log
.apply(console
, args
);
662 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
663 args
[_i
] = arguments
[_i
];
665 var console
= window
.console
;
666 if (console
&& console
.warn
) {
667 return console
.warn
.apply(console
, args
);
670 return log
.apply(null, args
);
675 ----------------------------------------------------------------------------------------------------------------------*/
676 var hasOwnPropMethod
= {}.hasOwnProperty
;
677 // Merges an array of objects into a single object.
678 // The second argument allows for an array of property names who's object values will be merged together.
679 function mergeProps(propObjs
, complexProps
) {
688 for (i
= 0; i
< complexProps
.length
; i
++) {
689 name
= complexProps
[i
];
691 // collect the trailing object values, stopping when a non-object is discovered
692 for (j
= propObjs
.length
- 1; j
>= 0; j
--) {
693 val
= propObjs
[j
][name
];
694 if (typeof val
=== 'object') {
695 complexObjs
.unshift(val
);
697 else if (val
!== undefined) {
698 dest
[name
] = val
; // if there were no objects, this value will be used
702 // if the trailing values were objects, use the merged value
703 if (complexObjs
.length
) {
704 dest
[name
] = mergeProps(complexObjs
);
708 // copy values into the destination, going from last to first
709 for (i
= propObjs
.length
- 1; i
>= 0; i
--) {
711 for (name
in props
) {
712 if (!(name
in dest
)) {
713 dest
[name
] = props
[name
];
719 exports
.mergeProps
= mergeProps
;
720 function copyOwnProps(src
, dest
) {
721 for (var name_1
in src
) {
722 if (hasOwnProp(src
, name_1
)) {
723 dest
[name_1
] = src
[name_1
];
727 exports
.copyOwnProps
= copyOwnProps
;
728 function hasOwnProp(obj
, name
) {
729 return hasOwnPropMethod
.call(obj
, name
);
731 exports
.hasOwnProp
= hasOwnProp
;
732 function applyAll(functions
, thisObj
, args
) {
733 if ($.isFunction(functions
)) {
734 functions
= [functions
];
739 for (i
= 0; i
< functions
.length
; i
++) {
740 ret
= functions
[i
].apply(thisObj
, args
) || ret
;
745 exports
.applyAll
= applyAll
;
746 function removeMatching(array
, testFunc
) {
749 while (i
< array
.length
) {
750 if (testFunc(array
[i
])) {
760 exports
.removeMatching
= removeMatching
;
761 function removeExact(array
, exactVal
) {
764 while (i
< array
.length
) {
765 if (array
[i
] === exactVal
) {
775 exports
.removeExact
= removeExact
;
776 function isArraysEqual(a0
, a1
) {
779 if (len
== null || len
!== a1
.length
) {
782 for (i
= 0; i
< len
; i
++) {
783 if (a0
[i
] !== a1
[i
]) {
789 exports
.isArraysEqual
= isArraysEqual
;
790 function firstDefined() {
792 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
793 args
[_i
] = arguments
[_i
];
795 for (var i
= 0; i
< args
.length
; i
++) {
796 if (args
[i
] !== undefined) {
801 exports
.firstDefined
= firstDefined
;
802 function htmlEscape(s
) {
803 return (s
+ '').replace(/&/g
, '&')
804 .replace(/</g
, '<')
805 .replace(/>/g
, '>')
806 .replace(/'/g, ''')
807 .replace(/"/g, '"
;')
808 .replace(/\n/g, '<br
/>');
810 exports.htmlEscape = htmlEscape;
811 function stripHtmlEntities(text) {
812 return text.replace(/&.*?;/g, '');
814 exports.stripHtmlEntities = stripHtmlEntities;
815 // Given a hash of CSS properties, returns a string of CSS.
816 // Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
817 function cssToStr(cssProps) {
819 $.each(cssProps, function (name, val) {
821 statements.push(name + ':' + val);
824 return statements.join(';');
826 exports.cssToStr = cssToStr;
827 // Given an object hash of HTML attribute names to values,
828 // generates a string that can be injected between < > in HTML
829 function attrsToStr(attrs) {
831 $.each(attrs, function (name, val) {
833 parts.push(name + '="' + htmlEscape(val) + '"');
836 return parts.join(' ');
838 exports.attrsToStr = attrsToStr;
839 function capitaliseFirstLetter(str) {
840 return str.charAt(0).toUpperCase() + str.slice(1);
842 exports.capitaliseFirstLetter = capitaliseFirstLetter;
843 function compareNumbers(a, b) {
846 exports.compareNumbers = compareNumbers;
850 exports.isInt = isInt;
851 // Returns a method bound to the given object context.
852 // Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with
853 // different contexts as identical when binding/unbinding events.
854 function proxy(obj, methodName) {
855 var method = obj[methodName];
857 return method.apply(obj, arguments);
860 exports.proxy = proxy;
861 // Returns a function, that, as long as it continues to be invoked, will not
862 // be triggered. The function will be called after it stops being called for
863 // N milliseconds. If `immediate` is passed, trigger the function on the
864 // leading edge, instead of the trailing.
865 // https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
866 function debounce(func, wait, immediate) {
867 if (immediate === void 0) { immediate = false; }
873 var later = function () {
874 var last = +new Date() - timestamp;
876 timeout = setTimeout(later, wait - last);
881 result = func.apply(context, args);
882 context = args = null;
889 timestamp = +new Date();
890 var callNow = immediate && !timeout;
892 timeout = setTimeout(later, wait);
895 result = func.apply(context, args);
896 context = args = null;
901 exports.debounce = debounce;
906 /***/ (function(module, exports, __webpack_require__) {
908 Object.defineProperty(exports, "__esModule", { value: true });
909 var moment = __webpack_require__(0);
910 var moment_ext_1 = __webpack_require__(10);
911 var UnzonedRange = /** @class */ (function () {
912 function UnzonedRange(startInput, endInput) {
913 // TODO: move these into footprint.
914 // Especially, doesn't make sense
for null startMs
/endMs
.
917 if (moment
.isMoment(startInput
)) {
918 startInput
= startInput
.clone().stripZone();
920 if (moment
.isMoment(endInput
)) {
921 endInput
= endInput
.clone().stripZone();
924 this.startMs
= startInput
.valueOf();
927 this.endMs
= endInput
.valueOf();
931 SIDEEFFECT: will mutate eventRanges.
932 Will return a new array result.
933 Only works for non-open-ended ranges.
935 UnzonedRange
.invertRanges = function (ranges
, constraintRange
) {
936 var invertedRanges
= [];
937 var startMs
= constraintRange
.startMs
; // the end of the previous range. the start of the new range
940 // ranges need to be in order. required for our date-walking algorithm
941 ranges
.sort(compareUnzonedRanges
);
942 for (i
= 0; i
< ranges
.length
; i
++) {
943 dateRange
= ranges
[i
];
944 // add the span of time before the event (if there is any)
945 if (dateRange
.startMs
> startMs
) {
946 invertedRanges
.push(new UnzonedRange(startMs
, dateRange
.startMs
));
948 if (dateRange
.endMs
> startMs
) {
949 startMs
= dateRange
.endMs
;
952 // add the span of time after the last event (if there is any)
953 if (startMs
< constraintRange
.endMs
) {
954 invertedRanges
.push(new UnzonedRange(startMs
, constraintRange
.endMs
));
956 return invertedRanges
;
958 UnzonedRange
.prototype.intersect = function (otherRange
) {
959 var startMs
= this.startMs
;
960 var endMs
= this.endMs
;
962 if (otherRange
.startMs
!= null) {
963 if (startMs
== null) {
964 startMs
= otherRange
.startMs
;
967 startMs
= Math
.max(startMs
, otherRange
.startMs
);
970 if (otherRange
.endMs
!= null) {
972 endMs
= otherRange
.endMs
;
975 endMs
= Math
.min(endMs
, otherRange
.endMs
);
978 if (startMs
== null || endMs
== null || startMs
< endMs
) {
979 newRange
= new UnzonedRange(startMs
, endMs
);
980 newRange
.isStart
= this.isStart
&& startMs
=== this.startMs
;
981 newRange
.isEnd
= this.isEnd
&& endMs
=== this.endMs
;
985 UnzonedRange
.prototype.intersectsWith = function (otherRange
) {
986 return (this.endMs
== null || otherRange
.startMs
== null || this.endMs
> otherRange
.startMs
) &&
987 (this.startMs
== null || otherRange
.endMs
== null || this.startMs
< otherRange
.endMs
);
989 UnzonedRange
.prototype.containsRange = function (innerRange
) {
990 return (this.startMs
== null || (innerRange
.startMs
!= null && innerRange
.startMs
>= this.startMs
)) &&
991 (this.endMs
== null || (innerRange
.endMs
!= null && innerRange
.endMs
<= this.endMs
));
993 // `date` can be a moment, a Date, or a millisecond time.
994 UnzonedRange
.prototype.containsDate = function (date
) {
995 var ms
= date
.valueOf();
996 return (this.startMs
== null || ms
>= this.startMs
) &&
997 (this.endMs
== null || ms
< this.endMs
);
999 // If the given date is not within the given range, move it inside.
1000 // (If it's past the end, make it one millisecond before the end).
1001 // `date` can be a moment, a Date, or a millisecond time.
1002 // Returns a MS-time.
1003 UnzonedRange
.prototype.constrainDate = function (date
) {
1004 var ms
= date
.valueOf();
1005 if (this.startMs
!= null && ms
< this.startMs
) {
1008 if (this.endMs
!= null && ms
>= this.endMs
) {
1009 ms
= this.endMs
- 1;
1013 UnzonedRange
.prototype.equals = function (otherRange
) {
1014 return this.startMs
=== otherRange
.startMs
&& this.endMs
=== otherRange
.endMs
;
1016 UnzonedRange
.prototype.clone = function () {
1017 var range
= new UnzonedRange(this.startMs
, this.endMs
);
1018 range
.isStart
= this.isStart
;
1019 range
.isEnd
= this.isEnd
;
1022 // Returns an ambig-zoned moment from startMs.
1023 // BEWARE: returned moment is not localized.
1024 // Formatting and start-of-week will be default.
1025 UnzonedRange
.prototype.getStart = function () {
1026 if (this.startMs
!= null) {
1027 return moment_ext_1
.default.utc(this.startMs
).stripZone();
1031 // Returns an ambig-zoned moment from startMs.
1032 // BEWARE: returned moment is not localized.
1033 // Formatting and start-of-week will be default.
1034 UnzonedRange
.prototype.getEnd = function () {
1035 if (this.endMs
!= null) {
1036 return moment_ext_1
.default.utc(this.endMs
).stripZone();
1040 UnzonedRange
.prototype.as = function (unit
) {
1041 return moment
.utc(this.endMs
).diff(moment
.utc(this.startMs
), unit
, true);
1043 return UnzonedRange
;
1045 exports
.default = UnzonedRange
;
1047 Only works for non-open-ended ranges.
1049 function compareUnzonedRanges(range1
, range2
) {
1050 return range1
.startMs
- range2
.startMs
; // earlier ranges go first
1056 /***/ (function(module
, exports
, __webpack_require__
) {
1058 Object
.defineProperty(exports
, "__esModule", { value
: true });
1059 var tslib_1
= __webpack_require__(2);
1060 var $ = __webpack_require__(3);
1061 var ParsableModelMixin_1
= __webpack_require__(208);
1062 var Class_1
= __webpack_require__(33);
1063 var EventDefParser_1
= __webpack_require__(49);
1064 var EventSource
= /** @class */ (function (_super
) {
1065 tslib_1
.__extends(EventSource
, _super
);
1066 // can we do away with calendar? at least for the abstract?
1067 // useful for buildEventDef
1068 function EventSource(calendar
) {
1069 var _this
= _super
.call(this) || this;
1070 _this
.calendar
= calendar
;
1071 _this
.className
= [];
1072 _this
.uid
= String(EventSource
.uuid
++);
1076 rawInput can be any data type!
1078 EventSource
.parse = function (rawInput
, calendar
) {
1079 var source
= new this(calendar
);
1080 if (typeof rawInput
=== 'object') {
1081 if (source
.applyProps(rawInput
)) {
1087 EventSource
.normalizeId = function (id
) {
1093 EventSource
.prototype.fetch = function (start
, end
, timezone
) {
1094 // subclasses must implement. must return a promise.
1096 EventSource
.prototype.removeEventDefsById = function (eventDefId
) {
1097 // optional for subclasses to implement
1099 EventSource
.prototype.removeAllEventDefs = function () {
1100 // optional for subclasses to implement
1103 For compairing/matching
1105 EventSource
.prototype.getPrimitive = function (otherSource
) {
1106 // subclasses must implement
1108 EventSource
.prototype.parseEventDefs = function (rawEventDefs
) {
1112 for (i
= 0; i
< rawEventDefs
.length
; i
++) {
1113 eventDef
= this.parseEventDef(rawEventDefs
[i
]);
1115 eventDefs
.push(eventDef
);
1120 EventSource
.prototype.parseEventDef = function (rawInput
) {
1121 var calendarTransform
= this.calendar
.opt('eventDataTransform');
1122 var sourceTransform
= this.eventDataTransform
;
1123 if (calendarTransform
) {
1124 rawInput
= calendarTransform(rawInput
, this.calendar
);
1126 if (sourceTransform
) {
1127 rawInput
= sourceTransform(rawInput
, this.calendar
);
1129 return EventDefParser_1
.default.parse(rawInput
, this);
1131 EventSource
.prototype.applyManualStandardProps = function (rawProps
) {
1132 if (rawProps
.id
!= null) {
1133 this.id
= EventSource
.normalizeId(rawProps
.id
);
1135 // TODO: converge with EventDef
1136 if ($.isArray(rawProps
.className
)) {
1137 this.className
= rawProps
.className
;
1139 else if (typeof rawProps
.className
=== 'string') {
1140 this.className
= rawProps
.className
.split(/\s+/);
1144 EventSource
.uuid
= 0;
1145 EventSource
.defineStandardProps
= ParsableModelMixin_1
.default.defineStandardProps
;
1146 EventSource
.copyVerbatimStandardProps
= ParsableModelMixin_1
.default.copyVerbatimStandardProps
;
1148 }(Class_1
.default));
1149 exports
.default = EventSource
;
1150 ParsableModelMixin_1
.default.mixInto(EventSource
);
1152 // ---------------------------------------------------------------------------------------------------------------------
1153 EventSource
.defineStandardProps({
1154 // manually process...
1157 // automatically transfer...
1159 backgroundColor
: true,
1163 startEditable
: true,
1164 durationEditable
: true,
1168 allDayDefault
: true,
1169 eventDataTransform
: true
1175 /***/ (function(module
, exports
, __webpack_require__
) {
1178 Utility methods for easily listening to events on another object,
1179 and more importantly, easily unlistening from them.
1182 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin'
1184 listenTo: ListenerInterface['listenTo']
1185 stopListeningTo: ListenerInterface['stopListeningTo']
1187 ListenerMixin.mixInto(TheClass)
1189 Object
.defineProperty(exports
, "__esModule", { value
: true });
1190 var tslib_1
= __webpack_require__(2);
1191 var $ = __webpack_require__(3);
1192 var Mixin_1
= __webpack_require__(14);
1194 var ListenerMixin
= /** @class */ (function (_super
) {
1195 tslib_1
.__extends(ListenerMixin
, _super
);
1196 function ListenerMixin() {
1197 return _super
!== null && _super
.apply(this, arguments
) || this;
1200 Given an `other` object that has on/off methods, bind the given `callback` to an event by the given name.
1201 The `callback` will be called with the `this` context of the object that .listenTo is being called on.
1203 .listenTo(other, eventName, callback)
1206 eventName1: callback1,
1207 eventName2: callback2
1210 ListenerMixin
.prototype.listenTo = function (other
, arg
, callback
) {
1211 if (typeof arg
=== 'object') {
1212 for (var eventName
in arg
) {
1213 if (arg
.hasOwnProperty(eventName
)) {
1214 this.listenTo(other
, eventName
, arg
[eventName
]);
1218 else if (typeof arg
=== 'string') {
1219 other
.on(arg
+ '.' + this.getListenerNamespace(), // use event namespacing to identify this object
1220 $.proxy(callback
, this) // always use `this` context
1221 // the usually-undesired jQuery guid behavior doesn't matter,
1222 // because we always unbind via namespace
1227 Causes the current object to stop listening to events on the `other` object.
1228 `eventName` is optional. If omitted, will stop listening to ALL events on `other`.
1230 ListenerMixin
.prototype.stopListeningTo = function (other
, eventName
) {
1231 other
.off((eventName
|| '') + '.' + this.getListenerNamespace());
1234 Returns a string, unique to this object, to be used for event namespacing
1236 ListenerMixin
.prototype.getListenerNamespace = function () {
1237 if (this.listenerId
== null) {
1238 this.listenerId
= guid
++;
1240 return '_listener' + this.listenerId
;
1242 return ListenerMixin
;
1243 }(Mixin_1
.default));
1244 exports
.default = ListenerMixin
;
1251 /***/ (function(module
, exports
, __webpack_require__
) {
1253 Object
.defineProperty(exports
, "__esModule", { value
: true });
1254 var moment
= __webpack_require__(0);
1255 var $ = __webpack_require__(3);
1256 var util_1
= __webpack_require__(4);
1257 var ambigDateOfMonthRegex
= /^\s*\d{4}-\d\d$/;
1258 var ambigTimeOrZoneRegex
= /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/;
1259 var newMomentProto
= moment
.fn
; // where we will attach our new methods
1260 exports
.newMomentProto
= newMomentProto
;
1261 var oldMomentProto
= $.extend({}, newMomentProto
); // copy of original moment methods
1262 exports
.oldMomentProto
= oldMomentProto
;
1263 // tell momentjs to transfer these properties upon clone
1264 var momentProperties
= moment
.momentProperties
;
1265 momentProperties
.push('_fullCalendar');
1266 momentProperties
.push('_ambigTime');
1267 momentProperties
.push('_ambigZone');
1269 Call this if you want Moment's original format method to be used
1271 function oldMomentFormat(mom
, formatStr
) {
1272 return oldMomentProto
.format
.call(mom
, formatStr
); // oldMomentProto defined in moment-ext.js
1274 exports
.oldMomentFormat
= oldMomentFormat
;
1276 // -------------------------------------------------------------------------------------------------
1277 // Creates a new moment, similar to the vanilla moment(...) constructor, but with
1278 // extra features (ambiguous time, enhanced formatting). When given an existing moment,
1279 // it will function as a clone (and retain the zone of the moment). Anything else will
1280 // result in a moment in the local zone.
1281 var momentExt = function () {
1282 return makeMoment(arguments
);
1284 exports
.default = momentExt
;
1285 // Sames as momentExt, but forces the resulting moment to be in the UTC timezone.
1286 momentExt
.utc = function () {
1287 var mom
= makeMoment(arguments
, true);
1288 // Force it into UTC because makeMoment doesn't guarantee it
1289 // (if given a pre-existing moment for example)
1290 if (mom
.hasTime()) {
1295 // Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved.
1296 // ISO8601 strings with no timezone offset will become ambiguously zoned.
1297 momentExt
.parseZone = function () {
1298 return makeMoment(arguments
, true, true);
1300 // Builds an enhanced moment from args. When given an existing moment, it clones. When given a
1301 // native Date, or called with no arguments (the current time), the resulting moment will be local.
1302 // Anything else needs to be "parsed" (a string or an array), and will be affected by:
1303 // parseAsUTC - if there is no zone information, should we parse the input in UTC?
1304 // parseZone - if there is zone information, should we force the zone of the moment?
1305 function makeMoment(args
, parseAsUTC
, parseZone
) {
1306 if (parseAsUTC
=== void 0) { parseAsUTC
= false; }
1307 if (parseZone
=== void 0) { parseZone
= false; }
1308 var input
= args
[0];
1309 var isSingleString
= args
.length
=== 1 && typeof input
=== 'string';
1314 if (moment
.isMoment(input
) || util_1
.isNativeDate(input
) || input
=== undefined) {
1315 mom
= moment
.apply(null, args
);
1318 isAmbigTime
= false;
1319 isAmbigZone
= false;
1320 if (isSingleString
) {
1321 if (ambigDateOfMonthRegex
.test(input
)) {
1322 // accept strings like '2014-05', but convert to the first of the month
1324 args
= [input
]; // for when we pass it on to moment's constructor
1328 else if ((ambigMatch
= ambigTimeOrZoneRegex
.exec(input
))) {
1329 isAmbigTime
= !ambigMatch
[5]; // no time part?
1333 else if ($.isArray(input
)) {
1334 // arrays have no timezone information, so assume ambiguous zone
1337 // otherwise, probably a string with a format
1338 if (parseAsUTC
|| isAmbigTime
) {
1339 mom
= moment
.utc
.apply(moment
, args
);
1342 mom
= moment
.apply(null, args
);
1345 mom
._ambigTime
= true;
1346 mom
._ambigZone
= true; // ambiguous time always means ambiguous zone
1348 else if (parseZone
) {
1350 mom
._ambigZone
= true;
1352 else if (isSingleString
) {
1353 mom
.utcOffset(input
); // if not a valid zone, will assign UTC
1357 mom
._fullCalendar
= true; // flag for extended functionality
1361 // -------------------------------------------------------------------------------------------------
1362 // Returns the week number, considering the locale's custom week number calcuation
1363 // `weeks` is an alias for `week`
1364 newMomentProto
.week
= newMomentProto
.weeks = function (input
) {
1365 var weekCalc
= this._locale
._fullCalendar_weekCalc
;
1366 if (input
== null && typeof weekCalc
=== 'function') {
1367 return weekCalc(this);
1369 else if (weekCalc
=== 'ISO') {
1370 return oldMomentProto
.isoWeek
.apply(this, arguments
); // ISO getter/setter
1372 return oldMomentProto
.week
.apply(this, arguments
); // local getter/setter
1375 // -------------------------------------------------------------------------------------------------
1377 // Returns a Duration with the hours/minutes/seconds/ms values of the moment.
1378 // If the moment has an ambiguous time, a duration of 00:00 will be returned.
1381 // You can supply a Duration, a Moment, or a Duration-like argument.
1382 // When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.
1383 newMomentProto
.time = function (time
) {
1384 // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.
1385 // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.
1386 if (!this._fullCalendar
) {
1387 return oldMomentProto
.time
.apply(this, arguments
);
1390 return moment
.duration({
1391 hours
: this.hours(),
1392 minutes
: this.minutes(),
1393 seconds
: this.seconds(),
1394 milliseconds
: this.milliseconds()
1398 this._ambigTime
= false; // mark that the moment now has a time
1399 if (!moment
.isDuration(time
) && !moment
.isMoment(time
)) {
1400 time
= moment
.duration(time
);
1402 // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).
1403 // Only for Duration times, not Moment times.
1405 if (moment
.isDuration(time
)) {
1406 dayHours
= Math
.floor(time
.asDays()) * 24;
1408 // We need to set the individual fields.
1409 // Can't use startOf('day') then add duration. In case of DST at start of day.
1410 return this.hours(dayHours
+ time
.hours())
1411 .minutes(time
.minutes())
1412 .seconds(time
.seconds())
1413 .milliseconds(time
.milliseconds());
1416 // Converts the moment to UTC, stripping out its time-of-day and timezone offset,
1417 // but preserving its YMD. A moment with a stripped time will display no time
1418 // nor timezone offset when .format() is called.
1419 newMomentProto
.stripTime = function () {
1420 if (!this._ambigTime
) {
1421 this.utc(true); // keepLocalTime=true (for keeping *date* value)
1429 // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1430 // which clears all ambig flags.
1431 this._ambigTime
= true;
1432 this._ambigZone
= true; // if ambiguous time, also ambiguous timezone offset
1434 return this; // for chaining
1436 // Returns if the moment has a non-ambiguous time (boolean)
1437 newMomentProto
.hasTime = function () {
1438 return !this._ambigTime
;
1441 // -------------------------------------------------------------------------------------------------
1442 // Converts the moment to UTC, stripping out its timezone offset, but preserving its
1443 // YMD and time-of-day. A moment with a stripped timezone offset will display no
1444 // timezone offset when .format() is called.
1445 newMomentProto
.stripZone = function () {
1447 if (!this._ambigZone
) {
1448 wasAmbigTime
= this._ambigTime
;
1449 this.utc(true); // keepLocalTime=true (for keeping date and time values)
1450 // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore
1451 this._ambigTime
= wasAmbigTime
|| false;
1452 // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1453 // which clears the ambig flags.
1454 this._ambigZone
= true;
1456 return this; // for chaining
1458 // Returns of the moment has a non-ambiguous timezone offset (boolean)
1459 newMomentProto
.hasZone = function () {
1460 return !this._ambigZone
;
1462 // implicitly marks a zone
1463 newMomentProto
.local = function (keepLocalTime
) {
1464 // for when converting from ambiguously-zoned to local,
1465 // keep the time values when converting from UTC -> local
1466 oldMomentProto
.local
.call(this, this._ambigZone
|| keepLocalTime
);
1467 // ensure non-ambiguous
1468 // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals
1469 this._ambigTime
= false;
1470 this._ambigZone
= false;
1471 return this; // for chaining
1473 // implicitly marks a zone
1474 newMomentProto
.utc = function (keepLocalTime
) {
1475 oldMomentProto
.utc
.call(this, keepLocalTime
);
1476 // ensure non-ambiguous
1477 // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals
1478 this._ambigTime
= false;
1479 this._ambigZone
= false;
1482 // implicitly marks a zone (will probably get called upon .utc() and .local())
1483 newMomentProto
.utcOffset = function (tzo
) {
1485 // these assignments needs to happen before the original zone method is called.
1486 // I forget why, something to do with a browser crash.
1487 this._ambigTime
= false;
1488 this._ambigZone
= false;
1490 return oldMomentProto
.utcOffset
.apply(this, arguments
);
1496 /***/ (function(module
, exports
, __webpack_require__
) {
1500 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
1502 on: EmitterInterface['on']
1503 one: EmitterInterface['one']
1504 off: EmitterInterface['off']
1505 trigger: EmitterInterface['trigger']
1506 triggerWith: EmitterInterface['triggerWith']
1507 hasHandlers: EmitterInterface['hasHandlers']
1509 EmitterMixin.mixInto(TheClass)
1511 Object
.defineProperty(exports
, "__esModule", { value
: true });
1512 var tslib_1
= __webpack_require__(2);
1513 var $ = __webpack_require__(3);
1514 var Mixin_1
= __webpack_require__(14);
1515 var EmitterMixin
= /** @class */ (function (_super
) {
1516 tslib_1
.__extends(EmitterMixin
, _super
);
1517 function EmitterMixin() {
1518 return _super
!== null && _super
.apply(this, arguments
) || this;
1520 // jQuery-ification via $(this) allows a non-DOM object to have
1521 // the same event handling capabilities (including namespaces).
1522 EmitterMixin
.prototype.on = function (types
, handler
) {
1523 $(this).on(types
, this._prepareIntercept(handler
));
1524 return this; // for chaining
1526 EmitterMixin
.prototype.one = function (types
, handler
) {
1527 $(this).one(types
, this._prepareIntercept(handler
));
1528 return this; // for chaining
1530 EmitterMixin
.prototype._prepareIntercept = function (handler
) {
1531 // handlers are always called with an "event" object as their first param.
1532 // sneak the `this` context and arguments into the extra parameter object
1533 // and forward them on to the original handler.
1534 var intercept = function (ev
, extra
) {
1535 return handler
.apply(extra
.context
|| this, extra
.args
|| []);
1537 // mimick jQuery's internal "proxy" system (risky, I know)
1538 // causing all functions with the same .guid to appear to be the same.
1539 // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448
1540 // this is needed for calling .off with the original non-intercept handler.
1541 if (!handler
.guid
) {
1542 handler
.guid
= $.guid
++;
1544 intercept
.guid
= handler
.guid
;
1547 EmitterMixin
.prototype.off = function (types
, handler
) {
1548 $(this).off(types
, handler
);
1549 return this; // for chaining
1551 EmitterMixin
.prototype.trigger = function (types
) {
1553 for (var _i
= 1; _i
< arguments
.length
; _i
++) {
1554 args
[_i
- 1] = arguments
[_i
];
1556 // pass in "extra" info to the intercept
1557 $(this).triggerHandler(types
, { args
: args
});
1558 return this; // for chaining
1560 EmitterMixin
.prototype.triggerWith = function (types
, context
, args
) {
1561 // `triggerHandler` is less reliant on the DOM compared to `trigger`.
1562 // pass in "extra" info to the intercept.
1563 $(this).triggerHandler(types
, { context
: context
, args
: args
});
1564 return this; // for chaining
1566 EmitterMixin
.prototype.hasHandlers = function (type
) {
1567 var hash
= $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/
1568 return hash
&& hash
[type
] && hash
[type
].length
> 0;
1570 return EmitterMixin
;
1571 }(Mixin_1
.default));
1572 exports
.default = EmitterMixin
;
1577 /***/ (function(module
, exports
) {
1579 Object
.defineProperty(exports
, "__esModule", { value
: true });
1581 Meant to be immutable
1583 var ComponentFootprint
= /** @class */ (function () {
1584 function ComponentFootprint(unzonedRange
, isAllDay
) {
1585 this.isAllDay
= false; // component can choose to ignore this
1586 this.unzonedRange
= unzonedRange
;
1587 this.isAllDay
= isAllDay
;
1590 Only works for non-open-ended ranges.
1592 ComponentFootprint
.prototype.toLegacy = function (calendar
) {
1594 start
: calendar
.msToMoment(this.unzonedRange
.startMs
, this.isAllDay
),
1595 end
: calendar
.msToMoment(this.unzonedRange
.endMs
, this.isAllDay
)
1598 return ComponentFootprint
;
1600 exports
.default = ComponentFootprint
;
1605 /***/ (function(module
, exports
, __webpack_require__
) {
1607 Object
.defineProperty(exports
, "__esModule", { value
: true });
1608 var tslib_1
= __webpack_require__(2);
1609 var EventDef_1
= __webpack_require__(34);
1610 var EventInstance_1
= __webpack_require__(209);
1611 var EventDateProfile_1
= __webpack_require__(17);
1612 var SingleEventDef
= /** @class */ (function (_super
) {
1613 tslib_1
.__extends(SingleEventDef
, _super
);
1614 function SingleEventDef() {
1615 return _super
!== null && _super
.apply(this, arguments
) || this;
1618 Will receive start/end params, but will be ignored.
1620 SingleEventDef
.prototype.buildInstances = function () {
1621 return [this.buildInstance()];
1623 SingleEventDef
.prototype.buildInstance = function () {
1624 return new EventInstance_1
.default(this, // definition
1627 SingleEventDef
.prototype.isAllDay = function () {
1628 return this.dateProfile
.isAllDay();
1630 SingleEventDef
.prototype.clone = function () {
1631 var def
= _super
.prototype.clone
.call(this);
1632 def
.dateProfile
= this.dateProfile
;
1635 SingleEventDef
.prototype.rezone = function () {
1636 var calendar
= this.source
.calendar
;
1637 var dateProfile
= this.dateProfile
;
1638 this.dateProfile
= new EventDateProfile_1
.default(calendar
.moment(dateProfile
.start
), dateProfile
.end
? calendar
.moment(dateProfile
.end
) : null, calendar
);
1641 NOTE: if super-method fails, should still attempt to apply
1643 SingleEventDef
.prototype.applyManualStandardProps = function (rawProps
) {
1644 var superSuccess
= _super
.prototype.applyManualStandardProps
.call(this, rawProps
);
1645 var dateProfile
= EventDateProfile_1
.default.parse(rawProps
, this.source
); // returns null on failure
1647 this.dateProfile
= dateProfile
;
1648 // make sure `date` shows up in the legacy event objects as-is
1649 if (rawProps
.date
!= null) {
1650 this.miscProps
.date
= rawProps
.date
;
1652 return superSuccess
;
1658 return SingleEventDef
;
1659 }(EventDef_1
.default));
1660 exports
.default = SingleEventDef
;
1662 // ---------------------------------------------------------------------------------------------------------------------
1663 SingleEventDef
.defineStandardProps({
1673 /***/ (function(module
, exports
) {
1675 Object
.defineProperty(exports
, "__esModule", { value
: true });
1676 var Mixin
= /** @class */ (function () {
1679 Mixin
.mixInto = function (destClass
) {
1681 Object
.getOwnPropertyNames(this.prototype).forEach(function (name
) {
1682 if (!destClass
.prototype[name
]) {
1683 destClass
.prototype[name
] = _this
.prototype[name
];
1688 will override existing methods
1689 TODO: remove! not used anymore
1691 Mixin
.mixOver = function (destClass
) {
1693 Object
.getOwnPropertyNames(this.prototype).forEach(function (name
) {
1694 destClass
.prototype[name
] = _this
.prototype[name
];
1699 exports
.default = Mixin
;
1704 /***/ (function(module
, exports
) {
1706 Object
.defineProperty(exports
, "__esModule", { value
: true });
1707 var Interaction
= /** @class */ (function () {
1708 function Interaction(component
) {
1709 this.view
= component
._getView();
1710 this.component
= component
;
1712 Interaction
.prototype.opt = function (name
) {
1713 return this.view
.opt(name
);
1715 Interaction
.prototype.end = function () {
1716 // subclasses can implement
1720 exports
.default = Interaction
;
1725 /***/ (function(module
, exports
, __webpack_require__
) {
1727 Object
.defineProperty(exports
, "__esModule", { value
: true });
1728 exports
.version
= '3.9.0';
1729 // When introducing internal API incompatibilities (where fullcalendar plugins would break),
1730 // the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0)
1731 // and the below integer should be incremented.
1732 exports
.internalApiVersion
= 12;
1733 var util_1
= __webpack_require__(4);
1734 exports
.applyAll
= util_1
.applyAll
;
1735 exports
.debounce
= util_1
.debounce
;
1736 exports
.isInt
= util_1
.isInt
;
1737 exports
.htmlEscape
= util_1
.htmlEscape
;
1738 exports
.cssToStr
= util_1
.cssToStr
;
1739 exports
.proxy
= util_1
.proxy
;
1740 exports
.capitaliseFirstLetter
= util_1
.capitaliseFirstLetter
;
1741 exports
.getOuterRect
= util_1
.getOuterRect
;
1742 exports
.getClientRect
= util_1
.getClientRect
;
1743 exports
.getContentRect
= util_1
.getContentRect
;
1744 exports
.getScrollbarWidths
= util_1
.getScrollbarWidths
;
1745 exports
.preventDefault
= util_1
.preventDefault
;
1746 exports
.parseFieldSpecs
= util_1
.parseFieldSpecs
;
1747 exports
.compareByFieldSpecs
= util_1
.compareByFieldSpecs
;
1748 exports
.compareByFieldSpec
= util_1
.compareByFieldSpec
;
1749 exports
.flexibleCompare
= util_1
.flexibleCompare
;
1750 exports
.computeGreatestUnit
= util_1
.computeGreatestUnit
;
1751 exports
.divideRangeByDuration
= util_1
.divideRangeByDuration
;
1752 exports
.divideDurationByDuration
= util_1
.divideDurationByDuration
;
1753 exports
.multiplyDuration
= util_1
.multiplyDuration
;
1754 exports
.durationHasTime
= util_1
.durationHasTime
;
1755 exports
.log
= util_1
.log
;
1756 exports
.warn
= util_1
.warn
;
1757 exports
.removeExact
= util_1
.removeExact
;
1758 exports
.intersectRects
= util_1
.intersectRects
;
1759 var date_formatting_1
= __webpack_require__(47);
1760 exports
.formatDate
= date_formatting_1
.formatDate
;
1761 exports
.formatRange
= date_formatting_1
.formatRange
;
1762 exports
.queryMostGranularFormatUnit
= date_formatting_1
.queryMostGranularFormatUnit
;
1763 var locale_1
= __webpack_require__(31);
1764 exports
.datepickerLocale
= locale_1
.datepickerLocale
;
1765 exports
.locale
= locale_1
.locale
;
1766 var moment_ext_1
= __webpack_require__(10);
1767 exports
.moment
= moment_ext_1
.default;
1768 var EmitterMixin_1
= __webpack_require__(11);
1769 exports
.EmitterMixin
= EmitterMixin_1
.default;
1770 var ListenerMixin_1
= __webpack_require__(7);
1771 exports
.ListenerMixin
= ListenerMixin_1
.default;
1772 var Model_1
= __webpack_require__(48);
1773 exports
.Model
= Model_1
.default;
1774 var Constraints_1
= __webpack_require__(207);
1775 exports
.Constraints
= Constraints_1
.default;
1776 var UnzonedRange_1
= __webpack_require__(5);
1777 exports
.UnzonedRange
= UnzonedRange_1
.default;
1778 var ComponentFootprint_1
= __webpack_require__(12);
1779 exports
.ComponentFootprint
= ComponentFootprint_1
.default;
1780 var BusinessHourGenerator_1
= __webpack_require__(212);
1781 exports
.BusinessHourGenerator
= BusinessHourGenerator_1
.default;
1782 var EventDef_1
= __webpack_require__(34);
1783 exports
.EventDef
= EventDef_1
.default;
1784 var EventDefMutation_1
= __webpack_require__(37);
1785 exports
.EventDefMutation
= EventDefMutation_1
.default;
1786 var EventSourceParser_1
= __webpack_require__(38);
1787 exports
.EventSourceParser
= EventSourceParser_1
.default;
1788 var EventSource_1
= __webpack_require__(6);
1789 exports
.EventSource
= EventSource_1
.default;
1790 var ThemeRegistry_1
= __webpack_require__(51);
1791 exports
.defineThemeSystem
= ThemeRegistry_1
.defineThemeSystem
;
1792 var EventInstanceGroup_1
= __webpack_require__(18);
1793 exports
.EventInstanceGroup
= EventInstanceGroup_1
.default;
1794 var ArrayEventSource_1
= __webpack_require__(52);
1795 exports
.ArrayEventSource
= ArrayEventSource_1
.default;
1796 var FuncEventSource_1
= __webpack_require__(215);
1797 exports
.FuncEventSource
= FuncEventSource_1
.default;
1798 var JsonFeedEventSource_1
= __webpack_require__(216);
1799 exports
.JsonFeedEventSource
= JsonFeedEventSource_1
.default;
1800 var EventFootprint_1
= __webpack_require__(36);
1801 exports
.EventFootprint
= EventFootprint_1
.default;
1802 var Class_1
= __webpack_require__(33);
1803 exports
.Class
= Class_1
.default;
1804 var Mixin_1
= __webpack_require__(14);
1805 exports
.Mixin
= Mixin_1
.default;
1806 var CoordCache_1
= __webpack_require__(53);
1807 exports
.CoordCache
= CoordCache_1
.default;
1808 var DragListener_1
= __webpack_require__(54);
1809 exports
.DragListener
= DragListener_1
.default;
1810 var Promise_1
= __webpack_require__(20);
1811 exports
.Promise
= Promise_1
.default;
1812 var TaskQueue_1
= __webpack_require__(217);
1813 exports
.TaskQueue
= TaskQueue_1
.default;
1814 var RenderQueue_1
= __webpack_require__(218);
1815 exports
.RenderQueue
= RenderQueue_1
.default;
1816 var Scroller_1
= __webpack_require__(39);
1817 exports
.Scroller
= Scroller_1
.default;
1818 var Theme_1
= __webpack_require__(19);
1819 exports
.Theme
= Theme_1
.default;
1820 var DateComponent_1
= __webpack_require__(219);
1821 exports
.DateComponent
= DateComponent_1
.default;
1822 var InteractiveDateComponent_1
= __webpack_require__(40);
1823 exports
.InteractiveDateComponent
= InteractiveDateComponent_1
.default;
1824 var Calendar_1
= __webpack_require__(220);
1825 exports
.Calendar
= Calendar_1
.default;
1826 var View_1
= __webpack_require__(41);
1827 exports
.View
= View_1
.default;
1828 var ViewRegistry_1
= __webpack_require__(22);
1829 exports
.defineView
= ViewRegistry_1
.defineView
;
1830 exports
.getViewConfig
= ViewRegistry_1
.getViewConfig
;
1831 var DayTableMixin_1
= __webpack_require__(55);
1832 exports
.DayTableMixin
= DayTableMixin_1
.default;
1833 var BusinessHourRenderer_1
= __webpack_require__(56);
1834 exports
.BusinessHourRenderer
= BusinessHourRenderer_1
.default;
1835 var EventRenderer_1
= __webpack_require__(42);
1836 exports
.EventRenderer
= EventRenderer_1
.default;
1837 var FillRenderer_1
= __webpack_require__(57);
1838 exports
.FillRenderer
= FillRenderer_1
.default;
1839 var HelperRenderer_1
= __webpack_require__(58);
1840 exports
.HelperRenderer
= HelperRenderer_1
.default;
1841 var ExternalDropping_1
= __webpack_require__(222);
1842 exports
.ExternalDropping
= ExternalDropping_1
.default;
1843 var EventResizing_1
= __webpack_require__(223);
1844 exports
.EventResizing
= EventResizing_1
.default;
1845 var EventPointing_1
= __webpack_require__(59);
1846 exports
.EventPointing
= EventPointing_1
.default;
1847 var EventDragging_1
= __webpack_require__(224);
1848 exports
.EventDragging
= EventDragging_1
.default;
1849 var DateSelecting_1
= __webpack_require__(225);
1850 exports
.DateSelecting
= DateSelecting_1
.default;
1851 var StandardInteractionsMixin_1
= __webpack_require__(60);
1852 exports
.StandardInteractionsMixin
= StandardInteractionsMixin_1
.default;
1853 var AgendaView_1
= __webpack_require__(226);
1854 exports
.AgendaView
= AgendaView_1
.default;
1855 var TimeGrid_1
= __webpack_require__(227);
1856 exports
.TimeGrid
= TimeGrid_1
.default;
1857 var DayGrid_1
= __webpack_require__(61);
1858 exports
.DayGrid
= DayGrid_1
.default;
1859 var BasicView_1
= __webpack_require__(62);
1860 exports
.BasicView
= BasicView_1
.default;
1861 var MonthView_1
= __webpack_require__(229);
1862 exports
.MonthView
= MonthView_1
.default;
1863 var ListView_1
= __webpack_require__(230);
1864 exports
.ListView
= ListView_1
.default;
1869 /***/ (function(module
, exports
, __webpack_require__
) {
1871 Object
.defineProperty(exports
, "__esModule", { value
: true });
1872 var UnzonedRange_1
= __webpack_require__(5);
1874 Meant to be immutable
1876 var EventDateProfile
= /** @class */ (function () {
1877 function EventDateProfile(start
, end
, calendar
) {
1879 this.end
= end
|| null;
1880 this.unzonedRange
= this.buildUnzonedRange(calendar
);
1883 Needs an EventSource object
1885 EventDateProfile
.parse = function (rawProps
, source
) {
1886 var startInput
= rawProps
.start
|| rawProps
.date
;
1887 var endInput
= rawProps
.end
;
1891 var calendar
= source
.calendar
;
1892 var start
= calendar
.moment(startInput
);
1893 var end
= endInput
? calendar
.moment(endInput
) : null;
1894 var forcedAllDay
= rawProps
.allDay
;
1895 var forceEventDuration
= calendar
.opt('forceEventDuration');
1896 if (!start
.isValid()) {
1899 if (end
&& (!end
.isValid() || !end
.isAfter(start
))) {
1902 if (forcedAllDay
== null) {
1903 forcedAllDay
= source
.allDayDefault
;
1904 if (forcedAllDay
== null) {
1905 forcedAllDay
= calendar
.opt('allDayDefault');
1908 if (forcedAllDay
=== true) {
1914 else if (forcedAllDay
=== false) {
1915 if (!start
.hasTime()) {
1918 if (end
&& !end
.hasTime()) {
1922 if (!end
&& forceEventDuration
) {
1923 end
= calendar
.getDefaultEventEnd(!start
.hasTime(), start
);
1925 return new EventDateProfile(start
, end
, calendar
);
1927 EventDateProfile
.isStandardProp = function (propName
) {
1928 return propName
=== 'start' || propName
=== 'date' || propName
=== 'end' || propName
=== 'allDay';
1930 EventDateProfile
.prototype.isAllDay = function () {
1931 return !(this.start
.hasTime() || (this.end
&& this.end
.hasTime()));
1934 Needs a Calendar object
1936 EventDateProfile
.prototype.buildUnzonedRange = function (calendar
) {
1937 var startMs
= this.start
.clone().stripZone().valueOf();
1938 var endMs
= this.getEnd(calendar
).stripZone().valueOf();
1939 return new UnzonedRange_1
.default(startMs
, endMs
);
1942 Needs a Calendar object
1944 EventDateProfile
.prototype.getEnd = function (calendar
) {
1947 // derive the end from the start and allDay. compute allDay if necessary
1948 calendar
.getDefaultEventEnd(this.isAllDay(), this.start
);
1950 return EventDateProfile
;
1952 exports
.default = EventDateProfile
;
1957 /***/ (function(module
, exports
, __webpack_require__
) {
1959 Object
.defineProperty(exports
, "__esModule", { value
: true });
1960 var UnzonedRange_1
= __webpack_require__(5);
1961 var util_1
= __webpack_require__(35);
1962 var EventRange_1
= __webpack_require__(211);
1964 It's expected that there will be at least one EventInstance,
1965 OR that an explicitEventDef is assigned.
1967 var EventInstanceGroup
= /** @class */ (function () {
1968 function EventInstanceGroup(eventInstances
) {
1969 this.eventInstances
= eventInstances
|| [];
1971 EventInstanceGroup
.prototype.getAllEventRanges = function (constraintRange
) {
1972 if (constraintRange
) {
1973 return this.sliceNormalRenderRanges(constraintRange
);
1976 return this.eventInstances
.map(util_1
.eventInstanceToEventRange
);
1979 EventInstanceGroup
.prototype.sliceRenderRanges = function (constraintRange
) {
1980 if (this.isInverse()) {
1981 return this.sliceInverseRenderRanges(constraintRange
);
1984 return this.sliceNormalRenderRanges(constraintRange
);
1987 EventInstanceGroup
.prototype.sliceNormalRenderRanges = function (constraintRange
) {
1988 var eventInstances
= this.eventInstances
;
1992 var slicedEventRanges
= [];
1993 for (i
= 0; i
< eventInstances
.length
; i
++) {
1994 eventInstance
= eventInstances
[i
];
1995 slicedRange
= eventInstance
.dateProfile
.unzonedRange
.intersect(constraintRange
);
1997 slicedEventRanges
.push(new EventRange_1
.default(slicedRange
, eventInstance
.def
, eventInstance
));
2000 return slicedEventRanges
;
2002 EventInstanceGroup
.prototype.sliceInverseRenderRanges = function (constraintRange
) {
2003 var unzonedRanges
= this.eventInstances
.map(util_1
.eventInstanceToUnzonedRange
);
2004 var ownerDef
= this.getEventDef();
2005 unzonedRanges
= UnzonedRange_1
.default.invertRanges(unzonedRanges
, constraintRange
);
2006 return unzonedRanges
.map(function (unzonedRange
) {
2007 return new EventRange_1
.default(unzonedRange
, ownerDef
); // don't give an EventInstance
2010 EventInstanceGroup
.prototype.isInverse = function () {
2011 return this.getEventDef().hasInverseRendering();
2013 EventInstanceGroup
.prototype.getEventDef = function () {
2014 return this.explicitEventDef
|| this.eventInstances
[0].def
;
2016 return EventInstanceGroup
;
2018 exports
.default = EventInstanceGroup
;
2023 /***/ (function(module
, exports
, __webpack_require__
) {
2025 Object
.defineProperty(exports
, "__esModule", { value
: true });
2026 var $ = __webpack_require__(3);
2027 var Theme
= /** @class */ (function () {
2028 function Theme(optionsManager
) {
2029 this.optionsManager
= optionsManager
;
2030 this.processIconOverride();
2032 Theme
.prototype.processIconOverride = function () {
2033 if (this.iconOverrideOption
) {
2034 this.setIconOverride(this.optionsManager
.get(this.iconOverrideOption
));
2037 Theme
.prototype.setIconOverride = function (iconOverrideHash
) {
2038 var iconClassesCopy
;
2040 if ($.isPlainObject(iconOverrideHash
)) {
2041 iconClassesCopy
= $.extend({}, this.iconClasses
);
2042 for (buttonName
in iconOverrideHash
) {
2043 iconClassesCopy
[buttonName
] = this.applyIconOverridePrefix(iconOverrideHash
[buttonName
]);
2045 this.iconClasses
= iconClassesCopy
;
2047 else if (iconOverrideHash
=== false) {
2048 this.iconClasses
= {};
2051 Theme
.prototype.applyIconOverridePrefix = function (className
) {
2052 var prefix
= this.iconOverridePrefix
;
2053 if (prefix
&& className
.indexOf(prefix
) !== 0) {
2054 className
= prefix
+ className
;
2058 Theme
.prototype.getClass = function (key
) {
2059 return this.classes
[key
] || '';
2061 Theme
.prototype.getIconClass = function (buttonName
) {
2062 var className
= this.iconClasses
[buttonName
];
2064 return this.baseIconClass
+ ' ' + className
;
2068 Theme
.prototype.getCustomButtonIconClass = function (customButtonProps
) {
2070 if (this.iconOverrideCustomButtonOption
) {
2071 className
= customButtonProps
[this.iconOverrideCustomButtonOption
];
2073 return this.baseIconClass
+ ' ' + this.applyIconOverridePrefix(className
);
2080 exports
.default = Theme
;
2081 Theme
.prototype.classes
= {};
2082 Theme
.prototype.iconClasses
= {};
2083 Theme
.prototype.baseIconClass
= '';
2084 Theme
.prototype.iconOverridePrefix
= '';
2089 /***/ (function(module
, exports
, __webpack_require__
) {
2091 Object
.defineProperty(exports
, "__esModule", { value
: true });
2092 var $ = __webpack_require__(3);
2094 construct: function (executor
) {
2095 var deferred
= $.Deferred();
2096 var promise
= deferred
.promise();
2097 if (typeof executor
=== 'function') {
2098 executor(function (val
) {
2099 deferred
.resolve(val
);
2100 attachImmediatelyResolvingThen(promise
, val
);
2103 attachImmediatelyRejectingThen(promise
);
2108 resolve: function (val
) {
2109 var deferred
= $.Deferred().resolve(val
);
2110 var promise
= deferred
.promise();
2111 attachImmediatelyResolvingThen(promise
, val
);
2114 reject: function () {
2115 var deferred
= $.Deferred().reject();
2116 var promise
= deferred
.promise();
2117 attachImmediatelyRejectingThen(promise
);
2121 exports
.default = PromiseStub
;
2122 function attachImmediatelyResolvingThen(promise
, val
) {
2123 promise
.then = function (onResolve
) {
2124 if (typeof onResolve
=== 'function') {
2125 return PromiseStub
.resolve(onResolve(val
));
2130 function attachImmediatelyRejectingThen(promise
) {
2131 promise
.then = function (onResolve
, onReject
) {
2132 if (typeof onReject
=== 'function') {
2142 /***/ (function(module
, exports
, __webpack_require__
) {
2144 Object
.defineProperty(exports
, "__esModule", { value
: true });
2145 var $ = __webpack_require__(3);
2146 var exportHooks
= __webpack_require__(16);
2147 var EmitterMixin_1
= __webpack_require__(11);
2148 var ListenerMixin_1
= __webpack_require__(7);
2149 exportHooks
.touchMouseIgnoreWait
= 500;
2150 var globalEmitter
= null;
2151 var neededCount
= 0;
2153 Listens to document and window-level user-interaction events, like touch events and mouse events,
2154 and fires these events as-is to whoever is observing a GlobalEmitter.
2155 Best when used as a singleton via GlobalEmitter.get()
2157 Normalizes mouse/touch events. For examples:
2158 - ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click
2159 - compensates for various buggy scenarios where a touchend does not fire
2161 var GlobalEmitter
= /** @class */ (function () {
2162 function GlobalEmitter() {
2163 this.isTouching
= false;
2164 this.mouseIgnoreDepth
= 0;
2166 // gets the singleton
2167 GlobalEmitter
.get = function () {
2168 if (!globalEmitter
) {
2169 globalEmitter
= new GlobalEmitter();
2170 globalEmitter
.bind();
2172 return globalEmitter
;
2174 // called when an object knows it will need a GlobalEmitter in the near future.
2175 GlobalEmitter
.needed = function () {
2176 GlobalEmitter
.get(); // ensures globalEmitter
2179 // called when the object that originally called needed() doesn't need a GlobalEmitter anymore.
2180 GlobalEmitter
.unneeded = function () {
2183 globalEmitter
.unbind();
2184 globalEmitter
= null;
2187 GlobalEmitter
.prototype.bind = function () {
2189 this.listenTo($(document
), {
2190 touchstart
: this.handleTouchStart
,
2191 touchcancel
: this.handleTouchCancel
,
2192 touchend
: this.handleTouchEnd
,
2193 mousedown
: this.handleMouseDown
,
2194 mousemove
: this.handleMouseMove
,
2195 mouseup
: this.handleMouseUp
,
2196 click
: this.handleClick
,
2197 selectstart
: this.handleSelectStart
,
2198 contextmenu
: this.handleContextMenu
2200 // because we need to call preventDefault
2201 // because https://www.chromestatus.com/features/5093566007214080
2202 // TODO: investigate performance because this is a global handler
2203 window
.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev
) {
2204 _this
.handleTouchMove($.Event(ev
));
2205 }, { passive
: false } // allows preventDefault()
2207 // attach a handler to get called when ANY scroll action happens on the page.
2208 // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
2209 // http://stackoverflow.com/a/32954565/96342
2210 window
.addEventListener('scroll', this.handleScrollProxy = function (ev
) {
2211 _this
.handleScroll($.Event(ev
));
2212 }, true // useCapture
2215 GlobalEmitter
.prototype.unbind = function () {
2216 this.stopListeningTo($(document
));
2217 window
.removeEventListener('touchmove', this.handleTouchMoveProxy
);
2218 window
.removeEventListener('scroll', this.handleScrollProxy
, true // useCapture
2222 // -----------------------------------------------------------------------------------------------------------------
2223 GlobalEmitter
.prototype.handleTouchStart = function (ev
) {
2224 // if a previous touch interaction never ended with a touchend, then implicitly end it,
2225 // but since a new touch interaction is about to begin, don't start the mouse ignore period.
2226 this.stopTouch(ev
, true); // skipMouseIgnore=true
2227 this.isTouching
= true;
2228 this.trigger('touchstart', ev
);
2230 GlobalEmitter
.prototype.handleTouchMove = function (ev
) {
2231 if (this.isTouching
) {
2232 this.trigger('touchmove', ev
);
2235 GlobalEmitter
.prototype.handleTouchCancel = function (ev
) {
2236 if (this.isTouching
) {
2237 this.trigger('touchcancel', ev
);
2238 // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both.
2239 // If touchend fires later, it won't have any effect b/c isTouching will be false.
2243 GlobalEmitter
.prototype.handleTouchEnd = function (ev
) {
2247 // -----------------------------------------------------------------------------------------------------------------
2248 GlobalEmitter
.prototype.handleMouseDown = function (ev
) {
2249 if (!this.shouldIgnoreMouse()) {
2250 this.trigger('mousedown', ev
);
2253 GlobalEmitter
.prototype.handleMouseMove = function (ev
) {
2254 if (!this.shouldIgnoreMouse()) {
2255 this.trigger('mousemove', ev
);
2258 GlobalEmitter
.prototype.handleMouseUp = function (ev
) {
2259 if (!this.shouldIgnoreMouse()) {
2260 this.trigger('mouseup', ev
);
2263 GlobalEmitter
.prototype.handleClick = function (ev
) {
2264 if (!this.shouldIgnoreMouse()) {
2265 this.trigger('click', ev
);
2269 // -----------------------------------------------------------------------------------------------------------------
2270 GlobalEmitter
.prototype.handleSelectStart = function (ev
) {
2271 this.trigger('selectstart', ev
);
2273 GlobalEmitter
.prototype.handleContextMenu = function (ev
) {
2274 this.trigger('contextmenu', ev
);
2276 GlobalEmitter
.prototype.handleScroll = function (ev
) {
2277 this.trigger('scroll', ev
);
2280 // -----------------------------------------------------------------------------------------------------------------
2281 GlobalEmitter
.prototype.stopTouch = function (ev
, skipMouseIgnore
) {
2282 if (skipMouseIgnore
=== void 0) { skipMouseIgnore
= false; }
2283 if (this.isTouching
) {
2284 this.isTouching
= false;
2285 this.trigger('touchend', ev
);
2286 if (!skipMouseIgnore
) {
2287 this.startTouchMouseIgnore();
2291 GlobalEmitter
.prototype.startTouchMouseIgnore = function () {
2293 var wait
= exportHooks
.touchMouseIgnoreWait
;
2295 this.mouseIgnoreDepth
++;
2296 setTimeout(function () {
2297 _this
.mouseIgnoreDepth
--;
2301 GlobalEmitter
.prototype.shouldIgnoreMouse = function () {
2302 return this.isTouching
|| Boolean(this.mouseIgnoreDepth
);
2304 return GlobalEmitter
;
2306 exports
.default = GlobalEmitter
;
2307 ListenerMixin_1
.default.mixInto(GlobalEmitter
);
2308 EmitterMixin_1
.default.mixInto(GlobalEmitter
);
2313 /***/ (function(module
, exports
, __webpack_require__
) {
2315 Object
.defineProperty(exports
, "__esModule", { value
: true });
2316 var exportHooks
= __webpack_require__(16);
2317 exports
.viewHash
= {};
2318 exportHooks
.views
= exports
.viewHash
;
2319 function defineView(viewName
, viewConfig
) {
2320 exports
.viewHash
[viewName
] = viewConfig
;
2322 exports
.defineView
= defineView
;
2323 function getViewConfig(viewName
) {
2324 return exports
.viewHash
[viewName
];
2326 exports
.getViewConfig
= getViewConfig
;
2331 /***/ (function(module
, exports
, __webpack_require__
) {
2333 Object
.defineProperty(exports
, "__esModule", { value
: true });
2334 var tslib_1
= __webpack_require__(2);
2335 var util_1
= __webpack_require__(4);
2336 var DragListener_1
= __webpack_require__(54);
2337 /* Tracks mouse movements over a component and raises events about which hit the mouse is over.
2338 ------------------------------------------------------------------------------------------------------------------------
2343 var HitDragListener
= /** @class */ (function (_super
) {
2344 tslib_1
.__extends(HitDragListener
, _super
);
2345 function HitDragListener(component
, options
) {
2346 var _this
= _super
.call(this, options
) || this;
2347 _this
.component
= component
;
2350 // Called when drag listening starts (but a real drag has not necessarily began).
2351 // ev might be undefined if dragging was started manually.
2352 HitDragListener
.prototype.handleInteractionStart = function (ev
) {
2353 var subjectEl
= this.subjectEl
;
2357 this.component
.hitsNeeded();
2358 this.computeScrollBounds(); // for autoscroll
2360 origPoint
= { left
: util_1
.getEvX(ev
), top
: util_1
.getEvY(ev
) };
2362 // constrain the point to bounds of the element being dragged
2364 subjectRect
= util_1
.getOuterRect(subjectEl
); // used for centering as well
2365 point
= util_1
.constrainPoint(point
, subjectRect
);
2367 this.origHit
= this.queryHit(point
.left
, point
.top
);
2368 // treat the center of the subject as the collision point?
2369 if (subjectEl
&& this.options
.subjectCenter
) {
2370 // only consider the area the subject overlaps the hit. best for large subjects.
2371 // TODO: skip this if hit didn't supply left/right/top/bottom
2373 subjectRect
= util_1
.intersectRects(this.origHit
, subjectRect
) ||
2374 subjectRect
; // in case there is no intersection
2376 point
= util_1
.getRectCenter(subjectRect
);
2378 this.coordAdjust
= util_1
.diffPoints(point
, origPoint
); // point - origPoint
2381 this.origHit
= null;
2382 this.coordAdjust
= null;
2384 // call the super-method. do it after origHit has been computed
2385 _super
.prototype.handleInteractionStart
.call(this, ev
);
2387 // Called when the actual drag has started
2388 HitDragListener
.prototype.handleDragStart = function (ev
) {
2390 _super
.prototype.handleDragStart
.call(this, ev
);
2391 // might be different from this.origHit if the min-distance is large
2392 hit
= this.queryHit(util_1
.getEvX(ev
), util_1
.getEvY(ev
));
2393 // report the initial hit the mouse is over
2394 // especially important if no min-distance and drag starts immediately
2396 this.handleHitOver(hit
);
2399 // Called when the drag moves
2400 HitDragListener
.prototype.handleDrag = function (dx
, dy
, ev
) {
2402 _super
.prototype.handleDrag
.call(this, dx
, dy
, ev
);
2403 hit
= this.queryHit(util_1
.getEvX(ev
), util_1
.getEvY(ev
));
2404 if (!isHitsEqual(hit
, this.hit
)) {
2406 this.handleHitOut();
2409 this.handleHitOver(hit
);
2413 // Called when dragging has been stopped
2414 HitDragListener
.prototype.handleDragEnd = function (ev
) {
2415 this.handleHitDone();
2416 _super
.prototype.handleDragEnd
.call(this, ev
);
2418 // Called when a the mouse has just moved over a new hit
2419 HitDragListener
.prototype.handleHitOver = function (hit
) {
2420 var isOrig
= isHitsEqual(hit
, this.origHit
);
2422 this.trigger('hitOver', this.hit
, isOrig
, this.origHit
);
2424 // Called when the mouse has just moved out of a hit
2425 HitDragListener
.prototype.handleHitOut = function () {
2427 this.trigger('hitOut', this.hit
);
2428 this.handleHitDone();
2432 // Called after a hitOut. Also called before a dragStop
2433 HitDragListener
.prototype.handleHitDone = function () {
2435 this.trigger('hitDone', this.hit
);
2438 // Called when the interaction ends, whether there was a real drag or not
2439 HitDragListener
.prototype.handleInteractionEnd = function (ev
, isCancelled
) {
2440 _super
.prototype.handleInteractionEnd
.call(this, ev
, isCancelled
);
2441 this.origHit
= null;
2443 this.component
.hitsNotNeeded();
2445 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
2446 HitDragListener
.prototype.handleScrollEnd = function () {
2447 _super
.prototype.handleScrollEnd
.call(this);
2448 // hits' absolute positions will be in new places after a user's scroll.
2449 // HACK for recomputing.
2450 if (this.isDragging
) {
2451 this.component
.releaseHits();
2452 this.component
.prepareHits();
2455 // Gets the hit underneath the coordinates for the given mouse event
2456 HitDragListener
.prototype.queryHit = function (left
, top
) {
2457 if (this.coordAdjust
) {
2458 left
+= this.coordAdjust
.left
;
2459 top
+= this.coordAdjust
.top
;
2461 return this.component
.queryHit(left
, top
);
2463 return HitDragListener
;
2464 }(DragListener_1
.default));
2465 exports
.default = HitDragListener
;
2466 // Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.
2467 // Two null values will be considered equal, as two "out of the component" states are the same.
2468 function isHitsEqual(hit0
, hit1
) {
2469 if (!hit0
&& !hit1
) {
2473 return hit0
.component
=== hit1
.component
&&
2474 isHitPropsWithin(hit0
, hit1
) &&
2475 isHitPropsWithin(hit1
, hit0
); // ensures all props are identical
2479 // Returns true if all of subHit's non-standard properties are within superHit
2480 function isHitPropsWithin(subHit
, superHit
) {
2481 for (var propName
in subHit
) {
2482 if (!/^(component|left|right|top|bottom)$/.test(propName
)) {
2483 if (subHit
[propName
] !== superHit
[propName
]) {
2501 /***/ (function(module
, exports
, __webpack_require__
) {
2503 Object
.defineProperty(exports
, "__esModule", { value
: true });
2504 var $ = __webpack_require__(3);
2505 var moment
= __webpack_require__(0);
2506 var exportHooks
= __webpack_require__(16);
2507 var options_1
= __webpack_require__(32);
2508 var util_1
= __webpack_require__(4);
2509 exports
.localeOptionHash
= {};
2510 exportHooks
.locales
= exports
.localeOptionHash
;
2511 // NOTE: can't guarantee any of these computations will run because not every locale has datepicker
2512 // configs, so make sure there are English fallbacks for these in the defaults file.
2513 var dpComputableOptions
= {
2514 buttonText: function (dpOptions
) {
2516 // the translations sometimes wrongly contain HTML entities
2517 prev
: util_1
.stripHtmlEntities(dpOptions
.prevText
),
2518 next
: util_1
.stripHtmlEntities(dpOptions
.nextText
),
2519 today
: util_1
.stripHtmlEntities(dpOptions
.currentText
)
2522 // Produces format strings like "MMMM YYYY" -> "September 2014"
2523 monthYearFormat: function (dpOptions
) {
2524 return dpOptions
.showMonthAfterYear
?
2525 'YYYY[' + dpOptions
.yearSuffix
+ '] MMMM' :
2526 'MMMM YYYY[' + dpOptions
.yearSuffix
+ ']';
2529 var momComputableOptions
= {
2530 // Produces format strings like "ddd M/D" -> "Fri 9/15"
2531 dayOfMonthFormat: function (momOptions
, fcOptions
) {
2532 var format
= momOptions
.longDateFormat('l'); // for the format like "M/D/YYYY"
2533 // strip the year off the edge, as well as other misc non-whitespace chars
2534 format
= format
.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '');
2535 if (fcOptions
.isRTL
) {
2536 format
+= ' ddd'; // for RTL, add day-of-week to end
2539 format
= 'ddd ' + format
; // for LTR, add day-of-week to beginning
2543 // Produces format strings like "h:mma" -> "6:00pm"
2544 mediumTimeFormat: function (momOptions
) {
2545 return momOptions
.longDateFormat('LT')
2546 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2548 // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
2549 smallTimeFormat: function (momOptions
) {
2550 return momOptions
.longDateFormat('LT')
2551 .replace(':mm', '(:mm)')
2552 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2553 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2555 // Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
2556 extraSmallTimeFormat: function (momOptions
) {
2557 return momOptions
.longDateFormat('LT')
2558 .replace(':mm', '(:mm)')
2559 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2560 .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
2562 // Produces format strings like "ha" / "H" -> "6pm" / "18"
2563 hourFormat: function (momOptions
) {
2564 return momOptions
.longDateFormat('LT')
2566 .replace(/(\Wmm)$/, '') // like above, but for foreign locales
2567 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2569 // Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
2570 noMeridiemTimeFormat: function (momOptions
) {
2571 return momOptions
.longDateFormat('LT')
2572 .replace(/\s*a$/i, ''); // remove trailing AM/PM
2575 // options that should be computed off live calendar options (considers override options)
2576 // TODO: best place for this? related to locale?
2577 // TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it
2578 var instanceComputableOptions
= {
2579 // Produces format strings for results like "Mo 16"
2580 smallDayDateFormat: function (options
) {
2581 return options
.isRTL
?
2585 // Produces format strings for results like "Wk 5"
2586 weekFormat: function (options
) {
2587 return options
.isRTL
?
2588 'w[ ' + options
.weekNumberTitle
+ ']' :
2589 '[' + options
.weekNumberTitle
+ ' ]w';
2591 // Produces format strings for results like "Wk5"
2592 smallWeekFormat: function (options
) {
2593 return options
.isRTL
?
2594 'w[' + options
.weekNumberTitle
+ ']' :
2595 '[' + options
.weekNumberTitle
+ ']w';
2598 // TODO: make these computable properties in optionsManager
2599 function populateInstanceComputableOptions(options
) {
2600 $.each(instanceComputableOptions
, function (name
, func
) {
2601 if (options
[name
] == null) {
2602 options
[name
] = func(options
);
2606 exports
.populateInstanceComputableOptions
= populateInstanceComputableOptions
;
2607 // Initialize jQuery UI datepicker translations while using some of the translations
2608 // Will set this as the default locales for datepicker.
2609 function datepickerLocale(localeCode
, dpLocaleCode
, dpOptions
) {
2610 // get the FullCalendar internal option hash for this locale. create if necessary
2611 var fcOptions
= exports
.localeOptionHash
[localeCode
] || (exports
.localeOptionHash
[localeCode
] = {});
2612 // transfer some simple options from datepicker to fc
2613 fcOptions
.isRTL
= dpOptions
.isRTL
;
2614 fcOptions
.weekNumberTitle
= dpOptions
.weekHeader
;
2615 // compute some more complex options from datepicker
2616 $.each(dpComputableOptions
, function (name
, func
) {
2617 fcOptions
[name
] = func(dpOptions
);
2619 var jqDatePicker
= $.datepicker
;
2620 // is jQuery UI Datepicker is on the page?
2622 // Register the locale data.
2623 // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker
2624 // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt".
2625 // Make an alias so the locale can be referenced either way.
2626 jqDatePicker
.regional
[dpLocaleCode
] =
2627 jqDatePicker
.regional
[localeCode
] = // alias
2629 // Alias 'en' to the default locale data. Do this every time.
2630 jqDatePicker
.regional
.en
= jqDatePicker
.regional
[''];
2631 // Set as Datepicker's global defaults.
2632 jqDatePicker
.setDefaults(dpOptions
);
2635 exports
.datepickerLocale
= datepickerLocale
;
2636 // Sets FullCalendar-specific translations. Will set the locales as the global default.
2637 function locale(localeCode
, newFcOptions
) {
2640 // get the FullCalendar internal option hash for this locale. create if necessary
2641 fcOptions
= exports
.localeOptionHash
[localeCode
] || (exports
.localeOptionHash
[localeCode
] = {});
2642 // provided new options for this locales? merge them in
2644 fcOptions
= exports
.localeOptionHash
[localeCode
] = options_1
.mergeOptions([fcOptions
, newFcOptions
]);
2646 // compute locale options that weren't defined.
2647 // always do this. newFcOptions can be undefined when initializing from i18n file,
2648 // so no way to tell if this is an initialization or a default-setting.
2649 momOptions
= getMomentLocaleData(localeCode
); // will fall back to en
2650 $.each(momComputableOptions
, function (name
, func
) {
2651 if (fcOptions
[name
] == null) {
2652 fcOptions
[name
] = (func
)(momOptions
, fcOptions
);
2655 // set it as the default locale for FullCalendar
2656 options_1
.globalDefaults
.locale
= localeCode
;
2658 exports
.locale
= locale
;
2659 // Returns moment's internal locale data. If doesn't exist, returns English.
2660 function getMomentLocaleData(localeCode
) {
2661 return moment
.localeData(localeCode
) || moment
.localeData('en');
2663 exports
.getMomentLocaleData
= getMomentLocaleData
;
2664 // Initialize English by forcing computation of moment-derived options.
2665 // Also, sets it as the default.
2666 locale('en', options_1
.englishDefaults
);
2671 /***/ (function(module
, exports
, __webpack_require__
) {
2673 Object
.defineProperty(exports
, "__esModule", { value
: true });
2674 var util_1
= __webpack_require__(4);
2675 exports
.globalDefaults
= {
2676 titleRangeSeparator
: ' \u2013 ',
2677 monthYearFormat
: 'MMMM YYYY',
2678 defaultTimedEventDuration
: '02:00:00',
2679 defaultAllDayEventDuration
: { days
: 1 },
2680 forceEventDuration
: false,
2681 nextDayThreshold
: '09:00:00',
2684 defaultView
: 'month',
2689 right
: 'today prev,next'
2693 weekNumberTitle
: 'W',
2694 weekNumberCalculation
: 'local',
2696 // nowIndicator: false,
2697 scrollTime
: '06:00:00',
2698 minTime
: '00:00:00',
2699 maxTime
: '24:00:00',
2700 showNonCurrentDates
: true,
2703 startParam
: 'start',
2705 timezoneParam
: 'timezone',
2707 // allDayDefault: undefined,
2714 prevYear
: 'prev year',
2715 nextYear
: 'next year',
2722 // buttonIcons: null,
2723 allDayText
: 'all-day',
2724 // allows setting a min-height to the event segment to prevent short events overlapping each other
2725 agendaEventMinHeight
: 0,
2726 // jquery-ui theming
2728 // themeButtonIcons: null,
2729 // eventResizableFromStart: false,
2731 dragRevertDuration
: 500,
2733 // selectable: false,
2735 // selectMinDistance: 0,
2737 eventOrder
: 'title',
2738 // eventRenderWait: null,
2740 eventLimitText
: 'more',
2741 eventLimitClick
: 'popover',
2742 dayPopoverFormat
: 'LL',
2743 handleWindowResize
: true,
2744 windowResizeDelay
: 100,
2745 longPressDelay
: 1000
2747 exports
.englishDefaults
= {
2748 dayPopoverFormat
: 'dddd, MMMM D'
2750 exports
.rtlDefaults
= {
2752 left
: 'next,prev today',
2757 prev
: 'right-single-arrow',
2758 next
: 'left-single-arrow',
2759 prevYear
: 'right-double-arrow',
2760 nextYear
: 'left-double-arrow'
2763 prev
: 'circle-triangle-e',
2764 next
: 'circle-triangle-w',
2765 nextYear
: 'seek-prev',
2766 prevYear
: 'seek-next'
2769 var complexOptions
= [
2776 // Merges an array of option objects into a single object
2777 function mergeOptions(optionObjs
) {
2778 return util_1
.mergeProps(optionObjs
, complexOptions
);
2780 exports
.mergeOptions
= mergeOptions
;
2785 /***/ (function(module
, exports
, __webpack_require__
) {
2787 Object
.defineProperty(exports
, "__esModule", { value
: true });
2788 var tslib_1
= __webpack_require__(2);
2789 var util_1
= __webpack_require__(4);
2790 // Class that all other classes will inherit from
2791 var Class
= /** @class */ (function () {
2794 // Called on a class to create a subclass.
2795 // LIMITATION: cannot provide a constructor!
2796 Class
.extend = function (members
) {
2797 var SubClass
= /** @class */ (function (_super
) {
2798 tslib_1
.__extends(SubClass
, _super
);
2799 function SubClass() {
2800 return _super
!== null && _super
.apply(this, arguments
) || this;
2804 util_1
.copyOwnProps(members
, SubClass
.prototype);
2807 // Adds new member variables/methods to the class's prototype.
2808 // Can be called with another class, or a plain object hash containing new members.
2809 Class
.mixin = function (members
) {
2810 util_1
.copyOwnProps(members
, this.prototype);
2814 exports
.default = Class
;
2819 /***/ (function(module
, exports
, __webpack_require__
) {
2821 Object
.defineProperty(exports
, "__esModule", { value
: true });
2822 var $ = __webpack_require__(3);
2823 var ParsableModelMixin_1
= __webpack_require__(208);
2824 var EventDef
= /** @class */ (function () {
2825 function EventDef(source
) {
2826 this.source
= source
;
2827 this.className
= [];
2828 this.miscProps
= {};
2830 EventDef
.parse = function (rawInput
, source
) {
2831 var def
= new this(source
);
2832 if (def
.applyProps(rawInput
)) {
2837 EventDef
.normalizeId = function (id
) {
2840 EventDef
.generateId = function () {
2841 return '_fc' + (EventDef
.uuid
++);
2843 EventDef
.prototype.clone = function () {
2844 var copy
= new this.constructor(this.source
);
2846 copy
.rawId
= this.rawId
;
2847 copy
.uid
= this.uid
; // not really unique anymore :(
2848 EventDef
.copyVerbatimStandardProps(this, copy
);
2849 copy
.className
= this.className
.slice(); // copy
2850 copy
.miscProps
= $.extend({}, this.miscProps
);
2853 EventDef
.prototype.hasInverseRendering = function () {
2854 return this.getRendering() === 'inverse-background';
2856 EventDef
.prototype.hasBgRendering = function () {
2857 var rendering
= this.getRendering();
2858 return rendering
=== 'inverse-background' || rendering
=== 'background';
2860 EventDef
.prototype.getRendering = function () {
2861 if (this.rendering
!= null) {
2862 return this.rendering
;
2864 return this.source
.rendering
;
2866 EventDef
.prototype.getConstraint = function () {
2867 if (this.constraint
!= null) {
2868 return this.constraint
;
2870 if (this.source
.constraint
!= null) {
2871 return this.source
.constraint
;
2873 return this.source
.calendar
.opt('eventConstraint'); // what about View option?
2875 EventDef
.prototype.getOverlap = function () {
2876 if (this.overlap
!= null) {
2877 return this.overlap
;
2879 if (this.source
.overlap
!= null) {
2880 return this.source
.overlap
;
2882 return this.source
.calendar
.opt('eventOverlap'); // what about View option?
2884 EventDef
.prototype.isStartExplicitlyEditable = function () {
2885 if (this.startEditable
!= null) {
2886 return this.startEditable
;
2888 return this.source
.startEditable
;
2890 EventDef
.prototype.isDurationExplicitlyEditable = function () {
2891 if (this.durationEditable
!= null) {
2892 return this.durationEditable
;
2894 return this.source
.durationEditable
;
2896 EventDef
.prototype.isExplicitlyEditable = function () {
2897 if (this.editable
!= null) {
2898 return this.editable
;
2900 return this.source
.editable
;
2902 EventDef
.prototype.toLegacy = function () {
2903 var obj
= $.extend({}, this.miscProps
);
2905 obj
.source
= this.source
;
2906 obj
.className
= this.className
.slice(); // copy
2907 obj
.allDay
= this.isAllDay();
2908 if (this.rawId
!= null) {
2909 obj
.id
= this.rawId
;
2911 EventDef
.copyVerbatimStandardProps(this, obj
);
2914 EventDef
.prototype.applyManualStandardProps = function (rawProps
) {
2915 if (rawProps
.id
!= null) {
2916 this.id
= EventDef
.normalizeId((this.rawId
= rawProps
.id
));
2919 this.id
= EventDef
.generateId();
2921 if (rawProps
._id
!= null) {
2922 this.uid
= String(rawProps
._id
);
2925 this.uid
= EventDef
.generateId();
2927 // TODO: converge with EventSource
2928 if ($.isArray(rawProps
.className
)) {
2929 this.className
= rawProps
.className
;
2931 if (typeof rawProps
.className
=== 'string') {
2932 this.className
= rawProps
.className
.split(/\s+/);
2936 EventDef
.prototype.applyMiscProps = function (rawProps
) {
2937 $.extend(this.miscProps
, rawProps
);
2940 EventDef
.defineStandardProps
= ParsableModelMixin_1
.default.defineStandardProps
;
2941 EventDef
.copyVerbatimStandardProps
= ParsableModelMixin_1
.default.copyVerbatimStandardProps
;
2944 exports
.default = EventDef
;
2945 ParsableModelMixin_1
.default.mixInto(EventDef
);
2946 EventDef
.defineStandardProps({
2947 // not automatically assigned (`false`)
2952 // automatically assigned (`true`)
2959 startEditable
: true,
2960 durationEditable
: true,
2962 backgroundColor
: true,
2970 /***/ (function(module
, exports
, __webpack_require__
) {
2972 Object
.defineProperty(exports
, "__esModule", { value
: true });
2973 var EventRange_1
= __webpack_require__(211);
2974 var EventFootprint_1
= __webpack_require__(36);
2975 var ComponentFootprint_1
= __webpack_require__(12);
2976 function eventDefsToEventInstances(eventDefs
, unzonedRange
) {
2977 var eventInstances
= [];
2979 for (i
= 0; i
< eventDefs
.length
; i
++) {
2980 eventInstances
.push
.apply(eventInstances
, // append
2981 eventDefs
[i
].buildInstances(unzonedRange
));
2983 return eventInstances
;
2985 exports
.eventDefsToEventInstances
= eventDefsToEventInstances
;
2986 function eventInstanceToEventRange(eventInstance
) {
2987 return new EventRange_1
.default(eventInstance
.dateProfile
.unzonedRange
, eventInstance
.def
, eventInstance
);
2989 exports
.eventInstanceToEventRange
= eventInstanceToEventRange
;
2990 function eventRangeToEventFootprint(eventRange
) {
2991 return new EventFootprint_1
.default(new ComponentFootprint_1
.default(eventRange
.unzonedRange
, eventRange
.eventDef
.isAllDay()), eventRange
.eventDef
, eventRange
.eventInstance
// might not exist
2994 exports
.eventRangeToEventFootprint
= eventRangeToEventFootprint
;
2995 function eventInstanceToUnzonedRange(eventInstance
) {
2996 return eventInstance
.dateProfile
.unzonedRange
;
2998 exports
.eventInstanceToUnzonedRange
= eventInstanceToUnzonedRange
;
2999 function eventFootprintToComponentFootprint(eventFootprint
) {
3000 return eventFootprint
.componentFootprint
;
3002 exports
.eventFootprintToComponentFootprint
= eventFootprintToComponentFootprint
;
3007 /***/ (function(module
, exports
) {
3009 Object
.defineProperty(exports
, "__esModule", { value
: true });
3010 var EventFootprint
= /** @class */ (function () {
3011 function EventFootprint(componentFootprint
, eventDef
, eventInstance
) {
3012 this.componentFootprint
= componentFootprint
;
3013 this.eventDef
= eventDef
;
3014 if (eventInstance
) {
3015 this.eventInstance
= eventInstance
;
3018 EventFootprint
.prototype.getEventLegacy = function () {
3019 return (this.eventInstance
|| this.eventDef
).toLegacy();
3021 return EventFootprint
;
3023 exports
.default = EventFootprint
;
3028 /***/ (function(module
, exports
, __webpack_require__
) {
3030 Object
.defineProperty(exports
, "__esModule", { value
: true });
3031 var util_1
= __webpack_require__(4);
3032 var EventDateProfile_1
= __webpack_require__(17);
3033 var EventDef_1
= __webpack_require__(34);
3034 var EventDefDateMutation_1
= __webpack_require__(50);
3035 var SingleEventDef_1
= __webpack_require__(13);
3036 var EventDefMutation
= /** @class */ (function () {
3037 function EventDefMutation() {
3039 EventDefMutation
.createFromRawProps = function (eventInstance
, rawProps
, largeUnit
) {
3040 var eventDef
= eventInstance
.def
;
3042 var standardProps
= {};
3044 var verbatimStandardProps
= {};
3045 var eventDefId
= null;
3046 var className
= null;
3051 for (propName
in rawProps
) {
3052 if (EventDateProfile_1
.default.isStandardProp(propName
)) {
3053 dateProps
[propName
] = rawProps
[propName
];
3055 else if (eventDef
.isStandardProp(propName
)) {
3056 standardProps
[propName
] = rawProps
[propName
];
3058 else if (eventDef
.miscProps
[propName
] !== rawProps
[propName
]) {
3059 miscProps
[propName
] = rawProps
[propName
];
3062 dateProfile
= EventDateProfile_1
.default.parse(dateProps
, eventDef
.source
);
3064 dateMutation
= EventDefDateMutation_1
.default.createFromDiff(eventInstance
.dateProfile
, dateProfile
, largeUnit
);
3066 if (standardProps
.id
!== eventDef
.id
) {
3067 eventDefId
= standardProps
.id
; // only apply if there's a change
3069 if (!util_1
.isArraysEqual(standardProps
.className
, eventDef
.className
)) {
3070 className
= standardProps
.className
; // only apply if there's a change
3072 EventDef_1
.default.copyVerbatimStandardProps(standardProps
, // src
3073 verbatimStandardProps
// dest
3075 defMutation
= new EventDefMutation();
3076 defMutation
.eventDefId
= eventDefId
;
3077 defMutation
.className
= className
;
3078 defMutation
.verbatimStandardProps
= verbatimStandardProps
;
3079 defMutation
.miscProps
= miscProps
;
3081 defMutation
.dateMutation
= dateMutation
;
3086 eventDef assumed to be a SingleEventDef.
3087 returns an undo function.
3089 EventDefMutation
.prototype.mutateSingle = function (eventDef
) {
3090 var origDateProfile
;
3091 if (this.dateMutation
) {
3092 origDateProfile
= eventDef
.dateProfile
;
3093 eventDef
.dateProfile
= this.dateMutation
.buildNewDateProfile(origDateProfile
, eventDef
.source
.calendar
);
3096 // TODO: more DRY with EventDef::applyManualStandardProps
3097 if (this.eventDefId
!= null) {
3098 eventDef
.id
= EventDef_1
.default.normalizeId((eventDef
.rawId
= this.eventDefId
));
3101 // TODO: more DRY with EventDef::applyManualStandardProps
3102 if (this.className
) {
3103 eventDef
.className
= this.className
;
3106 if (this.verbatimStandardProps
) {
3107 SingleEventDef_1
.default.copyVerbatimStandardProps(this.verbatimStandardProps
, // src
3112 if (this.miscProps
) {
3113 eventDef
.applyMiscProps(this.miscProps
);
3115 if (origDateProfile
) {
3116 return function () {
3117 eventDef
.dateProfile
= origDateProfile
;
3121 return function () { };
3124 EventDefMutation
.prototype.setDateMutation = function (dateMutation
) {
3125 if (dateMutation
&& !dateMutation
.isEmpty()) {
3126 this.dateMutation
= dateMutation
;
3129 this.dateMutation
= null;
3132 EventDefMutation
.prototype.isEmpty = function () {
3133 return !this.dateMutation
;
3135 return EventDefMutation
;
3137 exports
.default = EventDefMutation
;
3142 /***/ (function(module
, exports
) {
3144 Object
.defineProperty(exports
, "__esModule", { value
: true });
3147 registerClass: function (EventSourceClass
) {
3148 this.sourceClasses
.unshift(EventSourceClass
); // give highest priority
3150 parse: function (rawInput
, calendar
) {
3151 var sourceClasses
= this.sourceClasses
;
3154 for (i
= 0; i
< sourceClasses
.length
; i
++) {
3155 eventSource
= sourceClasses
[i
].parse(rawInput
, calendar
);
3166 /***/ (function(module
, exports
, __webpack_require__
) {
3168 Object
.defineProperty(exports
, "__esModule", { value
: true });
3169 var tslib_1
= __webpack_require__(2);
3170 var $ = __webpack_require__(3);
3171 var util_1
= __webpack_require__(4);
3172 var Class_1
= __webpack_require__(33);
3174 Embodies a div that has potential scrollbars
3176 var Scroller
= /** @class */ (function (_super
) {
3177 tslib_1
.__extends(Scroller
, _super
);
3178 function Scroller(options
) {
3179 var _this
= _super
.call(this) || this;
3180 options
= options
|| {};
3181 _this
.overflowX
= options
.overflowX
|| options
.overflow
|| 'auto';
3182 _this
.overflowY
= options
.overflowY
|| options
.overflow
|| 'auto';
3185 Scroller
.prototype.render = function () {
3186 this.el
= this.renderEl();
3187 this.applyOverflow();
3189 Scroller
.prototype.renderEl = function () {
3190 return (this.scrollEl
= $('<div class="fc-scroller"></div>'));
3192 // sets to natural height, unlocks overflow
3193 Scroller
.prototype.clear = function () {
3194 this.setHeight('auto');
3195 this.applyOverflow();
3197 Scroller
.prototype.destroy = function () {
3201 // -----------------------------------------------------------------------------------------------------------------
3202 Scroller
.prototype.applyOverflow = function () {
3204 'overflow-x': this.overflowX
,
3205 'overflow-y': this.overflowY
3208 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3209 // Useful for preserving scrollbar widths regardless of future resizes.
3210 // Can pass in scrollbarWidths for optimization.
3211 Scroller
.prototype.lockOverflow = function (scrollbarWidths
) {
3212 var overflowX
= this.overflowX
;
3213 var overflowY
= this.overflowY
;
3214 scrollbarWidths
= scrollbarWidths
|| this.getScrollbarWidths();
3215 if (overflowX
=== 'auto') {
3216 overflowX
= (scrollbarWidths
.top
|| scrollbarWidths
.bottom
|| // horizontal scrollbars?
3217 // OR scrolling pane with massless scrollbars?
3218 this.scrollEl
[0].scrollWidth
- 1 > this.scrollEl
[0].clientWidth
) ? 'scroll' : 'hidden';
3220 if (overflowY
=== 'auto') {
3221 overflowY
= (scrollbarWidths
.left
|| scrollbarWidths
.right
|| // vertical scrollbars?
3222 // OR scrolling pane with massless scrollbars?
3223 this.scrollEl
[0].scrollHeight
- 1 > this.scrollEl
[0].clientHeight
) ? 'scroll' : 'hidden';
3225 this.scrollEl
.css({ 'overflow-x': overflowX
, 'overflow-y': overflowY
});
3227 // Getters / Setters
3228 // -----------------------------------------------------------------------------------------------------------------
3229 Scroller
.prototype.setHeight = function (height
) {
3230 this.scrollEl
.height(height
);
3232 Scroller
.prototype.getScrollTop = function () {
3233 return this.scrollEl
.scrollTop();
3235 Scroller
.prototype.setScrollTop = function (top
) {
3236 this.scrollEl
.scrollTop(top
);
3238 Scroller
.prototype.getClientWidth = function () {
3239 return this.scrollEl
[0].clientWidth
;
3241 Scroller
.prototype.getClientHeight = function () {
3242 return this.scrollEl
[0].clientHeight
;
3244 Scroller
.prototype.getScrollbarWidths = function () {
3245 return util_1
.getScrollbarWidths(this.scrollEl
);
3248 }(Class_1
.default));
3249 exports
.default = Scroller
;
3254 /***/ (function(module
, exports
, __webpack_require__
) {
3256 Object
.defineProperty(exports
, "__esModule", { value
: true });
3257 var tslib_1
= __webpack_require__(2);
3258 var $ = __webpack_require__(3);
3259 var util_1
= __webpack_require__(4);
3260 var DateComponent_1
= __webpack_require__(219);
3261 var GlobalEmitter_1
= __webpack_require__(21);
3262 var InteractiveDateComponent
= /** @class */ (function (_super
) {
3263 tslib_1
.__extends(InteractiveDateComponent
, _super
);
3264 function InteractiveDateComponent(_view
, _options
) {
3265 var _this
= _super
.call(this, _view
, _options
) || this;
3266 // self-config, overridable by subclasses
3267 _this
.segSelector
= '.fc-event-container > *'; // what constitutes an event element?
3268 if (_this
.dateSelectingClass
) {
3269 _this
.dateClicking
= new _this
.dateClickingClass(_this
);
3271 if (_this
.dateSelectingClass
) {
3272 _this
.dateSelecting
= new _this
.dateSelectingClass(_this
);
3274 if (_this
.eventPointingClass
) {
3275 _this
.eventPointing
= new _this
.eventPointingClass(_this
);
3277 if (_this
.eventDraggingClass
&& _this
.eventPointing
) {
3278 _this
.eventDragging
= new _this
.eventDraggingClass(_this
, _this
.eventPointing
);
3280 if (_this
.eventResizingClass
&& _this
.eventPointing
) {
3281 _this
.eventResizing
= new _this
.eventResizingClass(_this
, _this
.eventPointing
);
3283 if (_this
.externalDroppingClass
) {
3284 _this
.externalDropping
= new _this
.externalDroppingClass(_this
);
3288 // Sets the container element that the view should render inside of, does global DOM-related initializations,
3289 // and renders all the non-date-related content inside.
3290 InteractiveDateComponent
.prototype.setElement = function (el
) {
3291 _super
.prototype.setElement
.call(this, el
);
3292 if (this.dateClicking
) {
3293 this.dateClicking
.bindToEl(el
);
3295 if (this.dateSelecting
) {
3296 this.dateSelecting
.bindToEl(el
);
3298 this.bindAllSegHandlersToEl(el
);
3300 InteractiveDateComponent
.prototype.removeElement = function () {
3301 this.endInteractions();
3302 _super
.prototype.removeElement
.call(this);
3304 InteractiveDateComponent
.prototype.executeEventUnrender = function () {
3305 this.endInteractions();
3306 _super
.prototype.executeEventUnrender
.call(this);
3308 InteractiveDateComponent
.prototype.bindGlobalHandlers = function () {
3309 _super
.prototype.bindGlobalHandlers
.call(this);
3310 if (this.externalDropping
) {
3311 this.externalDropping
.bindToDocument();
3314 InteractiveDateComponent
.prototype.unbindGlobalHandlers = function () {
3315 _super
.prototype.unbindGlobalHandlers
.call(this);
3316 if (this.externalDropping
) {
3317 this.externalDropping
.unbindFromDocument();
3320 InteractiveDateComponent
.prototype.bindDateHandlerToEl = function (el
, name
, handler
) {
3322 // attach a handler to the grid's root element.
3323 // jQuery will take care of unregistering them when removeElement gets called.
3324 this.el
.on(name
, function (ev
) {
3325 if (!$(ev
.target
).is(_this
.segSelector
+ ':not(.fc-helper),' + // directly on an event element
3326 _this
.segSelector
+ ':not(.fc-helper) *,' + // within an event element
3327 '.fc-more,' + // a "more.." link
3328 'a[data-goto]' // a clickable nav link
3330 return handler
.call(_this
, ev
);
3334 InteractiveDateComponent
.prototype.bindAllSegHandlersToEl = function (el
) {
3339 ].forEach(function (eventInteraction
) {
3340 if (eventInteraction
) {
3341 eventInteraction
.bindToEl(el
);
3345 InteractiveDateComponent
.prototype.bindSegHandlerToEl = function (el
, name
, handler
) {
3347 el
.on(name
, this.segSelector
, function (ev
) {
3348 var segEl
= $(ev
.currentTarget
);
3349 if (!segEl
.is('.fc-helper')) {
3350 var seg
= segEl
.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload
3351 if (seg
&& !_this
.shouldIgnoreEventPointing()) {
3352 return handler
.call(_this
, seg
, ev
); // context will be the Grid
3357 InteractiveDateComponent
.prototype.shouldIgnoreMouse = function () {
3359 // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter.
3360 return GlobalEmitter_1
.default.get().shouldIgnoreMouse();
3362 InteractiveDateComponent
.prototype.shouldIgnoreTouch = function () {
3363 var view
= this._getView();
3364 // On iOS (and Android?) when a new selection is initiated overtop another selection,
3365 // the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
3366 // HACK: simply don't allow this to happen.
3367 // ALSO: prevent selection when an *event* is already raised.
3368 return view
.isSelected
|| view
.selectedEvent
;
3370 InteractiveDateComponent
.prototype.shouldIgnoreEventPointing = function () {
3371 // only call the handlers if there is not a drag/resize in progress
3372 return (this.eventDragging
&& this.eventDragging
.isDragging
) ||
3373 (this.eventResizing
&& this.eventResizing
.isResizing
);
3375 InteractiveDateComponent
.prototype.canStartSelection = function (seg
, ev
) {
3376 return util_1
.getEvIsTouch(ev
) &&
3377 !this.canStartResize(seg
, ev
) &&
3378 (this.isEventDefDraggable(seg
.footprint
.eventDef
) ||
3379 this.isEventDefResizable(seg
.footprint
.eventDef
));
3381 InteractiveDateComponent
.prototype.canStartDrag = function (seg
, ev
) {
3382 return !this.canStartResize(seg
, ev
) &&
3383 this.isEventDefDraggable(seg
.footprint
.eventDef
);
3385 InteractiveDateComponent
.prototype.canStartResize = function (seg
, ev
) {
3386 var view
= this._getView();
3387 var eventDef
= seg
.footprint
.eventDef
;
3388 return (!util_1
.getEvIsTouch(ev
) || view
.isEventDefSelected(eventDef
)) &&
3389 this.isEventDefResizable(eventDef
) &&
3390 $(ev
.target
).is('.fc-resizer');
3392 // Kills all in-progress dragging.
3393 // Useful for when public API methods that result in re-rendering are invoked during a drag.
3394 // Also useful for when touch devices misbehave and don't fire their touchend.
3395 InteractiveDateComponent
.prototype.endInteractions = function () {
3402 ].forEach(function (interaction
) {
3408 // Event Drag-n-Drop
3409 // ---------------------------------------------------------------------------------------------------------------
3410 // Computes if the given event is allowed to be dragged by the user
3411 InteractiveDateComponent
.prototype.isEventDefDraggable = function (eventDef
) {
3412 return this.isEventDefStartEditable(eventDef
);
3414 InteractiveDateComponent
.prototype.isEventDefStartEditable = function (eventDef
) {
3415 var isEditable
= eventDef
.isStartExplicitlyEditable();
3416 if (isEditable
== null) {
3417 isEditable
= this.opt('eventStartEditable');
3418 if (isEditable
== null) {
3419 isEditable
= this.isEventDefGenerallyEditable(eventDef
);
3424 InteractiveDateComponent
.prototype.isEventDefGenerallyEditable = function (eventDef
) {
3425 var isEditable
= eventDef
.isExplicitlyEditable();
3426 if (isEditable
== null) {
3427 isEditable
= this.opt('editable');
3432 // ---------------------------------------------------------------------------------------------------------------
3433 // Computes if the given event is allowed to be resized from its starting edge
3434 InteractiveDateComponent
.prototype.isEventDefResizableFromStart = function (eventDef
) {
3435 return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef
);
3437 // Computes if the given event is allowed to be resized from its ending edge
3438 InteractiveDateComponent
.prototype.isEventDefResizableFromEnd = function (eventDef
) {
3439 return this.isEventDefResizable(eventDef
);
3441 // Computes if the given event is allowed to be resized by the user at all
3442 InteractiveDateComponent
.prototype.isEventDefResizable = function (eventDef
) {
3443 var isResizable
= eventDef
.isDurationExplicitlyEditable();
3444 if (isResizable
== null) {
3445 isResizable
= this.opt('eventDurationEditable');
3446 if (isResizable
== null) {
3447 isResizable
= this.isEventDefGenerallyEditable(eventDef
);
3452 // Event Mutation / Constraints
3453 // ---------------------------------------------------------------------------------------------------------------
3454 // Diffs the two dates, returning a duration, based on granularity of the grid
3455 // TODO: port isTimeScale into this system?
3456 InteractiveDateComponent
.prototype.diffDates = function (a
, b
) {
3457 if (this.largeUnit
) {
3458 return util_1
.diffByUnit(a
, b
, this.largeUnit
);
3461 return util_1
.diffDayTime(a
, b
);
3464 // is it allowed, in relation to the view's validRange?
3465 // NOTE: very similar to isExternalInstanceGroupAllowed
3466 InteractiveDateComponent
.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup
) {
3467 var view
= this._getView();
3468 var dateProfile
= this.dateProfile
;
3469 var eventFootprints
= this.eventRangesToEventFootprints(eventInstanceGroup
.getAllEventRanges());
3471 for (i
= 0; i
< eventFootprints
.length
; i
++) {
3472 // TODO: just use getAllEventRanges directly
3473 if (!dateProfile
.validUnzonedRange
.containsRange(eventFootprints
[i
].componentFootprint
.unzonedRange
)) {
3477 return view
.calendar
.constraints
.isEventInstanceGroupAllowed(eventInstanceGroup
);
3479 // NOTE: very similar to isEventInstanceGroupAllowed
3480 // when it's a completely anonymous external drag, no event.
3481 InteractiveDateComponent
.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup
) {
3482 var view
= this._getView();
3483 var dateProfile
= this.dateProfile
;
3484 var eventFootprints
= this.eventRangesToEventFootprints(eventInstanceGroup
.getAllEventRanges());
3486 for (i
= 0; i
< eventFootprints
.length
; i
++) {
3487 if (!dateProfile
.validUnzonedRange
.containsRange(eventFootprints
[i
].componentFootprint
.unzonedRange
)) {
3491 for (i
= 0; i
< eventFootprints
.length
; i
++) {
3492 // treat it as a selection
3493 // TODO: pass in eventInstanceGroup instead
3494 // because we don't want calendar's constraint system to depend on a component's
3495 // determination of footprints.
3496 if (!view
.calendar
.constraints
.isSelectionFootprintAllowed(eventFootprints
[i
].componentFootprint
)) {
3502 return InteractiveDateComponent
;
3503 }(DateComponent_1
.default));
3504 exports
.default = InteractiveDateComponent
;
3509 /***/ (function(module
, exports
, __webpack_require__
) {
3511 Object
.defineProperty(exports
, "__esModule", { value
: true });
3512 var tslib_1
= __webpack_require__(2);
3513 var $ = __webpack_require__(3);
3514 var moment
= __webpack_require__(0);
3515 var util_1
= __webpack_require__(4);
3516 var RenderQueue_1
= __webpack_require__(218);
3517 var DateProfileGenerator_1
= __webpack_require__(221);
3518 var InteractiveDateComponent_1
= __webpack_require__(40);
3519 var GlobalEmitter_1
= __webpack_require__(21);
3520 var UnzonedRange_1
= __webpack_require__(5);
3521 /* An abstract class from which other views inherit from
3522 ----------------------------------------------------------------------------------------------------------------------*/
3523 var View
= /** @class */ (function (_super
) {
3524 tslib_1
.__extends(View
, _super
);
3525 function View(calendar
, viewSpec
) {
3526 var _this
= _super
.call(this, null, viewSpec
.options
) || this;
3527 _this
.batchRenderDepth
= 0;
3528 _this
.isSelected
= false; // boolean whether a range of time is user-selected or not
3529 _this
.calendar
= calendar
;
3530 _this
.viewSpec
= viewSpec
;
3532 _this
.type
= viewSpec
.type
;
3533 // .name is deprecated
3534 _this
.name
= _this
.type
;
3535 _this
.initRenderQueue();
3536 _this
.initHiddenDays();
3537 _this
.dateProfileGenerator
= new _this
.dateProfileGeneratorClass(_this
);
3538 _this
.bindBaseRenderHandlers();
3539 _this
.eventOrderSpecs
= util_1
.parseFieldSpecs(_this
.opt('eventOrder'));
3541 if (_this
['initialize']) {
3542 _this
['initialize']();
3546 View
.prototype._getView = function () {
3549 // Retrieves an option with the given name
3550 View
.prototype.opt = function (name
) {
3551 return this.options
[name
];
3554 ------------------------------------------------------------------------------------------------------------------*/
3555 View
.prototype.initRenderQueue = function () {
3556 this.renderQueue
= new RenderQueue_1
.default({
3557 event
: this.opt('eventRenderWait')
3559 this.renderQueue
.on('start', this.onRenderQueueStart
.bind(this));
3560 this.renderQueue
.on('stop', this.onRenderQueueStop
.bind(this));
3561 this.on('before:change', this.startBatchRender
);
3562 this.on('change', this.stopBatchRender
);
3564 View
.prototype.onRenderQueueStart = function () {
3565 this.calendar
.freezeContentHeight();
3566 this.addScroll(this.queryScroll());
3568 View
.prototype.onRenderQueueStop = function () {
3569 if (this.calendar
.updateViewSize()) {
3572 this.calendar
.thawContentHeight();
3574 View
.prototype.startBatchRender = function () {
3575 if (!(this.batchRenderDepth
++)) {
3576 this.renderQueue
.pause();
3579 View
.prototype.stopBatchRender = function () {
3580 if (!(--this.batchRenderDepth
)) {
3581 this.renderQueue
.resume();
3584 View
.prototype.requestRender = function (func
, namespace, actionType
) {
3585 this.renderQueue
.queue(func
, namespace, actionType
);
3587 // given func will auto-bind to `this`
3588 View
.prototype.whenSizeUpdated = function (func
) {
3589 if (this.renderQueue
.isRunning
) {
3590 this.renderQueue
.one('stop', func
.bind(this));
3596 /* Title and Date Formatting
3597 ------------------------------------------------------------------------------------------------------------------*/
3598 // Computes what the title at the top of the calendar should be for this view
3599 View
.prototype.computeTitle = function (dateProfile
) {
3601 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
3602 if (/^(year|month)$/.test(dateProfile
.currentRangeUnit
)) {
3603 unzonedRange
= dateProfile
.currentUnzonedRange
;
3606 unzonedRange
= dateProfile
.activeUnzonedRange
;
3608 return this.formatRange({
3609 start
: this.calendar
.msToMoment(unzonedRange
.startMs
, dateProfile
.isRangeAllDay
),
3610 end
: this.calendar
.msToMoment(unzonedRange
.endMs
, dateProfile
.isRangeAllDay
)
3611 }, dateProfile
.isRangeAllDay
, this.opt('titleFormat') || this.computeTitleFormat(dateProfile
), this.opt('titleRangeSeparator'));
3613 // Generates the format string that should be used to generate the title for the current date range.
3614 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
3615 View
.prototype.computeTitleFormat = function (dateProfile
) {
3616 var currentRangeUnit
= dateProfile
.currentRangeUnit
;
3617 if (currentRangeUnit
=== 'year') {
3620 else if (currentRangeUnit
=== 'month') {
3621 return this.opt('monthYearFormat'); // like "September 2014"
3623 else if (dateProfile
.currentUnzonedRange
.as('days') > 1) {
3624 return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014"
3627 return 'LL'; // one day. longer, like "September 9 2014"
3630 // Date Setting/Unsetting
3631 // -----------------------------------------------------------------------------------------------------------------
3632 View
.prototype.setDate = function (date
) {
3633 var currentDateProfile
= this.get('dateProfile');
3634 var newDateProfile
= this.dateProfileGenerator
.build(date
, undefined, true); // forceToValid=true
3635 if (!currentDateProfile
||
3636 !currentDateProfile
.activeUnzonedRange
.equals(newDateProfile
.activeUnzonedRange
)) {
3637 this.set('dateProfile', newDateProfile
);
3640 View
.prototype.unsetDate = function () {
3641 this.unset('dateProfile');
3644 // -----------------------------------------------------------------------------------------------------------------
3645 View
.prototype.fetchInitialEvents = function (dateProfile
) {
3646 var calendar
= this.calendar
;
3647 var forceAllDay
= dateProfile
.isRangeAllDay
&& !this.usesMinMaxTime
;
3648 return calendar
.requestEvents(calendar
.msToMoment(dateProfile
.activeUnzonedRange
.startMs
, forceAllDay
), calendar
.msToMoment(dateProfile
.activeUnzonedRange
.endMs
, forceAllDay
));
3650 View
.prototype.bindEventChanges = function () {
3651 this.listenTo(this.calendar
, 'eventsReset', this.resetEvents
); // TODO: make this a real event
3653 View
.prototype.unbindEventChanges = function () {
3654 this.stopListeningTo(this.calendar
, 'eventsReset');
3656 View
.prototype.setEvents = function (eventsPayload
) {
3657 this.set('currentEvents', eventsPayload
);
3658 this.set('hasEvents', true);
3660 View
.prototype.unsetEvents = function () {
3661 this.unset('currentEvents');
3662 this.unset('hasEvents');
3664 View
.prototype.resetEvents = function (eventsPayload
) {
3665 this.startBatchRender();
3667 this.setEvents(eventsPayload
);
3668 this.stopBatchRender();
3670 // Date High-level Rendering
3671 // -----------------------------------------------------------------------------------------------------------------
3672 View
.prototype.requestDateRender = function (dateProfile
) {
3674 this.requestRender(function () {
3675 _this
.executeDateRender(dateProfile
);
3678 View
.prototype.requestDateUnrender = function () {
3680 this.requestRender(function () {
3681 _this
.executeDateUnrender();
3682 }, 'date', 'destroy');
3684 // if dateProfile not specified, uses current
3685 View
.prototype.executeDateRender = function (dateProfile
) {
3686 _super
.prototype.executeDateRender
.call(this, dateProfile
);
3687 if (this['render']) {
3688 this['render'](); // TODO: deprecate
3690 this.trigger('datesRendered');
3691 this.addScroll({ isDateInit
: true });
3692 this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon
3694 View
.prototype.executeDateUnrender = function () {
3696 this.stopNowIndicator();
3697 this.trigger('before:datesUnrendered');
3698 if (this['destroy']) {
3699 this['destroy'](); // TODO: deprecate
3701 _super
.prototype.executeDateUnrender
.call(this);
3704 // -----------------------------------------------------------------------------------------------------------------
3705 View
.prototype.bindBaseRenderHandlers = function () {
3707 this.on('datesRendered', function () {
3708 _this
.whenSizeUpdated(_this
.triggerViewRender
);
3710 this.on('before:datesUnrendered', function () {
3711 _this
.triggerViewDestroy();
3714 View
.prototype.triggerViewRender = function () {
3715 this.publiclyTrigger('viewRender', {
3717 args
: [this, this.el
]
3720 View
.prototype.triggerViewDestroy = function () {
3721 this.publiclyTrigger('viewDestroy', {
3723 args
: [this, this.el
]
3726 // Event High-level Rendering
3727 // -----------------------------------------------------------------------------------------------------------------
3728 View
.prototype.requestEventsRender = function (eventsPayload
) {
3730 this.requestRender(function () {
3731 _this
.executeEventRender(eventsPayload
);
3732 _this
.whenSizeUpdated(_this
.triggerAfterEventsRendered
);
3733 }, 'event', 'init');
3735 View
.prototype.requestEventsUnrender = function () {
3737 this.requestRender(function () {
3738 _this
.triggerBeforeEventsDestroyed();
3739 _this
.executeEventUnrender();
3740 }, 'event', 'destroy');
3742 // Business Hour High-level Rendering
3743 // -----------------------------------------------------------------------------------------------------------------
3744 View
.prototype.requestBusinessHoursRender = function (businessHourGenerator
) {
3746 this.requestRender(function () {
3747 _this
.renderBusinessHours(businessHourGenerator
);
3748 }, 'businessHours', 'init');
3750 View
.prototype.requestBusinessHoursUnrender = function () {
3752 this.requestRender(function () {
3753 _this
.unrenderBusinessHours();
3754 }, 'businessHours', 'destroy');
3756 // Misc view rendering utils
3757 // -----------------------------------------------------------------------------------------------------------------
3758 // Binds DOM handlers to elements that reside outside the view container, such as the document
3759 View
.prototype.bindGlobalHandlers = function () {
3760 _super
.prototype.bindGlobalHandlers
.call(this);
3761 this.listenTo(GlobalEmitter_1
.default.get(), {
3762 touchstart
: this.processUnselect
,
3763 mousedown
: this.handleDocumentMousedown
3766 // Unbinds DOM handlers from elements that reside outside the view container
3767 View
.prototype.unbindGlobalHandlers = function () {
3768 _super
.prototype.unbindGlobalHandlers
.call(this);
3769 this.stopListeningTo(GlobalEmitter_1
.default.get());
3772 ------------------------------------------------------------------------------------------------------------------*/
3773 // Immediately render the current time indicator and begins re-rendering it at an interval,
3774 // which is defined by this.getNowIndicatorUnit().
3775 // TODO: somehow do this for the current whole day's background too
3776 View
.prototype.startNowIndicator = function () {
3780 var delay
; // ms wait value
3781 if (this.opt('nowIndicator')) {
3782 unit
= this.getNowIndicatorUnit();
3784 update
= util_1
.proxy(this, 'updateNowIndicator'); // bind to `this`
3785 this.initialNowDate
= this.calendar
.getNow();
3786 this.initialNowQueriedMs
= new Date().valueOf();
3787 // wait until the beginning of the next interval
3788 delay
= this.initialNowDate
.clone().startOf(unit
).add(1, unit
).valueOf() - this.initialNowDate
.valueOf();
3789 this.nowIndicatorTimeoutID
= setTimeout(function () {
3790 _this
.nowIndicatorTimeoutID
= null;
3792 delay
= +moment
.duration(1, unit
);
3793 delay
= Math
.max(100, delay
); // prevent too frequent
3794 _this
.nowIndicatorIntervalID
= setInterval(update
, delay
); // update every interval
3797 // rendering will be initiated in updateSize
3800 // rerenders the now indicator, computing the new current time from the amount of time that has passed
3801 // since the initial getNow call.
3802 View
.prototype.updateNowIndicator = function () {
3803 if (this.isDatesRendered
&&
3804 this.initialNowDate
// activated before?
3806 this.unrenderNowIndicator(); // won't unrender if unnecessary
3807 this.renderNowIndicator(this.initialNowDate
.clone().add(new Date().valueOf() - this.initialNowQueriedMs
) // add ms
3809 this.isNowIndicatorRendered
= true;
3812 // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
3813 // Won't cause side effects if indicator isn't rendered.
3814 View
.prototype.stopNowIndicator = function () {
3815 if (this.isNowIndicatorRendered
) {
3816 if (this.nowIndicatorTimeoutID
) {
3817 clearTimeout(this.nowIndicatorTimeoutID
);
3818 this.nowIndicatorTimeoutID
= null;
3820 if (this.nowIndicatorIntervalID
) {
3821 clearInterval(this.nowIndicatorIntervalID
);
3822 this.nowIndicatorIntervalID
= null;
3824 this.unrenderNowIndicator();
3825 this.isNowIndicatorRendered
= false;
3829 ------------------------------------------------------------------------------------------------------------------*/
3830 View
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
3831 if (this['setHeight']) {
3832 this['setHeight'](totalHeight
, isAuto
);
3835 _super
.prototype.updateSize
.call(this, totalHeight
, isAuto
, isResize
);
3837 this.updateNowIndicator();
3840 ------------------------------------------------------------------------------------------------------------------*/
3841 View
.prototype.addScroll = function (scroll
) {
3842 var queuedScroll
= this.queuedScroll
|| (this.queuedScroll
= {});
3843 $.extend(queuedScroll
, scroll
);
3845 View
.prototype.popScroll = function () {
3846 this.applyQueuedScroll();
3847 this.queuedScroll
= null;
3849 View
.prototype.applyQueuedScroll = function () {
3850 if (this.queuedScroll
) {
3851 this.applyScroll(this.queuedScroll
);
3854 View
.prototype.queryScroll = function () {
3856 if (this.isDatesRendered
) {
3857 $.extend(scroll
, this.queryDateScroll());
3861 View
.prototype.applyScroll = function (scroll
) {
3862 if (scroll
.isDateInit
&& this.isDatesRendered
) {
3863 $.extend(scroll
, this.computeInitialDateScroll());
3865 if (this.isDatesRendered
) {
3866 this.applyDateScroll(scroll
);
3869 View
.prototype.computeInitialDateScroll = function () {
3870 return {}; // subclasses must implement
3872 View
.prototype.queryDateScroll = function () {
3873 return {}; // subclasses must implement
3875 View
.prototype.applyDateScroll = function (scroll
) {
3876 // subclasses must implement
3878 /* Event Drag-n-Drop
3879 ------------------------------------------------------------------------------------------------------------------*/
3880 View
.prototype.reportEventDrop = function (eventInstance
, eventMutation
, el
, ev
) {
3881 var eventManager
= this.calendar
.eventManager
;
3882 var undoFunc
= eventManager
.mutateEventsWithId(eventInstance
.def
.id
, eventMutation
);
3883 var dateMutation
= eventMutation
.dateMutation
;
3884 // update the EventInstance, for handlers
3886 eventInstance
.dateProfile
= dateMutation
.buildNewDateProfile(eventInstance
.dateProfile
, this.calendar
);
3888 this.triggerEventDrop(eventInstance
,
3889 // a drop doesn't necessarily mean a date mutation (ex: resource change)
3890 (dateMutation
&& dateMutation
.dateDelta
) || moment
.duration(), undoFunc
, el
, ev
);
3892 // Triggers event-drop handlers that have subscribed via the API
3893 View
.prototype.triggerEventDrop = function (eventInstance
, dateDelta
, undoFunc
, el
, ev
) {
3894 this.publiclyTrigger('eventDrop', {
3897 eventInstance
.toLegacy(),
3906 /* External Element Drag-n-Drop
3907 ------------------------------------------------------------------------------------------------------------------*/
3908 // Must be called when an external element, via jQuery UI, has been dropped onto the calendar.
3909 // `meta` is the parsed data that has been embedded into the dragging event.
3910 // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event.
3911 View
.prototype.reportExternalDrop = function (singleEventDef
, isEvent
, isSticky
, el
, ev
, ui
) {
3913 this.calendar
.eventManager
.addEventDef(singleEventDef
, isSticky
);
3915 this.triggerExternalDrop(singleEventDef
, isEvent
, el
, ev
, ui
);
3917 // Triggers external-drop handlers that have subscribed via the API
3918 View
.prototype.triggerExternalDrop = function (singleEventDef
, isEvent
, el
, ev
, ui
) {
3919 // trigger 'drop' regardless of whether element represents an event
3920 this.publiclyTrigger('drop', {
3923 singleEventDef
.dateProfile
.start
.clone(),
3930 // signal an external event landed
3931 this.publiclyTrigger('eventReceive', {
3934 singleEventDef
.buildInstance().toLegacy(),
3941 ------------------------------------------------------------------------------------------------------------------*/
3942 // Must be called when an event in the view has been resized to a new length
3943 View
.prototype.reportEventResize = function (eventInstance
, eventMutation
, el
, ev
) {
3944 var eventManager
= this.calendar
.eventManager
;
3945 var undoFunc
= eventManager
.mutateEventsWithId(eventInstance
.def
.id
, eventMutation
);
3946 // update the EventInstance, for handlers
3947 eventInstance
.dateProfile
= eventMutation
.dateMutation
.buildNewDateProfile(eventInstance
.dateProfile
, this.calendar
);
3948 this.triggerEventResize(eventInstance
, eventMutation
.dateMutation
.endDelta
, undoFunc
, el
, ev
);
3950 // Triggers event-resize handlers that have subscribed via the API
3951 View
.prototype.triggerEventResize = function (eventInstance
, durationDelta
, undoFunc
, el
, ev
) {
3952 this.publiclyTrigger('eventResize', {
3955 eventInstance
.toLegacy(),
3964 /* Selection (time range)
3965 ------------------------------------------------------------------------------------------------------------------*/
3966 // Selects a date span on the view. `start` and `end` are both Moments.
3967 // `ev` is the native mouse event that begin the interaction.
3968 View
.prototype.select = function (footprint
, ev
) {
3970 this.renderSelectionFootprint(footprint
);
3971 this.reportSelection(footprint
, ev
);
3973 View
.prototype.renderSelectionFootprint = function (footprint
) {
3974 if (this['renderSelection']) {
3975 this['renderSelection'](footprint
.toLegacy(this.calendar
));
3978 _super
.prototype.renderSelectionFootprint
.call(this, footprint
);
3981 // Called when a new selection is made. Updates internal state and triggers handlers.
3982 View
.prototype.reportSelection = function (footprint
, ev
) {
3983 this.isSelected
= true;
3984 this.triggerSelect(footprint
, ev
);
3986 // Triggers handlers to 'select'
3987 View
.prototype.triggerSelect = function (footprint
, ev
) {
3988 var dateProfile
= this.calendar
.footprintToDateProfile(footprint
); // abuse of "Event"DateProfile?
3989 this.publiclyTrigger('select', {
3999 // Undoes a selection. updates in the internal state and triggers handlers.
4000 // `ev` is the native mouse event that began the interaction.
4001 View
.prototype.unselect = function (ev
) {
4002 if (this.isSelected
) {
4003 this.isSelected
= false;
4004 if (this['destroySelection']) {
4005 this['destroySelection'](); // TODO: deprecate
4007 this.unrenderSelection();
4008 this.publiclyTrigger('unselect', {
4015 ------------------------------------------------------------------------------------------------------------------*/
4016 View
.prototype.selectEventInstance = function (eventInstance
) {
4017 if (!this.selectedEventInstance
||
4018 this.selectedEventInstance
!== eventInstance
) {
4019 this.unselectEventInstance();
4020 this.getEventSegs().forEach(function (seg
) {
4021 if (seg
.footprint
.eventInstance
=== eventInstance
&&
4022 seg
.el
// necessary?
4024 seg
.el
.addClass('fc-selected');
4027 this.selectedEventInstance
= eventInstance
;
4030 View
.prototype.unselectEventInstance = function () {
4031 if (this.selectedEventInstance
) {
4032 this.getEventSegs().forEach(function (seg
) {
4034 seg
.el
.removeClass('fc-selected');
4037 this.selectedEventInstance
= null;
4040 View
.prototype.isEventDefSelected = function (eventDef
) {
4041 // event references might change on refetchEvents(), while selectedEventInstance doesn't,
4043 return this.selectedEventInstance
&& this.selectedEventInstance
.def
.id
=== eventDef
.id
;
4045 /* Mouse / Touch Unselecting (time range & event unselection)
4046 ------------------------------------------------------------------------------------------------------------------*/
4047 // TODO: move consistently to down/start or up/end?
4048 // TODO: don't kill previous selection if touch scrolling
4049 View
.prototype.handleDocumentMousedown = function (ev
) {
4050 if (util_1
.isPrimaryMouseButton(ev
)) {
4051 this.processUnselect(ev
);
4054 View
.prototype.processUnselect = function (ev
) {
4055 this.processRangeUnselect(ev
);
4056 this.processEventUnselect(ev
);
4058 View
.prototype.processRangeUnselect = function (ev
) {
4060 // is there a time-range selection?
4061 if (this.isSelected
&& this.opt('unselectAuto')) {
4062 // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element
4063 ignore
= this.opt('unselectCancel');
4064 if (!ignore
|| !$(ev
.target
).closest(ignore
).length
) {
4069 View
.prototype.processEventUnselect = function (ev
) {
4070 if (this.selectedEventInstance
) {
4071 if (!$(ev
.target
).closest('.fc-selected').length
) {
4072 this.unselectEventInstance();
4077 ------------------------------------------------------------------------------------------------------------------*/
4078 View
.prototype.triggerBaseRendered = function () {
4079 this.publiclyTrigger('viewRender', {
4081 args
: [this, this.el
]
4084 View
.prototype.triggerBaseUnrendered = function () {
4085 this.publiclyTrigger('viewDestroy', {
4087 args
: [this, this.el
]
4090 // Triggers handlers to 'dayClick'
4091 // Span has start/end of the clicked area. Only the start is useful.
4092 View
.prototype.triggerDayClick = function (footprint
, dayEl
, ev
) {
4093 var dateProfile
= this.calendar
.footprintToDateProfile(footprint
); // abuse of "Event"DateProfile?
4094 this.publiclyTrigger('dayClick', {
4096 args
: [dateProfile
.start
, ev
, this]
4100 ------------------------------------------------------------------------------------------------------------------*/
4101 // For DateComponent::getDayClasses
4102 View
.prototype.isDateInOtherMonth = function (date
, dateProfile
) {
4105 // Arguments after name will be forwarded to a hypothetical function value
4106 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
4107 // Always clone your objects if you fear mutation.
4108 View
.prototype.getUnzonedRangeOption = function (name
) {
4109 var val
= this.opt(name
);
4110 if (typeof val
=== 'function') {
4111 val
= val
.apply(null, Array
.prototype.slice
.call(arguments
, 1));
4114 return this.calendar
.parseUnzonedRange(val
);
4118 ------------------------------------------------------------------------------------------------------------------*/
4119 // Initializes internal variables related to calculating hidden days-of-week
4120 View
.prototype.initHiddenDays = function () {
4121 var hiddenDays
= this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden
4122 var isHiddenDayHash
= []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
4125 if (this.opt('weekends') === false) {
4126 hiddenDays
.push(0, 6); // 0=sunday, 6=saturday
4128 for (i
= 0; i
< 7; i
++) {
4129 if (!(isHiddenDayHash
[i
] = $.inArray(i
, hiddenDays
) !== -1)) {
4134 throw new Error('invalid hiddenDays'); // all days were hidden? bad.
4136 this.isHiddenDayHash
= isHiddenDayHash
;
4138 // Remove days from the beginning and end of the range that are computed as hidden.
4139 // If the whole range is trimmed off, returns null
4140 View
.prototype.trimHiddenDays = function (inputUnzonedRange
) {
4141 var start
= inputUnzonedRange
.getStart();
4142 var end
= inputUnzonedRange
.getEnd();
4144 start
= this.skipHiddenDays(start
);
4147 end
= this.skipHiddenDays(end
, -1, true);
4149 if (start
=== null || end
=== null || start
< end
) {
4150 return new UnzonedRange_1
.default(start
, end
);
4154 // Is the current day hidden?
4155 // `day` is a day-of-week index (0-6), or a Moment
4156 View
.prototype.isHiddenDay = function (day
) {
4157 if (moment
.isMoment(day
)) {
4160 return this.isHiddenDayHash
[day
];
4162 // Incrementing the current day until it is no longer a hidden day, returning a copy.
4163 // DOES NOT CONSIDER validUnzonedRange!
4164 // If the initial value of `date` is not a hidden day, don't do anything.
4165 // Pass `isExclusive` as `true` if you are dealing with an end date.
4166 // `inc` defaults to `1` (increment one day forward each time)
4167 View
.prototype.skipHiddenDays = function (date
, inc
, isExclusive
) {
4168 if (inc
=== void 0) { inc
= 1; }
4169 if (isExclusive
=== void 0) { isExclusive
= false; }
4170 var out
= date
.clone();
4171 while (this.isHiddenDayHash
[(out
.day() + (isExclusive
? inc
: 0) + 7) % 7]) {
4172 out
.add(inc
, 'days');
4177 }(InteractiveDateComponent_1
.default));
4178 exports
.default = View
;
4179 View
.prototype.usesMinMaxTime
= false;
4180 View
.prototype.dateProfileGeneratorClass
= DateProfileGenerator_1
.default;
4181 View
.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps
) {
4182 this.requestDateRender(deps
.dateProfile
);
4184 this.requestDateUnrender();
4186 View
.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps
) {
4187 this.requestBusinessHoursRender(deps
.businessHourGenerator
);
4189 this.requestBusinessHoursUnrender();
4191 View
.watch('initialEvents', ['dateProfile'], function (deps
) {
4192 return this.fetchInitialEvents(deps
.dateProfile
);
4194 View
.watch('bindingEvents', ['initialEvents'], function (deps
) {
4195 this.setEvents(deps
.initialEvents
);
4196 this.bindEventChanges();
4198 this.unbindEventChanges();
4201 View
.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () {
4202 this.requestEventsRender(this.get('currentEvents'));
4204 this.requestEventsUnrender();
4206 View
.watch('title', ['dateProfile'], function (deps
) {
4207 return (this.title
= this.computeTitle(deps
.dateProfile
)); // assign to View for legacy reasons
4209 View
.watch('legacyDateProps', ['dateProfile'], function (deps
) {
4210 var calendar
= this.calendar
;
4211 var dateProfile
= deps
.dateProfile
;
4212 // DEPRECATED, but we need to keep it updated...
4213 this.start
= calendar
.msToMoment(dateProfile
.activeUnzonedRange
.startMs
, dateProfile
.isRangeAllDay
);
4214 this.end
= calendar
.msToMoment(dateProfile
.activeUnzonedRange
.endMs
, dateProfile
.isRangeAllDay
);
4215 this.intervalStart
= calendar
.msToMoment(dateProfile
.currentUnzonedRange
.startMs
, dateProfile
.isRangeAllDay
);
4216 this.intervalEnd
= calendar
.msToMoment(dateProfile
.currentUnzonedRange
.endMs
, dateProfile
.isRangeAllDay
);
4222 /***/ (function(module
, exports
, __webpack_require__
) {
4224 Object
.defineProperty(exports
, "__esModule", { value
: true });
4225 var $ = __webpack_require__(3);
4226 var util_1
= __webpack_require__(4);
4227 var EventRenderer
= /** @class */ (function () {
4228 function EventRenderer(component
, fillRenderer
) {
4229 this.view
= component
._getView();
4230 this.component
= component
;
4231 this.fillRenderer
= fillRenderer
;
4233 EventRenderer
.prototype.opt = function (name
) {
4234 return this.view
.opt(name
);
4236 // Updates values that rely on options and also relate to range
4237 EventRenderer
.prototype.rangeUpdated = function () {
4238 var displayEventTime
;
4239 var displayEventEnd
;
4240 this.eventTimeFormat
=
4241 this.opt('eventTimeFormat') ||
4242 this.opt('timeFormat') || // deprecated
4243 this.computeEventTimeFormat();
4244 displayEventTime
= this.opt('displayEventTime');
4245 if (displayEventTime
== null) {
4246 displayEventTime
= this.computeDisplayEventTime(); // might be based off of range
4248 displayEventEnd
= this.opt('displayEventEnd');
4249 if (displayEventEnd
== null) {
4250 displayEventEnd
= this.computeDisplayEventEnd(); // might be based off of range
4252 this.displayEventTime
= displayEventTime
;
4253 this.displayEventEnd
= displayEventEnd
;
4255 EventRenderer
.prototype.render = function (eventsPayload
) {
4256 var dateProfile
= this.component
._getDateProfile();
4262 for (eventDefId
in eventsPayload
) {
4263 instanceGroup
= eventsPayload
[eventDefId
];
4264 eventRanges
= instanceGroup
.sliceRenderRanges(dateProfile
.activeUnzonedRange
);
4265 if (instanceGroup
.getEventDef().hasBgRendering()) {
4266 bgRanges
.push
.apply(bgRanges
, eventRanges
);
4269 fgRanges
.push
.apply(fgRanges
, eventRanges
);
4272 this.renderBgRanges(bgRanges
);
4273 this.renderFgRanges(fgRanges
);
4275 EventRenderer
.prototype.unrender = function () {
4276 this.unrenderBgRanges();
4277 this.unrenderFgRanges();
4279 EventRenderer
.prototype.renderFgRanges = function (eventRanges
) {
4280 var eventFootprints
= this.component
.eventRangesToEventFootprints(eventRanges
);
4281 var segs
= this.component
.eventFootprintsToSegs(eventFootprints
);
4282 // render an `.el` on each seg
4283 // returns a subset of the segs. segs that were actually rendered
4284 segs
= this.renderFgSegEls(segs
);
4285 if (this.renderFgSegs(segs
) !== false) {
4289 EventRenderer
.prototype.unrenderFgRanges = function () {
4290 this.unrenderFgSegs(this.fgSegs
|| []);
4293 EventRenderer
.prototype.renderBgRanges = function (eventRanges
) {
4294 var eventFootprints
= this.component
.eventRangesToEventFootprints(eventRanges
);
4295 var segs
= this.component
.eventFootprintsToSegs(eventFootprints
);
4296 if (this.renderBgSegs(segs
) !== false) {
4300 EventRenderer
.prototype.unrenderBgRanges = function () {
4301 this.unrenderBgSegs();
4304 EventRenderer
.prototype.getSegs = function () {
4305 return (this.bgSegs
|| []).concat(this.fgSegs
|| []);
4307 // Renders foreground event segments onto the grid
4308 EventRenderer
.prototype.renderFgSegs = function (segs
) {
4309 // subclasses must implement
4310 // segs already has rendered els, and has been filtered.
4311 return false; // signal failure if not implemented
4313 // Unrenders all currently rendered foreground segments
4314 EventRenderer
.prototype.unrenderFgSegs = function (segs
) {
4315 // subclasses must implement
4317 EventRenderer
.prototype.renderBgSegs = function (segs
) {
4319 if (this.fillRenderer
) {
4320 this.fillRenderer
.renderSegs('bgEvent', segs
, {
4321 getClasses: function (seg
) {
4322 return _this
.getBgClasses(seg
.footprint
.eventDef
);
4324 getCss: function (seg
) {
4326 'background-color': _this
.getBgColor(seg
.footprint
.eventDef
)
4329 filterEl: function (seg
, el
) {
4330 return _this
.filterEventRenderEl(seg
.footprint
, el
);
4335 return false; // signal failure if no fillRenderer
4338 EventRenderer
.prototype.unrenderBgSegs = function () {
4339 if (this.fillRenderer
) {
4340 this.fillRenderer
.unrender('bgEvent');
4343 // Renders and assigns an `el` property for each foreground event segment.
4344 // Only returns segments that successfully rendered.
4345 EventRenderer
.prototype.renderFgSegEls = function (segs
, disableResizing
) {
4347 if (disableResizing
=== void 0) { disableResizing
= false; }
4348 var hasEventRenderHandlers
= this.view
.hasPublicHandlers('eventRender');
4350 var renderedSegs
= [];
4353 // build a large concatenation of event segment HTML
4354 for (i
= 0; i
< segs
.length
; i
++) {
4355 this.beforeFgSegHtml(segs
[i
]);
4356 html
+= this.fgSegHtml(segs
[i
], disableResizing
);
4358 // Grab individual elements from the combined HTML string. Use each as the default rendering.
4359 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
4360 $(html
).each(function (i
, node
) {
4363 if (hasEventRenderHandlers
) {
4364 el
= _this
.filterEventRenderEl(seg
.footprint
, el
);
4367 el
.data('fc-seg', seg
); // used by handlers
4369 renderedSegs
.push(seg
);
4373 return renderedSegs
;
4375 EventRenderer
.prototype.beforeFgSegHtml = function (seg
) {
4377 // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()
4378 EventRenderer
.prototype.fgSegHtml = function (seg
, disableResizing
) {
4379 // subclasses should implement
4381 // Generic utility for generating the HTML classNames for an event segment's element
4382 EventRenderer
.prototype.getSegClasses = function (seg
, isDraggable
, isResizable
) {
4385 seg
.isStart
? 'fc-start' : 'fc-not-start',
4386 seg
.isEnd
? 'fc-end' : 'fc-not-end'
4387 ].concat(this.getClasses(seg
.footprint
.eventDef
));
4389 classes
.push('fc-draggable');
4392 classes
.push('fc-resizable');
4394 // event is currently selected? attach a className.
4395 if (this.view
.isEventDefSelected(seg
.footprint
.eventDef
)) {
4396 classes
.push('fc-selected');
4400 // Given an event and the default element used for rendering, returns the element that should actually be used.
4401 // Basically runs events and elements through the eventRender hook.
4402 EventRenderer
.prototype.filterEventRenderEl = function (eventFootprint
, el
) {
4403 var legacy
= eventFootprint
.getEventLegacy();
4404 var custom
= this.view
.publiclyTrigger('eventRender', {
4406 args
: [legacy
, el
, this.view
]
4408 if (custom
=== false) {
4411 else if (custom
&& custom
!== true) {
4416 // Compute the text that should be displayed on an event's element.
4417 // `range` can be the Event object itself, or something range-like, with at least a `start`.
4418 // If event times are disabled, or the event has no time, will return a blank string.
4419 // If not specified, formatStr will default to the eventTimeFormat setting,
4420 // and displayEnd will default to the displayEventEnd setting.
4421 EventRenderer
.prototype.getTimeText = function (eventFootprint
, formatStr
, displayEnd
) {
4422 return this._getTimeText(eventFootprint
.eventInstance
.dateProfile
.start
, eventFootprint
.eventInstance
.dateProfile
.end
, eventFootprint
.componentFootprint
.isAllDay
, formatStr
, displayEnd
);
4424 EventRenderer
.prototype._getTimeText = function (start
, end
, isAllDay
, formatStr
, displayEnd
) {
4425 if (formatStr
== null) {
4426 formatStr
= this.eventTimeFormat
;
4428 if (displayEnd
== null) {
4429 displayEnd
= this.displayEventEnd
;
4431 if (this.displayEventTime
&& !isAllDay
) {
4432 if (displayEnd
&& end
) {
4433 return this.view
.formatRange({ start
: start
, end
: end
}, false, // allDay
4437 return start
.format(formatStr
);
4442 EventRenderer
.prototype.computeEventTimeFormat = function () {
4443 return this.opt('smallTimeFormat');
4445 EventRenderer
.prototype.computeDisplayEventTime = function () {
4448 EventRenderer
.prototype.computeDisplayEventEnd = function () {
4451 EventRenderer
.prototype.getBgClasses = function (eventDef
) {
4452 var classNames
= this.getClasses(eventDef
);
4453 classNames
.push('fc-bgevent');
4456 EventRenderer
.prototype.getClasses = function (eventDef
) {
4457 var objs
= this.getStylingObjs(eventDef
);
4459 var classNames
= [];
4460 for (i
= 0; i
< objs
.length
; i
++) {
4461 classNames
.push
.apply(// append
4462 classNames
, objs
[i
].eventClassName
|| objs
[i
].className
|| []);
4466 // Utility for generating event skin-related CSS properties
4467 EventRenderer
.prototype.getSkinCss = function (eventDef
) {
4469 'background-color': this.getBgColor(eventDef
),
4470 'border-color': this.getBorderColor(eventDef
),
4471 color
: this.getTextColor(eventDef
)
4474 // Queries for caller-specified color, then falls back to default
4475 EventRenderer
.prototype.getBgColor = function (eventDef
) {
4476 var objs
= this.getStylingObjs(eventDef
);
4479 for (i
= 0; i
< objs
.length
&& !val
; i
++) {
4480 val
= objs
[i
].eventBackgroundColor
|| objs
[i
].eventColor
||
4481 objs
[i
].backgroundColor
|| objs
[i
].color
;
4484 val
= this.opt('eventBackgroundColor') || this.opt('eventColor');
4488 // Queries for caller-specified color, then falls back to default
4489 EventRenderer
.prototype.getBorderColor = function (eventDef
) {
4490 var objs
= this.getStylingObjs(eventDef
);
4493 for (i
= 0; i
< objs
.length
&& !val
; i
++) {
4494 val
= objs
[i
].eventBorderColor
|| objs
[i
].eventColor
||
4495 objs
[i
].borderColor
|| objs
[i
].color
;
4498 val
= this.opt('eventBorderColor') || this.opt('eventColor');
4502 // Queries for caller-specified color, then falls back to default
4503 EventRenderer
.prototype.getTextColor = function (eventDef
) {
4504 var objs
= this.getStylingObjs(eventDef
);
4507 for (i
= 0; i
< objs
.length
&& !val
; i
++) {
4508 val
= objs
[i
].eventTextColor
||
4512 val
= this.opt('eventTextColor');
4516 EventRenderer
.prototype.getStylingObjs = function (eventDef
) {
4517 var objs
= this.getFallbackStylingObjs(eventDef
);
4518 objs
.unshift(eventDef
);
4521 EventRenderer
.prototype.getFallbackStylingObjs = function (eventDef
) {
4522 return [eventDef
.source
];
4524 EventRenderer
.prototype.sortEventSegs = function (segs
) {
4525 segs
.sort(util_1
.proxy(this, 'compareEventSegs'));
4527 // A cmp function for determining which segments should take visual priority
4528 EventRenderer
.prototype.compareEventSegs = function (seg1
, seg2
) {
4529 var f1
= seg1
.footprint
;
4530 var f2
= seg2
.footprint
;
4531 var cf1
= f1
.componentFootprint
;
4532 var cf2
= f2
.componentFootprint
;
4533 var r1
= cf1
.unzonedRange
;
4534 var r2
= cf2
.unzonedRange
;
4535 return r1
.startMs
- r2
.startMs
|| // earlier events go first
4536 (r2
.endMs
- r2
.startMs
) - (r1
.endMs
- r1
.startMs
) || // tie? longer events go first
4537 cf2
.isAllDay
- cf1
.isAllDay
|| // tie? put all-day events first (booleans cast to 0/1)
4538 util_1
.compareByFieldSpecs(f1
.eventDef
, f2
.eventDef
, this.view
.eventOrderSpecs
, f1
.eventDef
.miscProps
, f2
.eventDef
.miscProps
);
4540 return EventRenderer
;
4542 exports
.default = EventRenderer
;
4551 /***/ (function(module
, exports
, __webpack_require__
) {
4553 Object
.defineProperty(exports
, "__esModule", { value
: true });
4554 var moment_ext_1
= __webpack_require__(10);
4556 // -------------------------------------------------------------------------------------------------
4557 moment_ext_1
.newMomentProto
.format = function () {
4558 if (this._fullCalendar
&& arguments
[0]) {
4559 return formatDate(this, arguments
[0]); // our extended formatting
4561 if (this._ambigTime
) {
4562 return moment_ext_1
.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4564 if (this._ambigZone
) {
4565 return moment_ext_1
.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4567 if (this._fullCalendar
) {
4568 // moment.format() doesn't ensure english, but we want to.
4569 return moment_ext_1
.oldMomentFormat(englishMoment(this));
4571 return moment_ext_1
.oldMomentProto
.format
.apply(this, arguments
);
4573 moment_ext_1
.newMomentProto
.toISOString = function () {
4574 if (this._ambigTime
) {
4575 return moment_ext_1
.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4577 if (this._ambigZone
) {
4578 return moment_ext_1
.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4580 if (this._fullCalendar
) {
4581 // depending on browser, moment might not output english. ensure english.
4582 // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22
4583 return moment_ext_1
.oldMomentProto
.toISOString
.apply(englishMoment(this), arguments
);
4585 return moment_ext_1
.oldMomentProto
.toISOString
.apply(this, arguments
);
4587 function englishMoment(mom
) {
4588 if (mom
.locale() !== 'en') {
4589 return mom
.clone().locale('en');
4594 // ---------------------------------------------------------------------------------------------------------------------
4596 Inserted between chunks in the fake ("intermediate") formatting string.
4597 Important that it passes as whitespace (\s) because moment often identifies non-standalone months
4598 via a regexp with an \s.
4600 var PART_SEPARATOR
= '\u000b'; // vertical tab
4602 Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text,
4603 but rather, a "special" token that has custom rendering (see specialTokens map).
4605 var SPECIAL_TOKEN_MARKER
= '\u001f'; // information separator 1
4607 Inserted at the beginning and end of a span of text that must have non-zero numeric characters.
4608 Handling of these markers is done in a post-processing step at the very end of text rendering.
4610 var MAYBE_MARKER
= '\u001e'; // information separator 2
4611 var MAYBE_REGEXP
= new RegExp(MAYBE_MARKER
+ '([^' + MAYBE_MARKER
+ ']*)' + MAYBE_MARKER
, 'g'); // must be global
4613 Addition formatting tokens we want recognized
4615 var specialTokens
= {
4616 t: function (date
) {
4617 return moment_ext_1
.oldMomentFormat(date
, 'a').charAt(0);
4619 T: function (date
) {
4620 return moment_ext_1
.oldMomentFormat(date
, 'A').charAt(0);
4624 The first characters of formatting tokens for units that are 1 day or larger.
4625 `value` is for ranking relative size (lower means bigger).
4626 `unit` is a normalized unit, used for comparing moments.
4628 var largeTokenMap
= {
4629 Y
: { value
: 1, unit
: 'year' },
4630 M
: { value
: 2, unit
: 'month' },
4631 W
: { value
: 3, unit
: 'week' },
4632 w
: { value
: 3, unit
: 'week' },
4633 D
: { value
: 4, unit
: 'day' },
4634 d
: { value
: 4, unit
: 'day' } // day of week
4636 // Single Date Formatting
4637 // ---------------------------------------------------------------------------------------------------------------------
4639 Formats `date` with a Moment formatting string, but allow our non-zero areas and special token
4641 function formatDate(date
, formatStr
) {
4642 return renderFakeFormatString(getParsedFormatString(formatStr
).fakeFormatString
, date
);
4644 exports
.formatDate
= formatDate
;
4645 // Date Range Formatting
4646 // -------------------------------------------------------------------------------------------------
4647 // TODO: make it work with timezone offset
4649 Using a formatting string meant for a single date, generate a range string, like
4650 "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
4651 If the dates are the same as far as the format string is concerned, just return a single
4652 rendering of one date, without any separator.
4654 function formatRange(date1
, date2
, formatStr
, separator
, isRTL
) {
4656 date1
= moment_ext_1
.default.parseZone(date1
);
4657 date2
= moment_ext_1
.default.parseZone(date2
);
4658 localeData
= date1
.localeData();
4659 // Expand localized format strings, like "LL" -> "MMMM D YYYY".
4660 // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
4661 // or non-zero areas in Moment's localized format strings.
4662 formatStr
= localeData
.longDateFormat(formatStr
) || formatStr
;
4663 return renderParsedFormat(getParsedFormatString(formatStr
), date1
, date2
, separator
|| ' - ', isRTL
);
4665 exports
.formatRange
= formatRange
;
4667 Renders a range with an already-parsed format string.
4669 function renderParsedFormat(parsedFormat
, date1
, date2
, separator
, isRTL
) {
4670 var sameUnits
= parsedFormat
.sameUnits
;
4671 var unzonedDate1
= date1
.clone().stripZone(); // for same-unit comparisons
4672 var unzonedDate2
= date2
.clone().stripZone(); // "
4673 var renderedParts1
= renderFakeFormatStringParts(parsedFormat
.fakeFormatString
, date1
);
4674 var renderedParts2
= renderFakeFormatStringParts(parsedFormat
.fakeFormatString
, date2
);
4680 var middleStr1
= '';
4681 var middleStr2
= '';
4683 // Start at the leftmost side of the formatting string and continue until you hit a token
4684 // that is not the same between dates.
4685 for (leftI
= 0; leftI
< sameUnits
.length
&& (!sameUnits
[leftI
] || unzonedDate1
.isSame(unzonedDate2
, sameUnits
[leftI
])); leftI
++) {
4686 leftStr
+= renderedParts1
[leftI
];
4688 // Similarly, start at the rightmost side of the formatting string and move left
4689 for (rightI
= sameUnits
.length
- 1; rightI
> leftI
&& (!sameUnits
[rightI
] || unzonedDate1
.isSame(unzonedDate2
, sameUnits
[rightI
])); rightI
--) {
4690 // If current chunk is on the boundary of unique date-content, and is a special-case
4691 // date-formatting postfix character, then don't consume it. Consider it unique date-content.
4692 // TODO: make configurable
4693 if (rightI
- 1 === leftI
&& renderedParts1
[rightI
] === '.') {
4696 rightStr
= renderedParts1
[rightI
] + rightStr
;
4698 // The area in the middle is different for both of the dates.
4699 // Collect them distinctly so we can jam them together later.
4700 for (middleI
= leftI
; middleI
<= rightI
; middleI
++) {
4701 middleStr1
+= renderedParts1
[middleI
];
4702 middleStr2
+= renderedParts2
[middleI
];
4704 if (middleStr1
|| middleStr2
) {
4706 middleStr
= middleStr2
+ separator
+ middleStr1
;
4709 middleStr
= middleStr1
+ separator
+ middleStr2
;
4712 return processMaybeMarkers(leftStr
+ middleStr
+ rightStr
);
4714 // Format String Parsing
4715 // ---------------------------------------------------------------------------------------------------------------------
4716 var parsedFormatStrCache
= {};
4718 Returns a parsed format string, leveraging a cache.
4720 function getParsedFormatString(formatStr
) {
4721 return parsedFormatStrCache
[formatStr
] ||
4722 (parsedFormatStrCache
[formatStr
] = parseFormatString(formatStr
));
4725 Parses a format string into the following:
4726 - fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed.
4727 - sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"),
4728 that indicates how similar a range's start & end must be in order to share the same formatted text.
4729 If not a token, then the value is null.
4730 Always a flat array (not nested liked "chunks").
4732 function parseFormatString(formatStr
) {
4733 var chunks
= chunkFormatString(formatStr
);
4735 fakeFormatString
: buildFakeFormatString(chunks
),
4736 sameUnits
: buildSameUnits(chunks
)
4740 Break the formatting string into an array of chunks.
4741 A 'maybe' chunk will have nested chunks.
4743 function chunkFormatString(formatStr
) {
4746 // TODO: more descrimination
4747 // \4 is a backreference to the first character of a multi-character set.
4748 var chunker
= /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;
4749 while ((match
= chunker
.exec(formatStr
))) {
4751 chunks
.push
.apply(chunks
, // append
4752 splitStringLiteral(match
[1]));
4754 else if (match
[2]) {
4755 chunks
.push({ maybe
: chunkFormatString(match
[2]) });
4757 else if (match
[3]) {
4758 chunks
.push({ token
: match
[3] });
4760 else if (match
[5]) {
4761 chunks
.push
.apply(chunks
, // append
4762 splitStringLiteral(match
[5]));
4768 Potentially splits a literal-text string into multiple parts. For special cases.
4770 function splitStringLiteral(s
) {
4772 return ['.', ' ']; // for locales with periods bound to the end of each year/month/date
4779 Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control
4780 characters that will eventually be given to moment for formatting, and then post-processed.
4782 function buildFakeFormatString(chunks
) {
4786 for (i
= 0; i
< chunks
.length
; i
++) {
4788 if (typeof chunk
=== 'string') {
4789 parts
.push('[' + chunk
+ ']');
4791 else if (chunk
.token
) {
4792 if (chunk
.token
in specialTokens
) {
4793 parts
.push(SPECIAL_TOKEN_MARKER
+ // useful during post-processing
4794 '[' + chunk
.token
+ ']' // preserve as literal text
4798 parts
.push(chunk
.token
); // unprotected text implies a format string
4801 else if (chunk
.maybe
) {
4802 parts
.push(MAYBE_MARKER
+ // useful during post-processing
4803 buildFakeFormatString(chunk
.maybe
) +
4807 return parts
.join(PART_SEPARATOR
);
4810 Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate
4811 in which regard two dates must be similar in order to share range formatting text.
4812 The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat.
4814 function buildSameUnits(chunks
) {
4819 for (i
= 0; i
< chunks
.length
; i
++) {
4822 tokenInfo
= largeTokenMap
[chunk
.token
.charAt(0)];
4823 units
.push(tokenInfo
? tokenInfo
.unit
: 'second'); // default to a very strict same-second
4825 else if (chunk
.maybe
) {
4826 units
.push
.apply(units
, // append
4827 buildSameUnits(chunk
.maybe
));
4835 // Rendering to text
4836 // ---------------------------------------------------------------------------------------------------------------------
4838 Formats a date with a fake format string, post-processes the control characters, then returns.
4840 function renderFakeFormatString(fakeFormatString
, date
) {
4841 return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString
, date
).join(''));
4844 Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers.
4846 function renderFakeFormatStringParts(fakeFormatString
, date
) {
4848 var fakeRender
= moment_ext_1
.oldMomentFormat(date
, fakeFormatString
);
4849 var fakeParts
= fakeRender
.split(PART_SEPARATOR
);
4852 for (i
= 0; i
< fakeParts
.length
; i
++) {
4853 fakePart
= fakeParts
[i
];
4854 if (fakePart
.charAt(0) === SPECIAL_TOKEN_MARKER
) {
4856 // the literal string IS the token's name.
4857 // call special token's registered function.
4858 specialTokens
[fakePart
.substring(1)](date
));
4861 parts
.push(fakePart
);
4867 Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string.
4869 function processMaybeMarkers(s
) {
4870 return s
.replace(MAYBE_REGEXP
, function (m0
, m1
) {
4871 if (m1
.match(/[1-9]/)) {
4880 // -------------------------------------------------------------------------------------------------
4882 Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string.
4884 function queryMostGranularFormatUnit(formatStr
) {
4885 var chunks
= chunkFormatString(formatStr
);
4890 for (i
= 0; i
< chunks
.length
; i
++) {
4893 candidate
= largeTokenMap
[chunk
.token
.charAt(0)];
4895 if (!best
|| candidate
.value
> best
.value
) {
4906 exports
.queryMostGranularFormatUnit
= queryMostGranularFormatUnit
;
4911 /***/ (function(module
, exports
, __webpack_require__
) {
4913 Object
.defineProperty(exports
, "__esModule", { value
: true });
4914 var tslib_1
= __webpack_require__(2);
4915 var Class_1
= __webpack_require__(33);
4916 var EmitterMixin_1
= __webpack_require__(11);
4917 var ListenerMixin_1
= __webpack_require__(7);
4918 var Model
= /** @class */ (function (_super
) {
4919 tslib_1
.__extends(Model
, _super
);
4921 var _this
= _super
.call(this) || this;
4922 _this
._watchers
= {};
4924 _this
.applyGlobalWatchers();
4925 _this
.constructed();
4928 Model
.watch = function (name
) {
4930 for (var _i
= 1; _i
< arguments
.length
; _i
++) {
4931 args
[_i
- 1] = arguments
[_i
];
4933 // subclasses should make a masked-copy of the superclass's map
4935 if (!this.prototype.hasOwnProperty('_globalWatchArgs')) {
4936 this.prototype._globalWatchArgs
= Object
.create(this.prototype._globalWatchArgs
);
4938 this.prototype._globalWatchArgs
[name
] = args
;
4940 Model
.prototype.constructed = function () {
4941 // useful for monkeypatching. TODO: BaseClass?
4943 Model
.prototype.applyGlobalWatchers = function () {
4944 var map
= this._globalWatchArgs
;
4947 this.watch
.apply(this, [name
].concat(map
[name
]));
4950 Model
.prototype.has = function (name
) {
4951 return name
in this._props
;
4953 Model
.prototype.get = function (name
) {
4954 if (name
=== undefined) {
4957 return this._props
[name
];
4959 Model
.prototype.set = function (name
, val
) {
4961 if (typeof name
=== 'string') {
4963 newProps
[name
] = val
=== undefined ? null : val
;
4968 this.setProps(newProps
);
4970 Model
.prototype.reset = function (newProps
) {
4971 var oldProps
= this._props
;
4972 var changeset
= {}; // will have undefined's to signal unsets
4974 for (name
in oldProps
) {
4975 changeset
[name
] = undefined;
4977 for (name
in newProps
) {
4978 changeset
[name
] = newProps
[name
];
4980 this.setProps(changeset
);
4982 Model
.prototype.unset = function (name
) {
4986 if (typeof name
=== 'string') {
4992 for (i
= 0; i
< names
.length
; i
++) {
4993 newProps
[names
[i
]] = undefined;
4995 this.setProps(newProps
);
4997 Model
.prototype.setProps = function (newProps
) {
4998 var changedProps
= {};
5002 for (name
in newProps
) {
5003 val
= newProps
[name
];
5004 // a change in value?
5005 // if an object, don't check equality, because might have been mutated internally.
5006 // TODO: eventually enforce immutability.
5007 if (typeof val
=== 'object' ||
5008 val
!== this._props
[name
]) {
5009 changedProps
[name
] = val
;
5014 this.trigger('before:batchChange', changedProps
);
5015 for (name
in changedProps
) {
5016 val
= changedProps
[name
];
5017 this.trigger('before:change', name
, val
);
5018 this.trigger('before:change:' + name
, val
);
5020 for (name
in changedProps
) {
5021 val
= changedProps
[name
];
5022 if (val
=== undefined) {
5023 delete this._props
[name
];
5026 this._props
[name
] = val
;
5028 this.trigger('change:' + name
, val
);
5029 this.trigger('change', name
, val
);
5031 this.trigger('batchChange', changedProps
);
5034 Model
.prototype.watch = function (name
, depList
, startFunc
, stopFunc
) {
5037 this._watchers
[name
] = this._watchDeps(depList
, function (deps
) {
5038 var res
= startFunc
.call(_this
, deps
);
5039 if (res
&& res
.then
) {
5040 _this
.unset(name
); // put in an unset state while resolving
5041 res
.then(function (val
) {
5042 _this
.set(name
, val
);
5046 _this
.set(name
, res
);
5048 }, function (deps
) {
5051 stopFunc
.call(_this
, deps
);
5055 Model
.prototype.unwatch = function (name
) {
5056 var watcher
= this._watchers
[name
];
5058 delete this._watchers
[name
];
5062 Model
.prototype._watchDeps = function (depList
, startFunc
, stopFunc
) {
5064 var queuedChangeCnt
= 0;
5065 var depCnt
= depList
.length
;
5067 var values
= {}; // what's passed as the `deps` arguments
5068 var bindTuples
= []; // array of [ eventName, handlerFunc ] arrays
5069 var isCallingStop
= false;
5070 var onBeforeDepChange = function (depName
, val
, isOptional
) {
5072 if (queuedChangeCnt
=== 1) {
5073 if (satisfyCnt
=== depCnt
) {
5074 isCallingStop
= true;
5076 isCallingStop
= false;
5080 var onDepChange = function (depName
, val
, isOptional
) {
5081 if (val
=== undefined) {
5082 // required dependency that was previously set?
5083 if (!isOptional
&& values
[depName
] !== undefined) {
5086 delete values
[depName
];
5089 // required dependency that was previously unset?
5090 if (!isOptional
&& values
[depName
] === undefined) {
5093 values
[depName
] = val
;
5096 if (!queuedChangeCnt
) {
5097 // now finally satisfied or satisfied all along?
5098 if (satisfyCnt
=== depCnt
) {
5099 // if the stopFunc initiated another value change, ignore it.
5100 // it will be processed by another change event anyway.
5101 if (!isCallingStop
) {
5107 // intercept for .on() that remembers handlers
5108 var bind = function (eventName
, handler
) {
5109 _this
.on(eventName
, handler
);
5110 bindTuples
.push([eventName
, handler
]);
5112 // listen to dependency changes
5113 depList
.forEach(function (depName
) {
5114 var isOptional
= false;
5115 if (depName
.charAt(0) === '?') {
5116 depName
= depName
.substring(1);
5119 bind('before:change:' + depName
, function (val
) {
5120 onBeforeDepChange(depName
, val
, isOptional
);
5122 bind('change:' + depName
, function (val
) {
5123 onDepChange(depName
, val
, isOptional
);
5126 // process current dependency values
5127 depList
.forEach(function (depName
) {
5128 var isOptional
= false;
5129 if (depName
.charAt(0) === '?') {
5130 depName
= depName
.substring(1);
5133 if (_this
.has(depName
)) {
5134 values
[depName
] = _this
.get(depName
);
5137 else if (isOptional
) {
5141 // initially satisfied
5142 if (satisfyCnt
=== depCnt
) {
5146 teardown: function () {
5147 // remove all handlers
5148 for (var i
= 0; i
< bindTuples
.length
; i
++) {
5149 _this
.off(bindTuples
[i
][0], bindTuples
[i
][1]);
5152 // was satisfied, so call stopFunc
5153 if (satisfyCnt
=== depCnt
) {
5157 flash: function () {
5158 if (satisfyCnt
=== depCnt
) {
5165 Model
.prototype.flash = function (name
) {
5166 var watcher
= this._watchers
[name
];
5172 }(Class_1
.default));
5173 exports
.default = Model
;
5174 Model
.prototype._globalWatchArgs
= {}; // mutation protection in Model.watch
5175 EmitterMixin_1
.default.mixInto(Model
);
5176 ListenerMixin_1
.default.mixInto(Model
);
5181 /***/ (function(module
, exports
, __webpack_require__
) {
5183 Object
.defineProperty(exports
, "__esModule", { value
: true });
5184 var moment
= __webpack_require__(0);
5185 var util_1
= __webpack_require__(4);
5186 var SingleEventDef_1
= __webpack_require__(13);
5187 var RecurringEventDef_1
= __webpack_require__(210);
5189 parse: function (eventInput
, source
) {
5190 if (util_1
.isTimeString(eventInput
.start
) || moment
.isDuration(eventInput
.start
) ||
5191 util_1
.isTimeString(eventInput
.end
) || moment
.isDuration(eventInput
.end
)) {
5192 return RecurringEventDef_1
.default.parse(eventInput
, source
);
5195 return SingleEventDef_1
.default.parse(eventInput
, source
);
5203 /***/ (function(module
, exports
, __webpack_require__
) {
5205 Object
.defineProperty(exports
, "__esModule", { value
: true });
5206 var util_1
= __webpack_require__(4);
5207 var EventDateProfile_1
= __webpack_require__(17);
5208 var EventDefDateMutation
= /** @class */ (function () {
5209 function EventDefDateMutation() {
5210 this.clearEnd
= false;
5211 this.forceTimed
= false;
5212 this.forceAllDay
= false;
5214 EventDefDateMutation
.createFromDiff = function (dateProfile0
, dateProfile1
, largeUnit
) {
5215 var clearEnd
= dateProfile0
.end
&& !dateProfile1
.end
;
5216 var forceTimed
= dateProfile0
.isAllDay() && !dateProfile1
.isAllDay();
5217 var forceAllDay
= !dateProfile0
.isAllDay() && dateProfile1
.isAllDay();
5222 // subtracts the dates in the appropriate way, returning a duration
5223 function subtractDates(date1
, date0
) {
5225 return util_1
.diffByUnit(date1
, date0
, largeUnit
); // poorly named
5227 else if (dateProfile1
.isAllDay()) {
5228 return util_1
.diffDay(date1
, date0
); // poorly named
5231 return util_1
.diffDayTime(date1
, date0
); // poorly named
5234 dateDelta
= subtractDates(dateProfile1
.start
, dateProfile0
.start
);
5235 if (dateProfile1
.end
) {
5236 // use unzonedRanges because dateProfile0.end might be null
5237 endDiff
= subtractDates(dateProfile1
.unzonedRange
.getEnd(), dateProfile0
.unzonedRange
.getEnd());
5238 endDelta
= endDiff
.subtract(dateDelta
);
5240 mutation
= new EventDefDateMutation();
5241 mutation
.clearEnd
= clearEnd
;
5242 mutation
.forceTimed
= forceTimed
;
5243 mutation
.forceAllDay
= forceAllDay
;
5244 mutation
.setDateDelta(dateDelta
);
5245 mutation
.setEndDelta(endDelta
);
5249 returns an undo function.
5251 EventDefDateMutation
.prototype.buildNewDateProfile = function (eventDateProfile
, calendar
) {
5252 var start
= eventDateProfile
.start
.clone();
5254 var shouldRezone
= false;
5255 if (eventDateProfile
.end
&& !this.clearEnd
) {
5256 end
= eventDateProfile
.end
.clone();
5258 else if (this.endDelta
&& !end
) {
5259 end
= calendar
.getDefaultEventEnd(eventDateProfile
.isAllDay(), start
);
5261 if (this.forceTimed
) {
5262 shouldRezone
= true;
5263 if (!start
.hasTime()) {
5266 if (end
&& !end
.hasTime()) {
5270 else if (this.forceAllDay
) {
5271 if (start
.hasTime()) {
5274 if (end
&& end
.hasTime()) {
5278 if (this.dateDelta
) {
5279 shouldRezone
= true;
5280 start
.add(this.dateDelta
);
5282 end
.add(this.dateDelta
);
5285 // do this before adding startDelta to start, so we can work off of start
5286 if (this.endDelta
) {
5287 shouldRezone
= true;
5288 end
.add(this.endDelta
);
5290 if (this.startDelta
) {
5291 shouldRezone
= true;
5292 start
.add(this.startDelta
);
5295 start
= calendar
.applyTimezone(start
);
5297 end
= calendar
.applyTimezone(end
);
5300 // TODO: okay to access calendar option?
5301 if (!end
&& calendar
.opt('forceEventDuration')) {
5302 end
= calendar
.getDefaultEventEnd(eventDateProfile
.isAllDay(), start
);
5304 return new EventDateProfile_1
.default(start
, end
, calendar
);
5306 EventDefDateMutation
.prototype.setDateDelta = function (dateDelta
) {
5307 if (dateDelta
&& dateDelta
.valueOf()) {
5308 this.dateDelta
= dateDelta
;
5311 this.dateDelta
= null;
5314 EventDefDateMutation
.prototype.setStartDelta = function (startDelta
) {
5315 if (startDelta
&& startDelta
.valueOf()) {
5316 this.startDelta
= startDelta
;
5319 this.startDelta
= null;
5322 EventDefDateMutation
.prototype.setEndDelta = function (endDelta
) {
5323 if (endDelta
&& endDelta
.valueOf()) {
5324 this.endDelta
= endDelta
;
5327 this.endDelta
= null;
5330 EventDefDateMutation
.prototype.isEmpty = function () {
5331 return !this.clearEnd
&& !this.forceTimed
&& !this.forceAllDay
&&
5332 !this.dateDelta
&& !this.startDelta
&& !this.endDelta
;
5334 return EventDefDateMutation
;
5336 exports
.default = EventDefDateMutation
;
5341 /***/ (function(module
, exports
, __webpack_require__
) {
5343 Object
.defineProperty(exports
, "__esModule", { value
: true });
5344 var StandardTheme_1
= __webpack_require__(213);
5345 var JqueryUiTheme_1
= __webpack_require__(214);
5346 var themeClassHash
= {};
5347 function defineThemeSystem(themeName
, themeClass
) {
5348 themeClassHash
[themeName
] = themeClass
;
5350 exports
.defineThemeSystem
= defineThemeSystem
;
5351 function getThemeSystemClass(themeSetting
) {
5352 if (!themeSetting
) {
5353 return StandardTheme_1
.default;
5355 else if (themeSetting
=== true) {
5356 return JqueryUiTheme_1
.default;
5359 return themeClassHash
[themeSetting
];
5362 exports
.getThemeSystemClass
= getThemeSystemClass
;
5367 /***/ (function(module
, exports
, __webpack_require__
) {
5369 Object
.defineProperty(exports
, "__esModule", { value
: true });
5370 var tslib_1
= __webpack_require__(2);
5371 var $ = __webpack_require__(3);
5372 var util_1
= __webpack_require__(4);
5373 var Promise_1
= __webpack_require__(20);
5374 var EventSource_1
= __webpack_require__(6);
5375 var SingleEventDef_1
= __webpack_require__(13);
5376 var ArrayEventSource
= /** @class */ (function (_super
) {
5377 tslib_1
.__extends(ArrayEventSource
, _super
);
5378 function ArrayEventSource(calendar
) {
5379 var _this
= _super
.call(this, calendar
) || this;
5380 _this
.eventDefs
= []; // for if setRawEventDefs is never called
5383 ArrayEventSource
.parse = function (rawInput
, calendar
) {
5385 // normalize raw input
5386 if ($.isArray(rawInput
.events
)) {
5387 rawProps
= rawInput
;
5389 else if ($.isArray(rawInput
)) {
5390 rawProps
= { events
: rawInput
};
5393 return EventSource_1
.default.parse
.call(this, rawProps
, calendar
);
5397 ArrayEventSource
.prototype.setRawEventDefs = function (rawEventDefs
) {
5398 this.rawEventDefs
= rawEventDefs
;
5399 this.eventDefs
= this.parseEventDefs(rawEventDefs
);
5401 ArrayEventSource
.prototype.fetch = function (start
, end
, timezone
) {
5402 var eventDefs
= this.eventDefs
;
5404 if (this.currentTimezone
!= null &&
5405 this.currentTimezone
!== timezone
) {
5406 for (i
= 0; i
< eventDefs
.length
; i
++) {
5407 if (eventDefs
[i
] instanceof SingleEventDef_1
.default) {
5408 eventDefs
[i
].rezone();
5412 this.currentTimezone
= timezone
;
5413 return Promise_1
.default.resolve(eventDefs
);
5415 ArrayEventSource
.prototype.addEventDef = function (eventDef
) {
5416 this.eventDefs
.push(eventDef
);
5419 eventDefId already normalized to a string
5421 ArrayEventSource
.prototype.removeEventDefsById = function (eventDefId
) {
5422 return util_1
.removeMatching(this.eventDefs
, function (eventDef
) {
5423 return eventDef
.id
=== eventDefId
;
5426 ArrayEventSource
.prototype.removeAllEventDefs = function () {
5427 this.eventDefs
= [];
5429 ArrayEventSource
.prototype.getPrimitive = function () {
5430 return this.rawEventDefs
;
5432 ArrayEventSource
.prototype.applyManualStandardProps = function (rawProps
) {
5433 var superSuccess
= _super
.prototype.applyManualStandardProps
.call(this, rawProps
);
5434 this.setRawEventDefs(rawProps
.events
);
5435 return superSuccess
;
5437 return ArrayEventSource
;
5438 }(EventSource_1
.default));
5439 exports
.default = ArrayEventSource
;
5440 ArrayEventSource
.defineStandardProps({
5441 events
: false // don't automatically transfer
5447 /***/ (function(module
, exports
, __webpack_require__
) {
5449 Object
.defineProperty(exports
, "__esModule", { value
: true });
5450 var $ = __webpack_require__(3);
5451 var util_1
= __webpack_require__(4);
5453 A cache for the left/right/top/bottom/width/height values for one or more elements.
5454 Works with both offset (from topleft document) and position (from offsetParent).
5461 var CoordCache
= /** @class */ (function () {
5462 function CoordCache(options
) {
5463 this.isHorizontal
= false; // whether to query for left/right/width
5464 this.isVertical
= false; // whether to query for top/bottom/height
5465 this.els
= $(options
.els
);
5466 this.isHorizontal
= options
.isHorizontal
;
5467 this.isVertical
= options
.isVertical
;
5468 this.forcedOffsetParentEl
= options
.offsetParent
? $(options
.offsetParent
) : null;
5470 // Queries the els for coordinates and stores them.
5471 // Call this method before using and of the get* methods below.
5472 CoordCache
.prototype.build = function () {
5473 var offsetParentEl
= this.forcedOffsetParentEl
;
5474 if (!offsetParentEl
&& this.els
.length
> 0) {
5475 offsetParentEl
= this.els
.eq(0).offsetParent();
5477 this.origin
= offsetParentEl
?
5478 offsetParentEl
.offset() :
5480 this.boundingRect
= this.queryBoundingRect();
5481 if (this.isHorizontal
) {
5482 this.buildElHorizontals();
5484 if (this.isVertical
) {
5485 this.buildElVerticals();
5488 // Destroys all internal data about coordinates, freeing memory
5489 CoordCache
.prototype.clear = function () {
5491 this.boundingRect
= null;
5495 this.bottoms
= null;
5497 // When called, if coord caches aren't built, builds them
5498 CoordCache
.prototype.ensureBuilt = function () {
5503 // Populates the left/right internal coordinate arrays
5504 CoordCache
.prototype.buildElHorizontals = function () {
5507 this.els
.each(function (i
, node
) {
5509 var left
= el
.offset().left
;
5510 var width
= el
.outerWidth();
5512 rights
.push(left
+ width
);
5515 this.rights
= rights
;
5517 // Populates the top/bottom internal coordinate arrays
5518 CoordCache
.prototype.buildElVerticals = function () {
5521 this.els
.each(function (i
, node
) {
5523 var top
= el
.offset().top
;
5524 var height
= el
.outerHeight();
5526 bottoms
.push(top
+ height
);
5529 this.bottoms
= bottoms
;
5531 // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
5532 // If no intersection is made, returns undefined.
5533 CoordCache
.prototype.getHorizontalIndex = function (leftOffset
) {
5535 var lefts
= this.lefts
;
5536 var rights
= this.rights
;
5537 var len
= lefts
.length
;
5539 for (i
= 0; i
< len
; i
++) {
5540 if (leftOffset
>= lefts
[i
] && leftOffset
< rights
[i
]) {
5545 // Given a top offset (from document top), returns the index of the el that it vertically intersects.
5546 // If no intersection is made, returns undefined.
5547 CoordCache
.prototype.getVerticalIndex = function (topOffset
) {
5549 var tops
= this.tops
;
5550 var bottoms
= this.bottoms
;
5551 var len
= tops
.length
;
5553 for (i
= 0; i
< len
; i
++) {
5554 if (topOffset
>= tops
[i
] && topOffset
< bottoms
[i
]) {
5559 // Gets the left offset (from document left) of the element at the given index
5560 CoordCache
.prototype.getLeftOffset = function (leftIndex
) {
5562 return this.lefts
[leftIndex
];
5564 // Gets the left position (from offsetParent left) of the element at the given index
5565 CoordCache
.prototype.getLeftPosition = function (leftIndex
) {
5567 return this.lefts
[leftIndex
] - this.origin
.left
;
5569 // Gets the right offset (from document left) of the element at the given index.
5570 // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be.
5571 CoordCache
.prototype.getRightOffset = function (leftIndex
) {
5573 return this.rights
[leftIndex
];
5575 // Gets the right position (from offsetParent left) of the element at the given index.
5576 // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be.
5577 CoordCache
.prototype.getRightPosition = function (leftIndex
) {
5579 return this.rights
[leftIndex
] - this.origin
.left
;
5581 // Gets the width of the element at the given index
5582 CoordCache
.prototype.getWidth = function (leftIndex
) {
5584 return this.rights
[leftIndex
] - this.lefts
[leftIndex
];
5586 // Gets the top offset (from document top) of the element at the given index
5587 CoordCache
.prototype.getTopOffset = function (topIndex
) {
5589 return this.tops
[topIndex
];
5591 // Gets the top position (from offsetParent top) of the element at the given position
5592 CoordCache
.prototype.getTopPosition = function (topIndex
) {
5594 return this.tops
[topIndex
] - this.origin
.top
;
5596 // Gets the bottom offset (from the document top) of the element at the given index.
5597 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
5598 CoordCache
.prototype.getBottomOffset = function (topIndex
) {
5600 return this.bottoms
[topIndex
];
5602 // Gets the bottom position (from the offsetParent top) of the element at the given index.
5603 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
5604 CoordCache
.prototype.getBottomPosition = function (topIndex
) {
5606 return this.bottoms
[topIndex
] - this.origin
.top
;
5608 // Gets the height of the element at the given index
5609 CoordCache
.prototype.getHeight = function (topIndex
) {
5611 return this.bottoms
[topIndex
] - this.tops
[topIndex
];
5614 // TODO: decouple this from CoordCache
5615 // Compute and return what the elements' bounding rectangle is, from the user's perspective.
5616 // Right now, only returns a rectangle if constrained by an overflow:scroll element.
5617 // Returns null if there are no elements
5618 CoordCache
.prototype.queryBoundingRect = function () {
5620 if (this.els
.length
> 0) {
5621 scrollParentEl
= util_1
.getScrollParent(this.els
.eq(0));
5622 if (!scrollParentEl
.is(document
)) {
5623 return util_1
.getClientRect(scrollParentEl
);
5628 CoordCache
.prototype.isPointInBounds = function (leftOffset
, topOffset
) {
5629 return this.isLeftInBounds(leftOffset
) && this.isTopInBounds(topOffset
);
5631 CoordCache
.prototype.isLeftInBounds = function (leftOffset
) {
5632 return !this.boundingRect
|| (leftOffset
>= this.boundingRect
.left
&& leftOffset
< this.boundingRect
.right
);
5634 CoordCache
.prototype.isTopInBounds = function (topOffset
) {
5635 return !this.boundingRect
|| (topOffset
>= this.boundingRect
.top
&& topOffset
< this.boundingRect
.bottom
);
5639 exports
.default = CoordCache
;
5644 /***/ (function(module
, exports
, __webpack_require__
) {
5646 Object
.defineProperty(exports
, "__esModule", { value
: true });
5647 var $ = __webpack_require__(3);
5648 var util_1
= __webpack_require__(4);
5649 var ListenerMixin_1
= __webpack_require__(7);
5650 var GlobalEmitter_1
= __webpack_require__(21);
5651 /* Tracks a drag's mouse movement, firing various handlers
5652 ----------------------------------------------------------------------------------------------------------------------*/
5653 // TODO: use Emitter
5654 var DragListener
= /** @class */ (function () {
5655 function DragListener(options
) {
5656 this.isInteracting
= false;
5657 this.isDistanceSurpassed
= false;
5658 this.isDelayEnded
= false;
5659 this.isDragging
= false;
5660 this.isTouch
= false;
5661 this.isGeneric
= false; // initiated by 'dragstart' (jqui)
5662 this.shouldCancelTouchScroll
= true;
5663 this.scrollAlwaysKills
= false;
5664 this.isAutoScroll
= false;
5666 this.scrollSensitivity
= 30; // pixels from edge for scrolling to start
5667 this.scrollSpeed
= 200; // pixels per second, at maximum speed
5668 this.scrollIntervalMs
= 50; // millisecond wait between scroll increment
5669 this.options
= options
|| {};
5671 // Interaction (high-level)
5672 // -----------------------------------------------------------------------------------------------------------------
5673 DragListener
.prototype.startInteraction = function (ev
, extraOptions
) {
5674 if (extraOptions
=== void 0) { extraOptions
= {}; }
5675 if (ev
.type
=== 'mousedown') {
5676 if (GlobalEmitter_1
.default.get().shouldIgnoreMouse()) {
5679 else if (!util_1
.isPrimaryMouseButton(ev
)) {
5683 ev
.preventDefault(); // prevents native selection in most browsers
5686 if (!this.isInteracting
) {
5688 this.delay
= util_1
.firstDefined(extraOptions
.delay
, this.options
.delay
, 0);
5689 this.minDistance
= util_1
.firstDefined(extraOptions
.distance
, this.options
.distance
, 0);
5690 this.subjectEl
= this.options
.subjectEl
;
5691 util_1
.preventSelection($('body'));
5692 this.isInteracting
= true;
5693 this.isTouch
= util_1
.getEvIsTouch(ev
);
5694 this.isGeneric
= ev
.type
=== 'dragstart';
5695 this.isDelayEnded
= false;
5696 this.isDistanceSurpassed
= false;
5697 this.originX
= util_1
.getEvX(ev
);
5698 this.originY
= util_1
.getEvY(ev
);
5699 this.scrollEl
= util_1
.getScrollParent($(ev
.target
));
5700 this.bindHandlers();
5701 this.initAutoScroll();
5702 this.handleInteractionStart(ev
);
5703 this.startDelay(ev
);
5704 if (!this.minDistance
) {
5705 this.handleDistanceSurpassed(ev
);
5709 DragListener
.prototype.handleInteractionStart = function (ev
) {
5710 this.trigger('interactionStart', ev
);
5712 DragListener
.prototype.endInteraction = function (ev
, isCancelled
) {
5713 if (this.isInteracting
) {
5715 if (this.delayTimeoutId
) {
5716 clearTimeout(this.delayTimeoutId
);
5717 this.delayTimeoutId
= null;
5719 this.destroyAutoScroll();
5720 this.unbindHandlers();
5721 this.isInteracting
= false;
5722 this.handleInteractionEnd(ev
, isCancelled
);
5723 util_1
.allowSelection($('body'));
5726 DragListener
.prototype.handleInteractionEnd = function (ev
, isCancelled
) {
5727 this.trigger('interactionEnd', ev
, isCancelled
|| false);
5730 // -----------------------------------------------------------------------------------------------------------------
5731 DragListener
.prototype.bindHandlers = function () {
5732 // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart,
5733 // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly.
5734 var globalEmitter
= GlobalEmitter_1
.default.get();
5735 if (this.isGeneric
) {
5736 this.listenTo($(document
), {
5737 drag
: this.handleMove
,
5738 dragstop
: this.endInteraction
5741 else if (this.isTouch
) {
5742 this.listenTo(globalEmitter
, {
5743 touchmove
: this.handleTouchMove
,
5744 touchend
: this.endInteraction
,
5745 scroll
: this.handleTouchScroll
5749 this.listenTo(globalEmitter
, {
5750 mousemove
: this.handleMouseMove
,
5751 mouseup
: this.endInteraction
5754 this.listenTo(globalEmitter
, {
5755 selectstart
: util_1
.preventDefault
,
5756 contextmenu
: util_1
.preventDefault
// long taps would open menu on Chrome dev tools
5759 DragListener
.prototype.unbindHandlers = function () {
5760 this.stopListeningTo(GlobalEmitter_1
.default.get());
5761 this.stopListeningTo($(document
)); // for isGeneric
5763 // Drag (high-level)
5764 // -----------------------------------------------------------------------------------------------------------------
5765 // extraOptions ignored if drag already started
5766 DragListener
.prototype.startDrag = function (ev
, extraOptions
) {
5767 this.startInteraction(ev
, extraOptions
); // ensure interaction began
5768 if (!this.isDragging
) {
5769 this.isDragging
= true;
5770 this.handleDragStart(ev
);
5773 DragListener
.prototype.handleDragStart = function (ev
) {
5774 this.trigger('dragStart', ev
);
5776 DragListener
.prototype.handleMove = function (ev
) {
5777 var dx
= util_1
.getEvX(ev
) - this.originX
;
5778 var dy
= util_1
.getEvY(ev
) - this.originY
;
5779 var minDistance
= this.minDistance
;
5780 var distanceSq
; // current distance from the origin, squared
5781 if (!this.isDistanceSurpassed
) {
5782 distanceSq
= dx
* dx
+ dy
* dy
;
5783 if (distanceSq
>= minDistance
* minDistance
) {
5784 this.handleDistanceSurpassed(ev
);
5787 if (this.isDragging
) {
5788 this.handleDrag(dx
, dy
, ev
);
5791 // Called while the mouse is being moved and when we know a legitimate drag is taking place
5792 DragListener
.prototype.handleDrag = function (dx
, dy
, ev
) {
5793 this.trigger('drag', dx
, dy
, ev
);
5794 this.updateAutoScroll(ev
); // will possibly cause scrolling
5796 DragListener
.prototype.endDrag = function (ev
) {
5797 if (this.isDragging
) {
5798 this.isDragging
= false;
5799 this.handleDragEnd(ev
);
5802 DragListener
.prototype.handleDragEnd = function (ev
) {
5803 this.trigger('dragEnd', ev
);
5806 // -----------------------------------------------------------------------------------------------------------------
5807 DragListener
.prototype.startDelay = function (initialEv
) {
5810 this.delayTimeoutId
= setTimeout(function () {
5811 _this
.handleDelayEnd(initialEv
);
5815 this.handleDelayEnd(initialEv
);
5818 DragListener
.prototype.handleDelayEnd = function (initialEv
) {
5819 this.isDelayEnded
= true;
5820 if (this.isDistanceSurpassed
) {
5821 this.startDrag(initialEv
);
5825 // -----------------------------------------------------------------------------------------------------------------
5826 DragListener
.prototype.handleDistanceSurpassed = function (ev
) {
5827 this.isDistanceSurpassed
= true;
5828 if (this.isDelayEnded
) {
5833 // -----------------------------------------------------------------------------------------------------------------
5834 DragListener
.prototype.handleTouchMove = function (ev
) {
5835 // prevent inertia and touchmove-scrolling while dragging
5836 if (this.isDragging
&& this.shouldCancelTouchScroll
) {
5837 ev
.preventDefault();
5839 this.handleMove(ev
);
5841 DragListener
.prototype.handleMouseMove = function (ev
) {
5842 this.handleMove(ev
);
5844 // Scrolling (unrelated to auto-scroll)
5845 // -----------------------------------------------------------------------------------------------------------------
5846 DragListener
.prototype.handleTouchScroll = function (ev
) {
5847 // if the drag is being initiated by touch, but a scroll happens before
5848 // the drag-initiating delay is over, cancel the drag
5849 if (!this.isDragging
|| this.scrollAlwaysKills
) {
5850 this.endInteraction(ev
, true); // isCancelled=true
5854 // -----------------------------------------------------------------------------------------------------------------
5855 // Triggers a callback. Calls a function in the option hash of the same name.
5856 // Arguments beyond the first `name` are forwarded on.
5857 DragListener
.prototype.trigger = function (name
) {
5859 for (var _i
= 1; _i
< arguments
.length
; _i
++) {
5860 args
[_i
- 1] = arguments
[_i
];
5862 if (this.options
[name
]) {
5863 this.options
[name
].apply(this, args
);
5865 // makes _methods callable by event name. TODO: kill this
5866 if (this['_' + name
]) {
5867 this['_' + name
].apply(this, args
);
5871 // -----------------------------------------------------------------------------------------------------------------
5872 DragListener
.prototype.initAutoScroll = function () {
5873 var scrollEl
= this.scrollEl
;
5875 this.options
.scroll
&&
5877 !scrollEl
.is(window
) &&
5878 !scrollEl
.is(document
);
5879 if (this.isAutoScroll
) {
5880 // debounce makes sure rapid calls don't happen
5881 this.listenTo(scrollEl
, 'scroll', util_1
.debounce(this.handleDebouncedScroll
, 100));
5884 DragListener
.prototype.destroyAutoScroll = function () {
5885 this.endAutoScroll(); // kill any animation loop
5886 // remove the scroll handler if there is a scrollEl
5887 if (this.isAutoScroll
) {
5888 this.stopListeningTo(this.scrollEl
, 'scroll'); // will probably get removed by unbindHandlers too :(
5891 // Computes and stores the bounding rectangle of scrollEl
5892 DragListener
.prototype.computeScrollBounds = function () {
5893 if (this.isAutoScroll
) {
5894 this.scrollBounds
= util_1
.getOuterRect(this.scrollEl
);
5895 // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars
5898 // Called when the dragging is in progress and scrolling should be updated
5899 DragListener
.prototype.updateAutoScroll = function (ev
) {
5900 var sensitivity
= this.scrollSensitivity
;
5901 var bounds
= this.scrollBounds
;
5903 var bottomCloseness
;
5909 // compute closeness to edges. valid range is from 0.0 - 1.0
5910 topCloseness
= (sensitivity
- (util_1
.getEvY(ev
) - bounds
.top
)) / sensitivity
;
5911 bottomCloseness
= (sensitivity
- (bounds
.bottom
- util_1
.getEvY(ev
))) / sensitivity
;
5912 leftCloseness
= (sensitivity
- (util_1
.getEvX(ev
) - bounds
.left
)) / sensitivity
;
5913 rightCloseness
= (sensitivity
- (bounds
.right
- util_1
.getEvX(ev
))) / sensitivity
;
5914 // translate vertical closeness into velocity.
5915 // mouse must be completely in bounds for velocity to happen.
5916 if (topCloseness
>= 0 && topCloseness
<= 1) {
5917 topVel
= topCloseness
* this.scrollSpeed
* -1; // negative. for scrolling up
5919 else if (bottomCloseness
>= 0 && bottomCloseness
<= 1) {
5920 topVel
= bottomCloseness
* this.scrollSpeed
;
5922 // translate horizontal closeness into velocity
5923 if (leftCloseness
>= 0 && leftCloseness
<= 1) {
5924 leftVel
= leftCloseness
* this.scrollSpeed
* -1; // negative. for scrolling left
5926 else if (rightCloseness
>= 0 && rightCloseness
<= 1) {
5927 leftVel
= rightCloseness
* this.scrollSpeed
;
5930 this.setScrollVel(topVel
, leftVel
);
5932 // Sets the speed-of-scrolling for the scrollEl
5933 DragListener
.prototype.setScrollVel = function (topVel
, leftVel
) {
5934 this.scrollTopVel
= topVel
;
5935 this.scrollLeftVel
= leftVel
;
5936 this.constrainScrollVel(); // massages into realistic values
5937 // if there is non-zero velocity, and an animation loop hasn't already started, then START
5938 if ((this.scrollTopVel
|| this.scrollLeftVel
) && !this.scrollIntervalId
) {
5939 this.scrollIntervalId
= setInterval(util_1
.proxy(this, 'scrollIntervalFunc'), // scope to `this`
5940 this.scrollIntervalMs
);
5943 // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way
5944 DragListener
.prototype.constrainScrollVel = function () {
5945 var el
= this.scrollEl
;
5946 if (this.scrollTopVel
< 0) {
5947 if (el
.scrollTop() <= 0) {
5948 this.scrollTopVel
= 0;
5951 else if (this.scrollTopVel
> 0) {
5952 if (el
.scrollTop() + el
[0].clientHeight
>= el
[0].scrollHeight
) {
5953 this.scrollTopVel
= 0;
5956 if (this.scrollLeftVel
< 0) {
5957 if (el
.scrollLeft() <= 0) {
5958 this.scrollLeftVel
= 0;
5961 else if (this.scrollLeftVel
> 0) {
5962 if (el
.scrollLeft() + el
[0].clientWidth
>= el
[0].scrollWidth
) {
5963 this.scrollLeftVel
= 0;
5967 // This function gets called during every iteration of the scrolling animation loop
5968 DragListener
.prototype.scrollIntervalFunc = function () {
5969 var el
= this.scrollEl
;
5970 var frac
= this.scrollIntervalMs
/ 1000; // considering animation frequency, what the vel should be mult'd by
5971 // change the value of scrollEl's scroll
5972 if (this.scrollTopVel
) {
5973 el
.scrollTop(el
.scrollTop() + this.scrollTopVel
* frac
);
5975 if (this.scrollLeftVel
) {
5976 el
.scrollLeft(el
.scrollLeft() + this.scrollLeftVel
* frac
);
5978 this.constrainScrollVel(); // since the scroll values changed, recompute the velocities
5979 // if scrolled all the way, which causes the vels to be zero, stop the animation loop
5980 if (!this.scrollTopVel
&& !this.scrollLeftVel
) {
5981 this.endAutoScroll();
5984 // Kills any existing scrolling animation loop
5985 DragListener
.prototype.endAutoScroll = function () {
5986 if (this.scrollIntervalId
) {
5987 clearInterval(this.scrollIntervalId
);
5988 this.scrollIntervalId
= null;
5989 this.handleScrollEnd();
5992 // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)
5993 DragListener
.prototype.handleDebouncedScroll = function () {
5994 // recompute all coordinates, but *only* if this is *not* part of our scrolling animation
5995 if (!this.scrollIntervalId
) {
5996 this.handleScrollEnd();
5999 DragListener
.prototype.handleScrollEnd = function () {
6000 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
6002 return DragListener
;
6004 exports
.default = DragListener
;
6005 ListenerMixin_1
.default.mixInto(DragListener
);
6010 /***/ (function(module
, exports
, __webpack_require__
) {
6012 Object
.defineProperty(exports
, "__esModule", { value
: true });
6013 var tslib_1
= __webpack_require__(2);
6014 var util_1
= __webpack_require__(4);
6015 var Mixin_1
= __webpack_require__(14);
6017 A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns.
6018 Prerequisite: the object being mixed into needs to be a *Grid*
6020 var DayTableMixin
= /** @class */ (function (_super
) {
6021 tslib_1
.__extends(DayTableMixin
, _super
);
6022 function DayTableMixin() {
6023 return _super
!== null && _super
.apply(this, arguments
) || this;
6025 // Populates internal variables used for date calculation and rendering
6026 DayTableMixin
.prototype.updateDayTable = function () {
6029 var calendar
= view
.calendar
;
6030 var date
= calendar
.msToUtcMoment(t
.dateProfile
.renderUnzonedRange
.startMs
, true);
6031 var end
= calendar
.msToUtcMoment(t
.dateProfile
.renderUnzonedRange
.endMs
, true);
6033 var dayIndices
= [];
6038 while (date
.isBefore(end
)) {
6039 if (view
.isHiddenDay(date
)) {
6040 dayIndices
.push(dayIndex
+ 0.5); // mark that it's between indices
6044 dayIndices
.push(dayIndex
);
6045 dayDates
.push(date
.clone());
6047 date
.add(1, 'days');
6049 if (this.breakOnWeeks
) {
6050 // count columns until the day-of-week repeats
6051 firstDay
= dayDates
[0].day();
6052 for (daysPerRow
= 1; daysPerRow
< dayDates
.length
; daysPerRow
++) {
6053 if (dayDates
[daysPerRow
].day() === firstDay
) {
6057 rowCnt
= Math
.ceil(dayDates
.length
/ daysPerRow
);
6061 daysPerRow
= dayDates
.length
;
6063 this.dayDates
= dayDates
;
6064 this.dayIndices
= dayIndices
;
6065 this.daysPerRow
= daysPerRow
;
6066 this.rowCnt
= rowCnt
;
6067 this.updateDayTableCols();
6069 // Computes and assigned the colCnt property and updates any options that may be computed from it
6070 DayTableMixin
.prototype.updateDayTableCols = function () {
6071 this.colCnt
= this.computeColCnt();
6072 this.colHeadFormat
=
6073 this.opt('columnHeaderFormat') ||
6074 this.opt('columnFormat') || // deprecated
6075 this.computeColHeadFormat();
6077 // Determines how many columns there should be in the table
6078 DayTableMixin
.prototype.computeColCnt = function () {
6079 return this.daysPerRow
;
6081 // Computes the ambiguously-timed moment for the given cell
6082 DayTableMixin
.prototype.getCellDate = function (row
, col
) {
6083 return this.dayDates
[this.getCellDayIndex(row
, col
)].clone();
6085 // Computes the ambiguously-timed date range for the given cell
6086 DayTableMixin
.prototype.getCellRange = function (row
, col
) {
6087 var start
= this.getCellDate(row
, col
);
6088 var end
= start
.clone().add(1, 'days');
6089 return { start
: start
, end
: end
};
6091 // Returns the number of day cells, chronologically, from the first of the grid (0-based)
6092 DayTableMixin
.prototype.getCellDayIndex = function (row
, col
) {
6093 return row
* this.daysPerRow
+ this.getColDayIndex(col
);
6095 // Returns the numner of day cells, chronologically, from the first cell in *any given row*
6096 DayTableMixin
.prototype.getColDayIndex = function (col
) {
6098 return this.colCnt
- 1 - col
;
6104 // Given a date, returns its chronolocial cell-index from the first cell of the grid.
6105 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
6106 // If before the first offset, returns a negative number.
6107 // If after the last offset, returns an offset past the last cell offset.
6108 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
6109 DayTableMixin
.prototype.getDateDayIndex = function (date
) {
6110 var dayIndices
= this.dayIndices
;
6111 var dayOffset
= date
.diff(this.dayDates
[0], 'days');
6112 if (dayOffset
< 0) {
6113 return dayIndices
[0] - 1;
6115 else if (dayOffset
>= dayIndices
.length
) {
6116 return dayIndices
[dayIndices
.length
- 1] + 1;
6119 return dayIndices
[dayOffset
];
6123 ------------------------------------------------------------------------------------------------------------------*/
6124 // Computes a default column header formatting string if `colFormat` is not explicitly defined
6125 DayTableMixin
.prototype.computeColHeadFormat = function () {
6126 // if more than one week row, or if there are a lot of columns with not much space,
6127 // put just the day numbers will be in each cell
6128 if (this.rowCnt
> 1 || this.colCnt
> 10) {
6129 return 'ddd'; // "Sat"
6131 else if (this.colCnt
> 1) {
6132 return this.opt('dayOfMonthFormat'); // "Sat 12/10"
6135 return 'dddd'; // "Saturday"
6139 ------------------------------------------------------------------------------------------------------------------*/
6140 // Slices up a date range into a segment for every week-row it intersects with
6141 DayTableMixin
.prototype.sliceRangeByRow = function (unzonedRange
) {
6142 var daysPerRow
= this.daysPerRow
;
6143 var normalRange
= this.view
.computeDayRange(unzonedRange
); // make whole-day range, considering nextDayThreshold
6144 var rangeFirst
= this.getDateDayIndex(normalRange
.start
); // inclusive first index
6145 var rangeLast
= this.getDateDayIndex(normalRange
.end
.clone().subtract(1, 'days')); // inclusive last index
6149 var rowLast
; // inclusive day-index range for current row
6151 var segLast
; // inclusive day-index range for segment
6152 for (row
= 0; row
< this.rowCnt
; row
++) {
6153 rowFirst
= row
* daysPerRow
;
6154 rowLast
= rowFirst
+ daysPerRow
- 1;
6155 // intersect segment's offset range with the row's
6156 segFirst
= Math
.max(rangeFirst
, rowFirst
);
6157 segLast
= Math
.min(rangeLast
, rowLast
);
6158 // deal with in-between indices
6159 segFirst
= Math
.ceil(segFirst
); // in-between starts round to next cell
6160 segLast
= Math
.floor(segLast
); // in-between ends round to prev cell
6161 if (segFirst
<= segLast
) {
6164 // normalize to start of row
6165 firstRowDayIndex
: segFirst
- rowFirst
,
6166 lastRowDayIndex
: segLast
- rowFirst
,
6167 // must be matching integers to be the segment's start/end
6168 isStart
: segFirst
=== rangeFirst
,
6169 isEnd
: segLast
=== rangeLast
6175 // Slices up a date range into a segment for every day-cell it intersects with.
6176 // TODO: make more DRY with sliceRangeByRow somehow.
6177 DayTableMixin
.prototype.sliceRangeByDay = function (unzonedRange
) {
6178 var daysPerRow
= this.daysPerRow
;
6179 var normalRange
= this.view
.computeDayRange(unzonedRange
); // make whole-day range, considering nextDayThreshold
6180 var rangeFirst
= this.getDateDayIndex(normalRange
.start
); // inclusive first index
6181 var rangeLast
= this.getDateDayIndex(normalRange
.end
.clone().subtract(1, 'days')); // inclusive last index
6185 var rowLast
; // inclusive day-index range for current row
6188 var segLast
; // inclusive day-index range for segment
6189 for (row
= 0; row
< this.rowCnt
; row
++) {
6190 rowFirst
= row
* daysPerRow
;
6191 rowLast
= rowFirst
+ daysPerRow
- 1;
6192 for (i
= rowFirst
; i
<= rowLast
; i
++) {
6193 // intersect segment's offset range with the row's
6194 segFirst
= Math
.max(rangeFirst
, i
);
6195 segLast
= Math
.min(rangeLast
, i
);
6196 // deal with in-between indices
6197 segFirst
= Math
.ceil(segFirst
); // in-between starts round to next cell
6198 segLast
= Math
.floor(segLast
); // in-between ends round to prev cell
6199 if (segFirst
<= segLast
) {
6202 // normalize to start of row
6203 firstRowDayIndex
: segFirst
- rowFirst
,
6204 lastRowDayIndex
: segLast
- rowFirst
,
6205 // must be matching integers to be the segment's start/end
6206 isStart
: segFirst
=== rangeFirst
,
6207 isEnd
: segLast
=== rangeLast
6215 ------------------------------------------------------------------------------------------------------------------*/
6216 DayTableMixin
.prototype.renderHeadHtml = function () {
6217 var theme
= this.view
.calendar
.theme
;
6219 '<div class="fc-row ' + theme
.getClass('headerRow') + '">' +
6220 '<table class="' + theme
.getClass('tableGrid') + '">' +
6222 this.renderHeadTrHtml() +
6227 DayTableMixin
.prototype.renderHeadIntroHtml = function () {
6228 return this.renderIntroHtml(); // fall back to generic
6230 DayTableMixin
.prototype.renderHeadTrHtml = function () {
6233 (this.isRTL
? '' : this.renderHeadIntroHtml()) +
6234 this.renderHeadDateCellsHtml() +
6235 (this.isRTL
? this.renderHeadIntroHtml() : '') +
6238 DayTableMixin
.prototype.renderHeadDateCellsHtml = function () {
6242 for (col
= 0; col
< this.colCnt
; col
++) {
6243 date
= this.getCellDate(0, col
);
6244 htmls
.push(this.renderHeadDateCellHtml(date
));
6246 return htmls
.join('');
6248 // TODO: when internalApiVersion, accept an object for HTML attributes
6249 // (colspan should be no different)
6250 DayTableMixin
.prototype.renderHeadDateCellHtml = function (date
, colspan
, otherAttrs
) {
6253 var isDateValid
= t
.dateProfile
.activeUnzonedRange
.containsDate(date
); // TODO: called too frequently. cache somehow.
6256 view
.calendar
.theme
.getClass('widgetHeader')
6259 if (typeof t
.opt('columnHeaderHtml') === 'function') {
6260 innerHtml
= t
.opt('columnHeaderHtml')(date
);
6262 else if (typeof t
.opt('columnHeaderText') === 'function') {
6263 innerHtml
= util_1
.htmlEscape(t
.opt('columnHeaderText')(date
));
6266 innerHtml
= util_1
.htmlEscape(date
.format(t
.colHeadFormat
));
6268 // if only one row of days, the classNames on the header can represent the specific days beneath
6269 if (t
.rowCnt
=== 1) {
6270 classNames
= classNames
.concat(
6271 // includes the day-of-week class
6272 // noThemeHighlight=true (don't highlight the header)
6273 t
.getDayClasses(date
, true));
6276 classNames
.push('fc-' + util_1
.dayIDs
[date
.day()]); // only add the day-of-week class
6279 '<th class="' + classNames
.join(' ') + '"' +
6280 ((isDateValid
&& t
.rowCnt
) === 1 ?
6281 ' data-date="' + date
.format('YYYY-MM-DD') + '"' :
6284 ' colspan="' + colspan
+ '"' :
6291 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
6292 view
.buildGotoAnchorHtml({ date
: date
, forceOff
: t
.rowCnt
> 1 || t
.colCnt
=== 1 }, innerHtml
) :
6293 // if not valid, display text, but no link
6297 /* Background Rendering
6298 ------------------------------------------------------------------------------------------------------------------*/
6299 DayTableMixin
.prototype.renderBgTrHtml = function (row
) {
6302 (this.isRTL
? '' : this.renderBgIntroHtml(row
)) +
6303 this.renderBgCellsHtml(row
) +
6304 (this.isRTL
? this.renderBgIntroHtml(row
) : '') +
6307 DayTableMixin
.prototype.renderBgIntroHtml = function (row
) {
6308 return this.renderIntroHtml(); // fall back to generic
6310 DayTableMixin
.prototype.renderBgCellsHtml = function (row
) {
6314 for (col
= 0; col
< this.colCnt
; col
++) {
6315 date
= this.getCellDate(row
, col
);
6316 htmls
.push(this.renderBgCellHtml(date
));
6318 return htmls
.join('');
6320 DayTableMixin
.prototype.renderBgCellHtml = function (date
, otherAttrs
) {
6323 var isDateValid
= t
.dateProfile
.activeUnzonedRange
.containsDate(date
); // TODO: called too frequently. cache somehow.
6324 var classes
= t
.getDayClasses(date
);
6325 classes
.unshift('fc-day', view
.calendar
.theme
.getClass('widgetContent'));
6326 return '<td class="' + classes
.join(' ') + '"' +
6328 ' data-date="' + date
.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it
6336 ------------------------------------------------------------------------------------------------------------------*/
6337 DayTableMixin
.prototype.renderIntroHtml = function () {
6338 // Generates the default HTML intro for any row. User classes should override
6340 // TODO: a generic method for dealing with <tr>, RTL, intro
6341 // when increment internalApiVersion
6342 // wrapTr (scheduler)
6344 ------------------------------------------------------------------------------------------------------------------*/
6345 // Applies the generic "intro" and "outro" HTML to the given cells.
6346 // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
6347 DayTableMixin
.prototype.bookendCells = function (trEl
) {
6348 var introHtml
= this.renderIntroHtml();
6351 trEl
.append(introHtml
);
6354 trEl
.prepend(introHtml
);
6358 return DayTableMixin
;
6359 }(Mixin_1
.default));
6360 exports
.default = DayTableMixin
;
6365 /***/ (function(module
, exports
) {
6367 Object
.defineProperty(exports
, "__esModule", { value
: true });
6368 var BusinessHourRenderer
= /** @class */ (function () {
6370 component implements:
6371 - eventRangesToEventFootprints
6372 - eventFootprintsToSegs
6374 function BusinessHourRenderer(component
, fillRenderer
) {
6375 this.component
= component
;
6376 this.fillRenderer
= fillRenderer
;
6378 BusinessHourRenderer
.prototype.render = function (businessHourGenerator
) {
6379 var component
= this.component
;
6380 var unzonedRange
= component
._getDateProfile().activeUnzonedRange
;
6381 var eventInstanceGroup
= businessHourGenerator
.buildEventInstanceGroup(component
.hasAllDayBusinessHours
, unzonedRange
);
6382 var eventFootprints
= eventInstanceGroup
?
6383 component
.eventRangesToEventFootprints(eventInstanceGroup
.sliceRenderRanges(unzonedRange
)) :
6385 this.renderEventFootprints(eventFootprints
);
6387 BusinessHourRenderer
.prototype.renderEventFootprints = function (eventFootprints
) {
6388 var segs
= this.component
.eventFootprintsToSegs(eventFootprints
);
6389 this.renderSegs(segs
);
6392 BusinessHourRenderer
.prototype.renderSegs = function (segs
) {
6393 if (this.fillRenderer
) {
6394 this.fillRenderer
.renderSegs('businessHours', segs
, {
6395 getClasses: function (seg
) {
6396 return ['fc-nonbusiness', 'fc-bgevent'];
6401 BusinessHourRenderer
.prototype.unrender = function () {
6402 if (this.fillRenderer
) {
6403 this.fillRenderer
.unrender('businessHours');
6407 BusinessHourRenderer
.prototype.getSegs = function () {
6408 return this.segs
|| [];
6410 return BusinessHourRenderer
;
6412 exports
.default = BusinessHourRenderer
;
6417 /***/ (function(module
, exports
, __webpack_require__
) {
6419 Object
.defineProperty(exports
, "__esModule", { value
: true });
6420 var $ = __webpack_require__(3);
6421 var util_1
= __webpack_require__(4);
6422 var FillRenderer
= /** @class */ (function () {
6423 function FillRenderer(component
) {
6424 this.fillSegTag
= 'div';
6425 this.component
= component
;
6426 this.elsByFill
= {};
6428 FillRenderer
.prototype.renderFootprint = function (type
, componentFootprint
, props
) {
6429 this.renderSegs(type
, this.component
.componentFootprintToSegs(componentFootprint
), props
);
6431 FillRenderer
.prototype.renderSegs = function (type
, segs
, props
) {
6433 segs
= this.buildSegEls(type
, segs
, props
); // assignes `.el` to each seg. returns successfully rendered segs
6434 els
= this.attachSegEls(type
, segs
);
6436 this.reportEls(type
, els
);
6440 // Unrenders a specific type of fill that is currently rendered on the grid
6441 FillRenderer
.prototype.unrender = function (type
) {
6442 var el
= this.elsByFill
[type
];
6445 delete this.elsByFill
[type
];
6448 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
6449 // Only returns segments that successfully rendered.
6450 FillRenderer
.prototype.buildSegEls = function (type
, segs
, props
) {
6453 var renderedSegs
= [];
6456 // build a large concatenation of segment HTML
6457 for (i
= 0; i
< segs
.length
; i
++) {
6458 html
+= this.buildSegHtml(type
, segs
[i
], props
);
6460 // Grab individual elements from the combined HTML string. Use each as the default rendering.
6461 // Then, compute the 'el' for each segment.
6462 $(html
).each(function (i
, node
) {
6465 // allow custom filter methods per-type
6466 if (props
.filterEl
) {
6467 el
= props
.filterEl(seg
, el
);
6470 el
= $(el
); // allow custom filter to return raw DOM node
6471 // correct element type? (would be bad if a non-TD were inserted into a table for example)
6472 if (el
.is(_this
.fillSegTag
)) {
6474 renderedSegs
.push(seg
);
6479 return renderedSegs
;
6481 // Builds the HTML needed for one fill segment. Generic enough to work with different types.
6482 FillRenderer
.prototype.buildSegHtml = function (type
, seg
, props
) {
6483 // custom hooks per-type
6484 var classes
= props
.getClasses
? props
.getClasses(seg
) : [];
6485 var css
= util_1
.cssToStr(props
.getCss
? props
.getCss(seg
) : {});
6486 return '<' + this.fillSegTag
+
6487 (classes
.length
? ' class="' + classes
.join(' ') + '"' : '') +
6488 (css
? ' style="' + css
+ '"' : '') +
6491 // Should return wrapping DOM structure
6492 FillRenderer
.prototype.attachSegEls = function (type
, segs
) {
6493 // subclasses must implement
6495 FillRenderer
.prototype.reportEls = function (type
, nodes
) {
6496 if (this.elsByFill
[type
]) {
6497 this.elsByFill
[type
] = this.elsByFill
[type
].add(nodes
);
6500 this.elsByFill
[type
] = $(nodes
);
6503 return FillRenderer
;
6505 exports
.default = FillRenderer
;
6510 /***/ (function(module
, exports
, __webpack_require__
) {
6512 Object
.defineProperty(exports
, "__esModule", { value
: true });
6513 var SingleEventDef_1
= __webpack_require__(13);
6514 var EventFootprint_1
= __webpack_require__(36);
6515 var EventSource_1
= __webpack_require__(6);
6516 var HelperRenderer
= /** @class */ (function () {
6517 function HelperRenderer(component
, eventRenderer
) {
6518 this.view
= component
._getView();
6519 this.component
= component
;
6520 this.eventRenderer
= eventRenderer
;
6522 HelperRenderer
.prototype.renderComponentFootprint = function (componentFootprint
) {
6523 this.renderEventFootprints([
6524 this.fabricateEventFootprint(componentFootprint
)
6527 HelperRenderer
.prototype.renderEventDraggingFootprints = function (eventFootprints
, sourceSeg
, isTouch
) {
6528 this.renderEventFootprints(eventFootprints
, sourceSeg
, 'fc-dragging', isTouch
? null : this.view
.opt('dragOpacity'));
6530 HelperRenderer
.prototype.renderEventResizingFootprints = function (eventFootprints
, sourceSeg
, isTouch
) {
6531 this.renderEventFootprints(eventFootprints
, sourceSeg
, 'fc-resizing');
6533 HelperRenderer
.prototype.renderEventFootprints = function (eventFootprints
, sourceSeg
, extraClassNames
, opacity
) {
6534 var segs
= this.component
.eventFootprintsToSegs(eventFootprints
);
6535 var classNames
= 'fc-helper ' + (extraClassNames
|| '');
6537 // assigns each seg's el and returns a subset of segs that were rendered
6538 segs
= this.eventRenderer
.renderFgSegEls(segs
);
6539 for (i
= 0; i
< segs
.length
; i
++) {
6540 segs
[i
].el
.addClass(classNames
);
6542 if (opacity
!= null) {
6543 for (i
= 0; i
< segs
.length
; i
++) {
6544 segs
[i
].el
.css('opacity', opacity
);
6547 this.helperEls
= this.renderSegs(segs
, sourceSeg
);
6550 Must return all mock event elements
6552 HelperRenderer
.prototype.renderSegs = function (segs
, sourceSeg
) {
6553 // Subclasses must implement
6555 HelperRenderer
.prototype.unrender = function () {
6556 if (this.helperEls
) {
6557 this.helperEls
.remove();
6558 this.helperEls
= null;
6561 HelperRenderer
.prototype.fabricateEventFootprint = function (componentFootprint
) {
6562 var calendar
= this.view
.calendar
;
6563 var eventDateProfile
= calendar
.footprintToDateProfile(componentFootprint
);
6564 var dummyEvent
= new SingleEventDef_1
.default(new EventSource_1
.default(calendar
));
6566 dummyEvent
.dateProfile
= eventDateProfile
;
6567 dummyInstance
= dummyEvent
.buildInstance();
6568 return new EventFootprint_1
.default(componentFootprint
, dummyEvent
, dummyInstance
);
6570 return HelperRenderer
;
6572 exports
.default = HelperRenderer
;
6577 /***/ (function(module
, exports
, __webpack_require__
) {
6579 Object
.defineProperty(exports
, "__esModule", { value
: true });
6580 var tslib_1
= __webpack_require__(2);
6581 var GlobalEmitter_1
= __webpack_require__(21);
6582 var Interaction_1
= __webpack_require__(15);
6583 var EventPointing
= /** @class */ (function (_super
) {
6584 tslib_1
.__extends(EventPointing
, _super
);
6585 function EventPointing() {
6586 return _super
!== null && _super
.apply(this, arguments
) || this;
6589 component must implement:
6592 EventPointing
.prototype.bindToEl = function (el
) {
6593 var component
= this.component
;
6594 component
.bindSegHandlerToEl(el
, 'click', this.handleClick
.bind(this));
6595 component
.bindSegHandlerToEl(el
, 'mouseenter', this.handleMouseover
.bind(this));
6596 component
.bindSegHandlerToEl(el
, 'mouseleave', this.handleMouseout
.bind(this));
6598 EventPointing
.prototype.handleClick = function (seg
, ev
) {
6599 var res
= this.component
.publiclyTrigger('eventClick', {
6601 args
: [seg
.footprint
.getEventLegacy(), ev
, this.view
]
6603 if (res
=== false) {
6604 ev
.preventDefault();
6607 // Updates internal state and triggers handlers for when an event element is moused over
6608 EventPointing
.prototype.handleMouseover = function (seg
, ev
) {
6609 if (!GlobalEmitter_1
.default.get().shouldIgnoreMouse() &&
6610 !this.mousedOverSeg
) {
6611 this.mousedOverSeg
= seg
;
6612 // TODO: move to EventSelecting's responsibility
6613 if (this.view
.isEventDefResizable(seg
.footprint
.eventDef
)) {
6614 seg
.el
.addClass('fc-allow-mouse-resize');
6616 this.component
.publiclyTrigger('eventMouseover', {
6618 args
: [seg
.footprint
.getEventLegacy(), ev
, this.view
]
6622 // Updates internal state and triggers handlers for when an event element is moused out.
6623 // Can be given no arguments, in which case it will mouseout the segment that was previously moused over.
6624 EventPointing
.prototype.handleMouseout = function (seg
, ev
) {
6625 if (this.mousedOverSeg
) {
6626 this.mousedOverSeg
= null;
6627 // TODO: move to EventSelecting's responsibility
6628 if (this.view
.isEventDefResizable(seg
.footprint
.eventDef
)) {
6629 seg
.el
.removeClass('fc-allow-mouse-resize');
6631 this.component
.publiclyTrigger('eventMouseout', {
6634 seg
.footprint
.getEventLegacy(),
6641 EventPointing
.prototype.end = function () {
6642 if (this.mousedOverSeg
) {
6643 this.handleMouseout(this.mousedOverSeg
);
6646 return EventPointing
;
6647 }(Interaction_1
.default));
6648 exports
.default = EventPointing
;
6653 /***/ (function(module
, exports
, __webpack_require__
) {
6655 Object
.defineProperty(exports
, "__esModule", { value
: true });
6656 var tslib_1
= __webpack_require__(2);
6657 var Mixin_1
= __webpack_require__(14);
6658 var DateClicking_1
= __webpack_require__(245);
6659 var DateSelecting_1
= __webpack_require__(225);
6660 var EventPointing_1
= __webpack_require__(59);
6661 var EventDragging_1
= __webpack_require__(224);
6662 var EventResizing_1
= __webpack_require__(223);
6663 var ExternalDropping_1
= __webpack_require__(222);
6664 var StandardInteractionsMixin
= /** @class */ (function (_super
) {
6665 tslib_1
.__extends(StandardInteractionsMixin
, _super
);
6666 function StandardInteractionsMixin() {
6667 return _super
!== null && _super
.apply(this, arguments
) || this;
6669 return StandardInteractionsMixin
;
6670 }(Mixin_1
.default));
6671 exports
.default = StandardInteractionsMixin
;
6672 StandardInteractionsMixin
.prototype.dateClickingClass
= DateClicking_1
.default;
6673 StandardInteractionsMixin
.prototype.dateSelectingClass
= DateSelecting_1
.default;
6674 StandardInteractionsMixin
.prototype.eventPointingClass
= EventPointing_1
.default;
6675 StandardInteractionsMixin
.prototype.eventDraggingClass
= EventDragging_1
.default;
6676 StandardInteractionsMixin
.prototype.eventResizingClass
= EventResizing_1
.default;
6677 StandardInteractionsMixin
.prototype.externalDroppingClass
= ExternalDropping_1
.default;
6682 /***/ (function(module
, exports
, __webpack_require__
) {
6684 Object
.defineProperty(exports
, "__esModule", { value
: true });
6685 var tslib_1
= __webpack_require__(2);
6686 var $ = __webpack_require__(3);
6687 var util_1
= __webpack_require__(4);
6688 var CoordCache_1
= __webpack_require__(53);
6689 var Popover_1
= __webpack_require__(249);
6690 var UnzonedRange_1
= __webpack_require__(5);
6691 var ComponentFootprint_1
= __webpack_require__(12);
6692 var EventFootprint_1
= __webpack_require__(36);
6693 var BusinessHourRenderer_1
= __webpack_require__(56);
6694 var StandardInteractionsMixin_1
= __webpack_require__(60);
6695 var InteractiveDateComponent_1
= __webpack_require__(40);
6696 var DayTableMixin_1
= __webpack_require__(55);
6697 var DayGridEventRenderer_1
= __webpack_require__(250);
6698 var DayGridHelperRenderer_1
= __webpack_require__(251);
6699 var DayGridFillRenderer_1
= __webpack_require__(252);
6700 /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
6701 ----------------------------------------------------------------------------------------------------------------------*/
6702 var DayGrid
= /** @class */ (function (_super
) {
6703 tslib_1
.__extends(DayGrid
, _super
);
6704 function DayGrid(view
) {
6705 var _this
= _super
.call(this, view
) || this;
6706 _this
.cellWeekNumbersVisible
= false; // display week numbers in day cell?
6707 _this
.bottomCoordPadding
= 0; // hack for extending the hit area for the last row of the coordinate grid
6708 // isRigid determines whether the individual rows should ignore the contents and be a constant height.
6709 // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.
6710 _this
.isRigid
= false;
6711 _this
.hasAllDayBusinessHours
= true;
6714 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
6715 DayGrid
.prototype.componentFootprintToSegs = function (componentFootprint
) {
6716 var segs
= this.sliceRangeByRow(componentFootprint
.unzonedRange
);
6719 for (i
= 0; i
< segs
.length
; i
++) {
6722 seg
.leftCol
= this.daysPerRow
- 1 - seg
.lastRowDayIndex
;
6723 seg
.rightCol
= this.daysPerRow
- 1 - seg
.firstRowDayIndex
;
6726 seg
.leftCol
= seg
.firstRowDayIndex
;
6727 seg
.rightCol
= seg
.lastRowDayIndex
;
6733 ------------------------------------------------------------------------------------------------------------------*/
6734 DayGrid
.prototype.renderDates = function (dateProfile
) {
6735 this.dateProfile
= dateProfile
;
6736 this.updateDayTable();
6739 DayGrid
.prototype.unrenderDates = function () {
6740 this.removeSegPopover();
6742 // Renders the rows and columns into the component's `this.el`, which should already be assigned.
6743 DayGrid
.prototype.renderGrid = function () {
6744 var view
= this.view
;
6745 var rowCnt
= this.rowCnt
;
6746 var colCnt
= this.colCnt
;
6750 if (this.headContainerEl
) {
6751 this.headContainerEl
.html(this.renderHeadHtml());
6753 for (row
= 0; row
< rowCnt
; row
++) {
6754 html
+= this.renderDayRowHtml(row
, this.isRigid
);
6757 this.rowEls
= this.el
.find('.fc-row');
6758 this.cellEls
= this.el
.find('.fc-day, .fc-disabled-day');
6759 this.rowCoordCache
= new CoordCache_1
.default({
6763 this.colCoordCache
= new CoordCache_1
.default({
6764 els
: this.cellEls
.slice(0, this.colCnt
),
6767 // trigger dayRender with each cell's element
6768 for (row
= 0; row
< rowCnt
; row
++) {
6769 for (col
= 0; col
< colCnt
; col
++) {
6770 this.publiclyTrigger('dayRender', {
6773 this.getCellDate(row
, col
),
6774 this.getCellEl(row
, col
),
6781 // Generates the HTML for a single row, which is a div that wraps a table.
6782 // `row` is the row number.
6783 DayGrid
.prototype.renderDayRowHtml = function (row
, isRigid
) {
6784 var theme
= this.view
.calendar
.theme
;
6785 var classes
= ['fc-row', 'fc-week', theme
.getClass('dayRow')];
6787 classes
.push('fc-rigid');
6790 '<div class="' + classes
.join(' ') + '">' +
6791 '<div class="fc-bg">' +
6792 '<table class="' + theme
.getClass('tableGrid') + '">' +
6793 this.renderBgTrHtml(row
) +
6796 '<div class="fc-content-skeleton">' +
6798 (this.getIsNumbersVisible() ?
6800 this.renderNumberTrHtml(row
) +
6807 DayGrid
.prototype.getIsNumbersVisible = function () {
6808 return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible
;
6810 DayGrid
.prototype.getIsDayNumbersVisible = function () {
6811 return this.rowCnt
> 1;
6813 /* Grid Number Rendering
6814 ------------------------------------------------------------------------------------------------------------------*/
6815 DayGrid
.prototype.renderNumberTrHtml = function (row
) {
6818 (this.isRTL
? '' : this.renderNumberIntroHtml(row
)) +
6819 this.renderNumberCellsHtml(row
) +
6820 (this.isRTL
? this.renderNumberIntroHtml(row
) : '') +
6823 DayGrid
.prototype.renderNumberIntroHtml = function (row
) {
6824 return this.renderIntroHtml();
6826 DayGrid
.prototype.renderNumberCellsHtml = function (row
) {
6830 for (col
= 0; col
< this.colCnt
; col
++) {
6831 date
= this.getCellDate(row
, col
);
6832 htmls
.push(this.renderNumberCellHtml(date
));
6834 return htmls
.join('');
6836 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
6837 // The number row will only exist if either day numbers or week numbers are turned on.
6838 DayGrid
.prototype.renderNumberCellHtml = function (date
) {
6839 var view
= this.view
;
6841 var isDateValid
= this.dateProfile
.activeUnzonedRange
.containsDate(date
); // TODO: called too frequently. cache somehow.
6842 var isDayNumberVisible
= this.getIsDayNumbersVisible() && isDateValid
;
6844 var weekCalcFirstDoW
;
6845 if (!isDayNumberVisible
&& !this.cellWeekNumbersVisible
) {
6846 // no numbers in day cell (week number must be along the side)
6847 return '<td/>'; // will create an empty space above events :(
6849 classes
= this.getDayClasses(date
);
6850 classes
.unshift('fc-day-top');
6851 if (this.cellWeekNumbersVisible
) {
6852 // To determine the day of week number change under ISO, we cannot
6853 // rely on moment.js methods such as firstDayOfWeek() or weekday(),
6854 // because they rely on the locale's dow (possibly overridden by
6855 // our firstDay option), which may not be Monday. We cannot change
6856 // dow, because that would affect the calendar start day as well.
6857 if (date
._locale
._fullCalendar_weekCalc
=== 'ISO') {
6858 weekCalcFirstDoW
= 1; // Monday by ISO 8601 definition
6861 weekCalcFirstDoW
= date
._locale
.firstDayOfWeek();
6864 html
+= '<td class="' + classes
.join(' ') + '"' +
6866 ' data-date="' + date
.format() + '"' :
6869 if (this.cellWeekNumbersVisible
&& (date
.day() === weekCalcFirstDoW
)) {
6870 html
+= view
.buildGotoAnchorHtml({ date
: date
, type
: 'week' }, { 'class': 'fc-week-number' }, date
.format('w') // inner HTML
6873 if (isDayNumberVisible
) {
6874 html
+= view
.buildGotoAnchorHtml(date
, { 'class': 'fc-day-number' }, date
.format('D') // inner HTML
6881 ------------------------------------------------------------------------------------------------------------------*/
6882 DayGrid
.prototype.prepareHits = function () {
6883 this.colCoordCache
.build();
6884 this.rowCoordCache
.build();
6885 this.rowCoordCache
.bottoms
[this.rowCnt
- 1] += this.bottomCoordPadding
; // hack
6887 DayGrid
.prototype.releaseHits = function () {
6888 this.colCoordCache
.clear();
6889 this.rowCoordCache
.clear();
6891 DayGrid
.prototype.queryHit = function (leftOffset
, topOffset
) {
6892 if (this.colCoordCache
.isLeftInBounds(leftOffset
) && this.rowCoordCache
.isTopInBounds(topOffset
)) {
6893 var col
= this.colCoordCache
.getHorizontalIndex(leftOffset
);
6894 var row
= this.rowCoordCache
.getVerticalIndex(topOffset
);
6895 if (row
!= null && col
!= null) {
6896 return this.getCellHit(row
, col
);
6900 DayGrid
.prototype.getHitFootprint = function (hit
) {
6901 var range
= this.getCellRange(hit
.row
, hit
.col
);
6902 return new ComponentFootprint_1
.default(new UnzonedRange_1
.default(range
.start
, range
.end
), true // all-day?
6905 DayGrid
.prototype.getHitEl = function (hit
) {
6906 return this.getCellEl(hit
.row
, hit
.col
);
6909 ------------------------------------------------------------------------------------------------------------------*/
6910 // FYI: the first column is the leftmost column, regardless of date
6911 DayGrid
.prototype.getCellHit = function (row
, col
) {
6916 left
: this.colCoordCache
.getLeftOffset(col
),
6917 right
: this.colCoordCache
.getRightOffset(col
),
6918 top
: this.rowCoordCache
.getTopOffset(row
),
6919 bottom
: this.rowCoordCache
.getBottomOffset(row
)
6922 DayGrid
.prototype.getCellEl = function (row
, col
) {
6923 return this.cellEls
.eq(row
* this.colCnt
+ col
);
6926 ------------------------------------------------------------------------------------------------------------------*/
6927 // Unrenders all events currently rendered on the grid
6928 DayGrid
.prototype.executeEventUnrender = function () {
6929 this.removeSegPopover(); // removes the "more.." events popover
6930 _super
.prototype.executeEventUnrender
.call(this);
6932 // Retrieves all rendered segment objects currently rendered on the grid
6933 DayGrid
.prototype.getOwnEventSegs = function () {
6934 // append the segments from the "more..." popover
6935 return _super
.prototype.getOwnEventSegs
.call(this).concat(this.popoverSegs
|| []);
6937 /* Event Drag Visualization
6938 ------------------------------------------------------------------------------------------------------------------*/
6939 // Renders a visual indication of an event or external element being dragged.
6940 // `eventLocation` has zoned start and end (optional)
6941 DayGrid
.prototype.renderDrag = function (eventFootprints
, seg
, isTouch
) {
6943 for (i
= 0; i
< eventFootprints
.length
; i
++) {
6944 this.renderHighlight(eventFootprints
[i
].componentFootprint
);
6946 // render drags from OTHER components as helpers
6947 if (eventFootprints
.length
&& seg
&& seg
.component
!== this) {
6948 this.helperRenderer
.renderEventDraggingFootprints(eventFootprints
, seg
, isTouch
);
6949 return true; // signal helpers rendered
6952 // Unrenders any visual indication of a hovering event
6953 DayGrid
.prototype.unrenderDrag = function () {
6954 this.unrenderHighlight();
6955 this.helperRenderer
.unrender();
6957 /* Event Resize Visualization
6958 ------------------------------------------------------------------------------------------------------------------*/
6959 // Renders a visual indication of an event being resized
6960 DayGrid
.prototype.renderEventResize = function (eventFootprints
, seg
, isTouch
) {
6962 for (i
= 0; i
< eventFootprints
.length
; i
++) {
6963 this.renderHighlight(eventFootprints
[i
].componentFootprint
);
6965 this.helperRenderer
.renderEventResizingFootprints(eventFootprints
, seg
, isTouch
);
6967 // Unrenders a visual indication of an event being resized
6968 DayGrid
.prototype.unrenderEventResize = function () {
6969 this.unrenderHighlight();
6970 this.helperRenderer
.unrender();
6972 /* More+ Link Popover
6973 ------------------------------------------------------------------------------------------------------------------*/
6974 DayGrid
.prototype.removeSegPopover = function () {
6975 if (this.segPopover
) {
6976 this.segPopover
.hide(); // in handler, will call segPopover's removeElement
6979 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
6980 // `levelLimit` can be false (don't limit), a number, or true (should be computed).
6981 DayGrid
.prototype.limitRows = function (levelLimit
) {
6982 var rowStructs
= this.eventRenderer
.rowStructs
|| [];
6985 for (row
= 0; row
< rowStructs
.length
; row
++) {
6986 this.unlimitRow(row
);
6988 rowLevelLimit
= false;
6990 else if (typeof levelLimit
=== 'number') {
6991 rowLevelLimit
= levelLimit
;
6994 rowLevelLimit
= this.computeRowLevelLimit(row
);
6996 if (rowLevelLimit
!== false) {
6997 this.limitRow(row
, rowLevelLimit
);
7001 // Computes the number of levels a row will accomodate without going outside its bounds.
7002 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
7003 // `row` is the row number.
7004 DayGrid
.prototype.computeRowLevelLimit = function (row
) {
7005 var rowEl
= this.rowEls
.eq(row
); // the containing "fake" row div
7006 var rowHeight
= rowEl
.height(); // TODO: cache somehow?
7007 var trEls
= this.eventRenderer
.rowStructs
[row
].tbodyEl
.children();
7011 function iterInnerHeights(i
, childNode
) {
7012 trHeight
= Math
.max(trHeight
, $(childNode
).outerHeight());
7014 // Reveal one level <tr> at a time and stop when we find one out of bounds
7015 for (i
= 0; i
< trEls
.length
; i
++) {
7016 trEl
= trEls
.eq(i
).removeClass('fc-limited'); // reset to original state (reveal)
7017 // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,
7018 // so instead, find the tallest inner content element.
7020 trEl
.find('> td > :first-child').each(iterInnerHeights
);
7021 if (trEl
.position().top
+ trHeight
> rowHeight
) {
7025 return false; // should not limit at all
7027 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
7028 // `row` is the row number.
7029 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
7030 DayGrid
.prototype.limitRow = function (row
, levelLimit
) {
7032 var rowStruct
= this.eventRenderer
.rowStructs
[row
];
7033 var moreNodes
= []; // array of "more" <a> links and <td> DOM nodes
7034 var col
= 0; // col #, left-to-right (not chronologically)
7035 var levelSegs
; // array of segment objects in the last allowable level, ordered left-to-right
7036 var cellMatrix
; // a matrix (by level, then column) of all <td> jQuery elements in the row
7037 var limitedNodes
; // array of temporarily hidden level <tr> and segment <td> DOM nodes
7040 var segsBelow
; // array of segment objects below `seg` in the current `col`
7041 var totalSegsBelow
; // total number of segments below `seg` in any of the columns `seg` occupies
7042 var colSegsBelow
; // array of segment arrays, below seg, one for each column (offset from segs's first column)
7045 var segMoreNodes
; // array of "more" <td> cells that will stand-in for the current seg's cell
7050 // Iterates through empty level cells and places "more" links inside if need be
7051 var emptyCellsUntil = function (endCol
) {
7052 while (col
< endCol
) {
7053 segsBelow
= _this
.getCellSegs(row
, col
, levelLimit
);
7054 if (segsBelow
.length
) {
7055 td
= cellMatrix
[levelLimit
- 1][col
];
7056 moreLink
= _this
.renderMoreLink(row
, col
, segsBelow
);
7057 moreWrap
= $('<div/>').append(moreLink
);
7058 td
.append(moreWrap
);
7059 moreNodes
.push(moreWrap
[0]);
7064 if (levelLimit
&& levelLimit
< rowStruct
.segLevels
.length
) {
7065 levelSegs
= rowStruct
.segLevels
[levelLimit
- 1];
7066 cellMatrix
= rowStruct
.cellMatrix
;
7067 limitedNodes
= rowStruct
.tbodyEl
.children().slice(levelLimit
) // get level <tr> elements past the limit
7068 .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array
7069 // iterate though segments in the last allowable level
7070 for (i
= 0; i
< levelSegs
.length
; i
++) {
7072 emptyCellsUntil(seg
.leftCol
); // process empty cells before the segment
7073 // determine *all* segments below `seg` that occupy the same columns
7076 while (col
<= seg
.rightCol
) {
7077 segsBelow
= this.getCellSegs(row
, col
, levelLimit
);
7078 colSegsBelow
.push(segsBelow
);
7079 totalSegsBelow
+= segsBelow
.length
;
7082 if (totalSegsBelow
) {
7083 td
= cellMatrix
[levelLimit
- 1][seg
.leftCol
]; // the segment's parent cell
7084 rowspan
= td
.attr('rowspan') || 1;
7086 // make a replacement <td> for each column the segment occupies. will be one for each colspan
7087 for (j
= 0; j
< colSegsBelow
.length
; j
++) {
7088 moreTd
= $('<td class="fc-more-cell"/>').attr('rowspan', rowspan
);
7089 segsBelow
= colSegsBelow
[j
];
7090 moreLink
= this.renderMoreLink(row
, seg
.leftCol
+ j
, [seg
].concat(segsBelow
) // count seg as hidden too
7092 moreWrap
= $('<div/>').append(moreLink
);
7093 moreTd
.append(moreWrap
);
7094 segMoreNodes
.push(moreTd
[0]);
7095 moreNodes
.push(moreTd
[0]);
7097 td
.addClass('fc-limited').after($(segMoreNodes
)); // hide original <td> and inject replacements
7098 limitedNodes
.push(td
[0]);
7101 emptyCellsUntil(this.colCnt
); // finish off the level
7102 rowStruct
.moreEls
= $(moreNodes
); // for easy undoing later
7103 rowStruct
.limitedEls
= $(limitedNodes
); // for easy undoing later
7106 // Reveals all levels and removes all "more"-related elements for a grid's row.
7107 // `row` is a row number.
7108 DayGrid
.prototype.unlimitRow = function (row
) {
7109 var rowStruct
= this.eventRenderer
.rowStructs
[row
];
7110 if (rowStruct
.moreEls
) {
7111 rowStruct
.moreEls
.remove();
7112 rowStruct
.moreEls
= null;
7114 if (rowStruct
.limitedEls
) {
7115 rowStruct
.limitedEls
.removeClass('fc-limited');
7116 rowStruct
.limitedEls
= null;
7119 // Renders an <a> element that represents hidden event element for a cell.
7120 // Responsible for attaching click handler as well.
7121 DayGrid
.prototype.renderMoreLink = function (row
, col
, hiddenSegs
) {
7123 var view
= this.view
;
7124 return $('<a class="fc-more"/>')
7125 .text(this.getMoreLinkText(hiddenSegs
.length
))
7126 .on('click', function (ev
) {
7127 var clickOption
= _this
.opt('eventLimitClick');
7128 var date
= _this
.getCellDate(row
, col
);
7129 var moreEl
= $(ev
.currentTarget
);
7130 var dayEl
= _this
.getCellEl(row
, col
);
7131 var allSegs
= _this
.getCellSegs(row
, col
);
7132 // rescope the segments to be within the cell's date
7133 var reslicedAllSegs
= _this
.resliceDaySegs(allSegs
, date
);
7134 var reslicedHiddenSegs
= _this
.resliceDaySegs(hiddenSegs
, date
);
7135 if (typeof clickOption
=== 'function') {
7136 // the returned value can be an atomic option
7137 clickOption
= _this
.publiclyTrigger('eventLimitClick', {
7144 segs
: reslicedAllSegs
,
7145 hiddenSegs
: reslicedHiddenSegs
7152 if (clickOption
=== 'popover') {
7153 _this
.showSegPopover(row
, col
, moreEl
, reslicedAllSegs
);
7155 else if (typeof clickOption
=== 'string') {
7156 view
.calendar
.zoomTo(date
, clickOption
);
7160 // Reveals the popover that displays all events within a cell
7161 DayGrid
.prototype.showSegPopover = function (row
, col
, moreLink
, segs
) {
7163 var view
= this.view
;
7164 var moreWrap
= moreLink
.parent(); // the <div> wrapper around the <a>
7165 var topEl
; // the element we want to match the top coordinate of
7167 if (this.rowCnt
=== 1) {
7168 topEl
= view
.el
; // will cause the popover to cover any sort of header
7171 topEl
= this.rowEls
.eq(row
); // will align with top of row
7174 className
: 'fc-more-popover ' + view
.calendar
.theme
.getClass('popover'),
7175 content
: this.renderSegPopoverContent(row
, col
, segs
),
7177 top
: topEl
.offset().top
,
7179 viewportConstrain
: this.opt('popoverViewportConstrain'),
7181 // kill everything when the popover is hidden
7182 // notify events to be removed
7183 if (_this
.popoverSegs
) {
7184 _this
.triggerBeforeEventSegsDestroyed(_this
.popoverSegs
);
7186 _this
.segPopover
.removeElement();
7187 _this
.segPopover
= null;
7188 _this
.popoverSegs
= null;
7191 // Determine horizontal coordinate.
7192 // We use the moreWrap instead of the <td> to avoid border confusion.
7194 options
.right
= moreWrap
.offset().left
+ moreWrap
.outerWidth() + 1; // +1 to be over cell border
7197 options
.left
= moreWrap
.offset().left
- 1; // -1 to be over cell border
7199 this.segPopover
= new Popover_1
.default(options
);
7200 this.segPopover
.show();
7201 // the popover doesn't live within the grid's container element, and thus won't get the event
7202 // delegated-handlers for free. attach event-related handlers to the popover.
7203 this.bindAllSegHandlersToEl(this.segPopover
.el
);
7204 this.triggerAfterEventSegsRendered(segs
);
7206 // Builds the inner DOM contents of the segment popover
7207 DayGrid
.prototype.renderSegPopoverContent = function (row
, col
, segs
) {
7208 var view
= this.view
;
7209 var theme
= view
.calendar
.theme
;
7210 var title
= this.getCellDate(row
, col
).format(this.opt('dayPopoverFormat'));
7211 var content
= $('<div class="fc-header ' + theme
.getClass('popoverHeader') + '">' +
7212 '<span class="fc-close ' + theme
.getIconClass('close') + '"></span>' +
7213 '<span class="fc-title">' +
7214 util_1
.htmlEscape(title
) +
7216 '<div class="fc-clear"/>' +
7218 '<div class="fc-body ' + theme
.getClass('popoverContent') + '">' +
7219 '<div class="fc-event-container"></div>' +
7221 var segContainer
= content
.find('.fc-event-container');
7223 // render each seg's `el` and only return the visible segs
7224 segs
= this.eventRenderer
.renderFgSegEls(segs
, true); // disableResizing=true
7225 this.popoverSegs
= segs
;
7226 for (i
= 0; i
< segs
.length
; i
++) {
7227 // because segments in the popover are not part of a grid coordinate system, provide a hint to any
7228 // grids that want to do drag-n-drop about which cell it came from
7230 segs
[i
].hit
= this.getCellHit(row
, col
);
7231 this.hitsNotNeeded();
7232 segContainer
.append(segs
[i
].el
);
7236 // Given the events within an array of segment objects, reslice them to be in a single day
7237 DayGrid
.prototype.resliceDaySegs = function (segs
, dayDate
) {
7238 var dayStart
= dayDate
.clone();
7239 var dayEnd
= dayStart
.clone().add(1, 'days');
7240 var dayRange
= new UnzonedRange_1
.default(dayStart
, dayEnd
);
7245 for (i
= 0; i
< segs
.length
; i
++) {
7247 slicedRange
= seg
.footprint
.componentFootprint
.unzonedRange
.intersect(dayRange
);
7249 newSegs
.push($.extend({}, seg
, {
7250 footprint
: new EventFootprint_1
.default(new ComponentFootprint_1
.default(slicedRange
, seg
.footprint
.componentFootprint
.isAllDay
), seg
.footprint
.eventDef
, seg
.footprint
.eventInstance
),
7251 isStart
: seg
.isStart
&& slicedRange
.isStart
,
7252 isEnd
: seg
.isEnd
&& slicedRange
.isEnd
7256 // force an order because eventsToSegs doesn't guarantee one
7257 // TODO: research if still needed
7258 this.eventRenderer
.sortEventSegs(newSegs
);
7261 // Generates the text that should be inside a "more" link, given the number of events it represents
7262 DayGrid
.prototype.getMoreLinkText = function (num
) {
7263 var opt
= this.opt('eventLimitText');
7264 if (typeof opt
=== 'function') {
7268 return '+' + num
+ ' ' + opt
;
7271 // Returns segments within a given cell.
7272 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
7273 DayGrid
.prototype.getCellSegs = function (row
, col
, startLevel
) {
7274 var segMatrix
= this.eventRenderer
.rowStructs
[row
].segMatrix
;
7275 var level
= startLevel
|| 0;
7278 while (level
< segMatrix
.length
) {
7279 seg
= segMatrix
[level
][col
];
7288 }(InteractiveDateComponent_1
.default));
7289 exports
.default = DayGrid
;
7290 DayGrid
.prototype.eventRendererClass
= DayGridEventRenderer_1
.default;
7291 DayGrid
.prototype.businessHourRendererClass
= BusinessHourRenderer_1
.default;
7292 DayGrid
.prototype.helperRendererClass
= DayGridHelperRenderer_1
.default;
7293 DayGrid
.prototype.fillRendererClass
= DayGridFillRenderer_1
.default;
7294 StandardInteractionsMixin_1
.default.mixInto(DayGrid
);
7295 DayTableMixin_1
.default.mixInto(DayGrid
);
7300 /***/ (function(module
, exports
, __webpack_require__
) {
7302 Object
.defineProperty(exports
, "__esModule", { value
: true });
7303 var tslib_1
= __webpack_require__(2);
7304 var $ = __webpack_require__(3);
7305 var util_1
= __webpack_require__(4);
7306 var Scroller_1
= __webpack_require__(39);
7307 var View_1
= __webpack_require__(41);
7308 var BasicViewDateProfileGenerator_1
= __webpack_require__(228);
7309 var DayGrid_1
= __webpack_require__(61);
7310 /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
7311 ----------------------------------------------------------------------------------------------------------------------*/
7312 // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
7313 // It is responsible for managing width/height.
7314 var BasicView
= /** @class */ (function (_super
) {
7315 tslib_1
.__extends(BasicView
, _super
);
7316 function BasicView(calendar
, viewSpec
) {
7317 var _this
= _super
.call(this, calendar
, viewSpec
) || this;
7318 _this
.dayGrid
= _this
.instantiateDayGrid();
7319 _this
.dayGrid
.isRigid
= _this
.hasRigidRows();
7320 if (_this
.opt('weekNumbers')) {
7321 if (_this
.opt('weekNumbersWithinDays')) {
7322 _this
.dayGrid
.cellWeekNumbersVisible
= true;
7323 _this
.dayGrid
.colWeekNumbersVisible
= false;
7326 _this
.dayGrid
.cellWeekNumbersVisible
= false;
7327 _this
.dayGrid
.colWeekNumbersVisible
= true;
7330 _this
.addChild(_this
.dayGrid
);
7331 _this
.scroller
= new Scroller_1
.default({
7332 overflowX
: 'hidden',
7337 // Generates the DayGrid object this view needs. Draws from this.dayGridClass
7338 BasicView
.prototype.instantiateDayGrid = function () {
7339 // generate a subclass on the fly with BasicView-specific behavior
7340 // TODO: cache this subclass
7341 var subclass
= makeDayGridSubclass(this.dayGridClass
);
7342 return new subclass(this);
7344 BasicView
.prototype.executeDateRender = function (dateProfile
) {
7345 this.dayGrid
.breakOnWeeks
= /year|month|week/.test(dateProfile
.currentRangeUnit
);
7346 _super
.prototype.executeDateRender
.call(this, dateProfile
);
7348 BasicView
.prototype.renderSkeleton = function () {
7349 var dayGridContainerEl
;
7351 this.el
.addClass('fc-basic-view').html(this.renderSkeletonHtml());
7352 this.scroller
.render();
7353 dayGridContainerEl
= this.scroller
.el
.addClass('fc-day-grid-container');
7354 dayGridEl
= $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl
);
7355 this.el
.find('.fc-body > tr > td').append(dayGridContainerEl
);
7356 this.dayGrid
.headContainerEl
= this.el
.find('.fc-head-container');
7357 this.dayGrid
.setElement(dayGridEl
);
7359 BasicView
.prototype.unrenderSkeleton = function () {
7360 this.dayGrid
.removeElement();
7361 this.scroller
.destroy();
7363 // Builds the HTML skeleton for the view.
7364 // The day-grid component will render inside of a container defined by this HTML.
7365 BasicView
.prototype.renderSkeletonHtml = function () {
7366 var theme
= this.calendar
.theme
;
7368 '<table class="' + theme
.getClass('tableGrid') + '">' +
7369 (this.opt('columnHeader') ?
7370 '<thead class="fc-head">' +
7372 '<td class="fc-head-container ' + theme
.getClass('widgetHeader') + '"> </td>' +
7376 '<tbody class="fc-body">' +
7378 '<td class="' + theme
.getClass('widgetContent') + '"></td>' +
7383 // Generates an HTML attribute string for setting the width of the week number column, if it is known
7384 BasicView
.prototype.weekNumberStyleAttr = function () {
7385 if (this.weekNumberWidth
!= null) {
7386 return 'style="width:' + this.weekNumberWidth
+ 'px"';
7390 // Determines whether each row should have a constant height
7391 BasicView
.prototype.hasRigidRows = function () {
7392 var eventLimit
= this.opt('eventLimit');
7393 return eventLimit
&& typeof eventLimit
!== 'number';
7396 ------------------------------------------------------------------------------------------------------------------*/
7397 // Refreshes the horizontal dimensions of the view
7398 BasicView
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
7399 var eventLimit
= this.opt('eventLimit');
7400 var headRowEl
= this.dayGrid
.headContainerEl
.find('.fc-row');
7402 var scrollbarWidths
;
7403 // hack to give the view some height prior to dayGrid's columns being rendered
7404 // TODO: separate setting height from scroller VS dayGrid.
7405 if (!this.dayGrid
.rowEls
) {
7407 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
7408 this.scroller
.setHeight(scrollerHeight
);
7412 _super
.prototype.updateSize
.call(this, totalHeight
, isAuto
, isResize
);
7413 if (this.dayGrid
.colWeekNumbersVisible
) {
7414 // Make sure all week number cells running down the side have the same width.
7415 // Record the width for cells created later.
7416 this.weekNumberWidth
= util_1
.matchCellWidths(this.el
.find('.fc-week-number'));
7418 // reset all heights to be natural
7419 this.scroller
.clear();
7420 util_1
.uncompensateScroll(headRowEl
);
7421 this.dayGrid
.removeSegPopover(); // kill the "more" popover if displayed
7422 // is the event limit a constant level number?
7423 if (eventLimit
&& typeof eventLimit
=== 'number') {
7424 this.dayGrid
.limitRows(eventLimit
); // limit the levels first so the height can redistribute after
7426 // distribute the height to the rows
7427 // (totalHeight is a "recommended" value if isAuto)
7428 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
7429 this.setGridHeight(scrollerHeight
, isAuto
);
7430 // is the event limit dynamically calculated?
7431 if (eventLimit
&& typeof eventLimit
!== 'number') {
7432 this.dayGrid
.limitRows(eventLimit
); // limit the levels after the grid's row heights have been set
7435 this.scroller
.setHeight(scrollerHeight
);
7436 scrollbarWidths
= this.scroller
.getScrollbarWidths();
7437 if (scrollbarWidths
.left
|| scrollbarWidths
.right
) {
7438 util_1
.compensateScroll(headRowEl
, scrollbarWidths
);
7439 // doing the scrollbar compensation might have created text overflow which created more height. redo
7440 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
7441 this.scroller
.setHeight(scrollerHeight
);
7443 // guarantees the same scrollbar widths
7444 this.scroller
.lockOverflow(scrollbarWidths
);
7447 // given a desired total height of the view, returns what the height of the scroller should be
7448 BasicView
.prototype.computeScrollerHeight = function (totalHeight
) {
7449 return totalHeight
-
7450 util_1
.subtractInnerElHeight(this.el
, this.scroller
.el
); // everything that's NOT the scroller
7452 // Sets the height of just the DayGrid component in this view
7453 BasicView
.prototype.setGridHeight = function (height
, isAuto
) {
7455 util_1
.undistributeHeight(this.dayGrid
.rowEls
); // let the rows be their natural height with no expanding
7458 util_1
.distributeHeight(this.dayGrid
.rowEls
, height
, true); // true = compensate for height-hogging rows
7462 ------------------------------------------------------------------------------------------------------------------*/
7463 BasicView
.prototype.computeInitialDateScroll = function () {
7466 BasicView
.prototype.queryDateScroll = function () {
7467 return { top
: this.scroller
.getScrollTop() };
7469 BasicView
.prototype.applyDateScroll = function (scroll
) {
7470 if (scroll
.top
!== undefined) {
7471 this.scroller
.setScrollTop(scroll
.top
);
7476 exports
.default = BasicView
;
7477 BasicView
.prototype.dateProfileGeneratorClass
= BasicViewDateProfileGenerator_1
.default;
7478 BasicView
.prototype.dayGridClass
= DayGrid_1
.default;
7479 // customize the rendering behavior of BasicView's dayGrid
7480 function makeDayGridSubclass(SuperClass
) {
7481 return /** @class */ (function (_super
) {
7482 tslib_1
.__extends(SubClass
, _super
);
7483 function SubClass() {
7484 var _this
= _super
!== null && _super
.apply(this, arguments
) || this;
7485 _this
.colWeekNumbersVisible
= false; // display week numbers along the side?
7488 // Generates the HTML that will go before the day-of week header cells
7489 SubClass
.prototype.renderHeadIntroHtml = function () {
7490 var view
= this.view
;
7491 if (this.colWeekNumbersVisible
) {
7493 '<th class="fc-week-number ' + view
.calendar
.theme
.getClass('widgetHeader') + '" ' + view
.weekNumberStyleAttr() + '>' +
7494 '<span>' + // needed for matchCellWidths
7495 util_1
.htmlEscape(this.opt('weekNumberTitle')) +
7501 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
7502 SubClass
.prototype.renderNumberIntroHtml = function (row
) {
7503 var view
= this.view
;
7504 var weekStart
= this.getCellDate(row
, 0);
7505 if (this.colWeekNumbersVisible
) {
7507 '<td class="fc-week-number" ' + view
.weekNumberStyleAttr() + '>' +
7508 view
.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
7509 { date
: weekStart
, type
: 'week', forceOff
: this.colCnt
=== 1 }, weekStart
.format('w') // inner HTML
7515 // Generates the HTML that goes before the day bg cells for each day-row
7516 SubClass
.prototype.renderBgIntroHtml = function () {
7517 var view
= this.view
;
7518 if (this.colWeekNumbersVisible
) {
7519 return '<td class="fc-week-number ' + view
.calendar
.theme
.getClass('widgetContent') + '" ' +
7520 view
.weekNumberStyleAttr() + '></td>';
7524 // Generates the HTML that goes before every other type of row generated by DayGrid.
7525 // Affects helper-skeleton and highlight-skeleton rows.
7526 SubClass
.prototype.renderIntroHtml = function () {
7527 var view
= this.view
;
7528 if (this.colWeekNumbersVisible
) {
7529 return '<td class="fc-week-number" ' + view
.weekNumberStyleAttr() + '></td>';
7533 SubClass
.prototype.getIsNumbersVisible = function () {
7534 return DayGrid_1
.default.prototype.getIsNumbersVisible
.apply(this, arguments
) || this.colWeekNumbersVisible
;
7687 /***/ (function(module
, exports
, __webpack_require__
) {
7689 Object
.defineProperty(exports
, "__esModule", { value
: true });
7690 var UnzonedRange_1
= __webpack_require__(5);
7691 var ComponentFootprint_1
= __webpack_require__(12);
7692 var EventDefParser_1
= __webpack_require__(49);
7693 var EventSource_1
= __webpack_require__(6);
7694 var util_1
= __webpack_require__(35);
7695 var Constraints
= /** @class */ (function () {
7696 function Constraints(eventManager
, _calendar
) {
7697 this.eventManager
= eventManager
;
7698 this._calendar
= _calendar
;
7700 Constraints
.prototype.opt = function (name
) {
7701 return this._calendar
.opt(name
);
7704 determines if eventInstanceGroup is allowed,
7705 in relation to other EVENTS and business hours.
7707 Constraints
.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup
) {
7708 var eventDef
= eventInstanceGroup
.getEventDef();
7709 var eventFootprints
= this.eventRangesToEventFootprints(eventInstanceGroup
.getAllEventRanges());
7711 var peerEventInstances
= this.getPeerEventInstances(eventDef
);
7712 var peerEventRanges
= peerEventInstances
.map(util_1
.eventInstanceToEventRange
);
7713 var peerEventFootprints
= this.eventRangesToEventFootprints(peerEventRanges
);
7714 var constraintVal
= eventDef
.getConstraint();
7715 var overlapVal
= eventDef
.getOverlap();
7716 var eventAllowFunc
= this.opt('eventAllow');
7717 for (i
= 0; i
< eventFootprints
.length
; i
++) {
7718 if (!this.isFootprintAllowed(eventFootprints
[i
].componentFootprint
, peerEventFootprints
, constraintVal
, overlapVal
, eventFootprints
[i
].eventInstance
)) {
7722 if (eventAllowFunc
) {
7723 for (i
= 0; i
< eventFootprints
.length
; i
++) {
7724 if (eventAllowFunc(eventFootprints
[i
].componentFootprint
.toLegacy(this._calendar
), eventFootprints
[i
].getEventLegacy()) === false) {
7731 Constraints
.prototype.getPeerEventInstances = function (eventDef
) {
7732 return this.eventManager
.getEventInstancesWithoutId(eventDef
.id
);
7734 Constraints
.prototype.isSelectionFootprintAllowed = function (componentFootprint
) {
7735 var peerEventInstances
= this.eventManager
.getEventInstances();
7736 var peerEventRanges
= peerEventInstances
.map(util_1
.eventInstanceToEventRange
);
7737 var peerEventFootprints
= this.eventRangesToEventFootprints(peerEventRanges
);
7738 var selectAllowFunc
;
7739 if (this.isFootprintAllowed(componentFootprint
, peerEventFootprints
, this.opt('selectConstraint'), this.opt('selectOverlap'))) {
7740 selectAllowFunc
= this.opt('selectAllow');
7741 if (selectAllowFunc
) {
7742 return selectAllowFunc(componentFootprint
.toLegacy(this._calendar
)) !== false;
7750 Constraints
.prototype.isFootprintAllowed = function (componentFootprint
, peerEventFootprints
, constraintVal
, overlapVal
, subjectEventInstance
// optional
7752 var constraintFootprints
; // ComponentFootprint[]
7753 var overlapEventFootprints
; // EventFootprint[]
7754 if (constraintVal
!= null) {
7755 constraintFootprints
= this.constraintValToFootprints(constraintVal
, componentFootprint
.isAllDay
);
7756 if (!this.isFootprintWithinConstraints(componentFootprint
, constraintFootprints
)) {
7760 overlapEventFootprints
= this.collectOverlapEventFootprints(peerEventFootprints
, componentFootprint
);
7761 if (overlapVal
=== false) {
7762 if (overlapEventFootprints
.length
) {
7766 else if (typeof overlapVal
=== 'function') {
7767 if (!isOverlapsAllowedByFunc(overlapEventFootprints
, overlapVal
, subjectEventInstance
)) {
7771 if (subjectEventInstance
) {
7772 if (!isOverlapEventInstancesAllowed(overlapEventFootprints
, subjectEventInstance
)) {
7779 // ------------------------------------------------------------------------------------------------
7780 Constraints
.prototype.isFootprintWithinConstraints = function (componentFootprint
, constraintFootprints
) {
7782 for (i
= 0; i
< constraintFootprints
.length
; i
++) {
7783 if (this.footprintContainsFootprint(constraintFootprints
[i
], componentFootprint
)) {
7789 Constraints
.prototype.constraintValToFootprints = function (constraintVal
, isAllDay
) {
7791 if (constraintVal
=== 'businessHours') {
7792 return this.buildCurrentBusinessFootprints(isAllDay
);
7794 else if (typeof constraintVal
=== 'object') {
7795 eventInstances
= this.parseEventDefToInstances(constraintVal
); // handles recurring events
7796 if (!eventInstances
) {
7797 return this.parseFootprints(constraintVal
);
7800 return this.eventInstancesToFootprints(eventInstances
);
7803 else if (constraintVal
!= null) {
7804 eventInstances
= this.eventManager
.getEventInstancesWithId(constraintVal
);
7805 return this.eventInstancesToFootprints(eventInstances
);
7808 // returns ComponentFootprint[]
7809 // uses current view's range
7810 Constraints
.prototype.buildCurrentBusinessFootprints = function (isAllDay
) {
7811 var view
= this._calendar
.view
;
7812 var businessHourGenerator
= view
.get('businessHourGenerator');
7813 var unzonedRange
= view
.dateProfile
.activeUnzonedRange
;
7814 var eventInstanceGroup
= businessHourGenerator
.buildEventInstanceGroup(isAllDay
, unzonedRange
);
7815 if (eventInstanceGroup
) {
7816 return this.eventInstancesToFootprints(eventInstanceGroup
.eventInstances
);
7823 Constraints
.prototype.eventInstancesToFootprints = function (eventInstances
) {
7824 var eventRanges
= eventInstances
.map(util_1
.eventInstanceToEventRange
);
7825 var eventFootprints
= this.eventRangesToEventFootprints(eventRanges
);
7826 return eventFootprints
.map(util_1
.eventFootprintToComponentFootprint
);
7829 // ------------------------------------------------------------------------------------------------
7830 Constraints
.prototype.collectOverlapEventFootprints = function (peerEventFootprints
, targetFootprint
) {
7831 var overlapEventFootprints
= [];
7833 for (i
= 0; i
< peerEventFootprints
.length
; i
++) {
7834 if (this.footprintsIntersect(targetFootprint
, peerEventFootprints
[i
].componentFootprint
)) {
7835 overlapEventFootprints
.push(peerEventFootprints
[i
]);
7838 return overlapEventFootprints
;
7840 // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints
7841 // ------------------------------------------------------------------------------------------------
7842 // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to
7843 // constraints whereas the Grid code is related to rendering. Each approach might want to convert
7844 // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make
7847 Returns false on invalid input.
7849 Constraints
.prototype.parseEventDefToInstances = function (eventInput
) {
7850 var eventManager
= this.eventManager
;
7851 var eventDef
= EventDefParser_1
.default.parse(eventInput
, new EventSource_1
.default(this._calendar
));
7855 return eventDef
.buildInstances(eventManager
.currentPeriod
.unzonedRange
);
7857 Constraints
.prototype.eventRangesToEventFootprints = function (eventRanges
) {
7859 var eventFootprints
= [];
7860 for (i
= 0; i
< eventRanges
.length
; i
++) {
7861 eventFootprints
.push
.apply(// footprints
7862 eventFootprints
, this.eventRangeToEventFootprints(eventRanges
[i
]));
7864 return eventFootprints
;
7866 Constraints
.prototype.eventRangeToEventFootprints = function (eventRange
) {
7867 return [util_1
.eventRangeToEventFootprint(eventRange
)];
7870 Parses footprints directly.
7871 Very similar to EventDateProfile::parse :(
7873 Constraints
.prototype.parseFootprints = function (rawInput
) {
7876 if (rawInput
.start
) {
7877 start
= this._calendar
.moment(rawInput
.start
);
7878 if (!start
.isValid()) {
7883 end
= this._calendar
.moment(rawInput
.end
);
7884 if (!end
.isValid()) {
7889 new ComponentFootprint_1
.default(new UnzonedRange_1
.default(start
, end
), (start
&& !start
.hasTime()) || (end
&& !end
.hasTime()) // isAllDay
7894 // ----------------------------------------------------------------------------------------
7895 Constraints
.prototype.footprintContainsFootprint = function (outerFootprint
, innerFootprint
) {
7896 return outerFootprint
.unzonedRange
.containsRange(innerFootprint
.unzonedRange
);
7898 Constraints
.prototype.footprintsIntersect = function (footprint0
, footprint1
) {
7899 return footprint0
.unzonedRange
.intersectsWith(footprint1
.unzonedRange
);
7903 exports
.default = Constraints
;
7904 // optional subjectEventInstance
7905 function isOverlapsAllowedByFunc(overlapEventFootprints
, overlapFunc
, subjectEventInstance
) {
7907 for (i
= 0; i
< overlapEventFootprints
.length
; i
++) {
7908 if (!overlapFunc(overlapEventFootprints
[i
].eventInstance
.toLegacy(), subjectEventInstance
? subjectEventInstance
.toLegacy() : null)) {
7914 function isOverlapEventInstancesAllowed(overlapEventFootprints
, subjectEventInstance
) {
7915 var subjectLegacyInstance
= subjectEventInstance
.toLegacy();
7917 var overlapEventInstance
;
7918 var overlapEventDef
;
7920 for (i
= 0; i
< overlapEventFootprints
.length
; i
++) {
7921 overlapEventInstance
= overlapEventFootprints
[i
].eventInstance
;
7922 overlapEventDef
= overlapEventInstance
.def
;
7923 // don't need to pass in calendar, because don't want to consider global eventOverlap property,
7924 // because we already considered that earlier in the process.
7925 overlapVal
= overlapEventDef
.getOverlap();
7926 if (overlapVal
=== false) {
7929 else if (typeof overlapVal
=== 'function') {
7930 if (!overlapVal(overlapEventInstance
.toLegacy(), subjectLegacyInstance
)) {
7941 /***/ (function(module
, exports
, __webpack_require__
) {
7945 import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin'
7947 applyProps: ParsableModelInterface['applyProps']
7948 applyManualStandardProps: ParsableModelInterface['applyManualStandardProps']
7949 applyMiscProps: ParsableModelInterface['applyMiscProps']
7950 isStandardProp: ParsableModelInterface['isStandardProp']
7951 static defineStandardProps = ParsableModelMixin.defineStandardProps
7952 static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps
7954 ParsableModelMixin.mixInto(TheClass)
7956 Object
.defineProperty(exports
, "__esModule", { value
: true });
7957 var tslib_1
= __webpack_require__(2);
7958 var util_1
= __webpack_require__(4);
7959 var Mixin_1
= __webpack_require__(14);
7960 var ParsableModelMixin
= /** @class */ (function (_super
) {
7961 tslib_1
.__extends(ParsableModelMixin
, _super
);
7962 function ParsableModelMixin() {
7963 return _super
!== null && _super
.apply(this, arguments
) || this;
7965 ParsableModelMixin
.defineStandardProps = function (propDefs
) {
7966 var proto
= this.prototype;
7967 if (!proto
.hasOwnProperty('standardPropMap')) {
7968 proto
.standardPropMap
= Object
.create(proto
.standardPropMap
);
7970 util_1
.copyOwnProps(propDefs
, proto
.standardPropMap
);
7972 ParsableModelMixin
.copyVerbatimStandardProps = function (src
, dest
) {
7973 var map
= this.prototype.standardPropMap
;
7975 for (propName
in map
) {
7976 if (src
[propName
] != null && // in the src object?
7977 map
[propName
] === true // false means "copy verbatim"
7979 dest
[propName
] = src
[propName
];
7984 Returns true/false for success.
7985 Meant to be only called ONCE, at object creation.
7987 ParsableModelMixin
.prototype.applyProps = function (rawProps
) {
7988 var standardPropMap
= this.standardPropMap
;
7989 var manualProps
= {};
7992 for (propName
in rawProps
) {
7993 if (standardPropMap
[propName
] === true) {
7994 this[propName
] = rawProps
[propName
];
7996 else if (standardPropMap
[propName
] === false) {
7997 manualProps
[propName
] = rawProps
[propName
];
8000 miscProps
[propName
] = rawProps
[propName
];
8003 this.applyMiscProps(miscProps
);
8004 return this.applyManualStandardProps(manualProps
);
8007 If subclasses override, they must call this supermethod and return the boolean response.
8008 Meant to be only called ONCE, at object creation.
8010 ParsableModelMixin
.prototype.applyManualStandardProps = function (rawProps
) {
8014 Can be called even after initial object creation.
8016 ParsableModelMixin
.prototype.applyMiscProps = function (rawProps
) {
8017 // subclasses can implement
8020 TODO: why is this a method when defineStandardProps is static
8022 ParsableModelMixin
.prototype.isStandardProp = function (propName
) {
8023 return propName
in this.standardPropMap
;
8025 return ParsableModelMixin
;
8026 }(Mixin_1
.default));
8027 exports
.default = ParsableModelMixin
;
8028 ParsableModelMixin
.prototype.standardPropMap
= {}; // will be cloned by defineStandardProps
8033 /***/ (function(module
, exports
) {
8035 Object
.defineProperty(exports
, "__esModule", { value
: true });
8036 var EventInstance
= /** @class */ (function () {
8037 function EventInstance(def
, dateProfile
) {
8039 this.dateProfile
= dateProfile
;
8041 EventInstance
.prototype.toLegacy = function () {
8042 var dateProfile
= this.dateProfile
;
8043 var obj
= this.def
.toLegacy();
8044 obj
.start
= dateProfile
.start
.clone();
8045 obj
.end
= dateProfile
.end
? dateProfile
.end
.clone() : null;
8048 return EventInstance
;
8050 exports
.default = EventInstance
;
8055 /***/ (function(module
, exports
, __webpack_require__
) {
8057 Object
.defineProperty(exports
, "__esModule", { value
: true });
8058 var tslib_1
= __webpack_require__(2);
8059 var $ = __webpack_require__(3);
8060 var moment
= __webpack_require__(0);
8061 var EventDef_1
= __webpack_require__(34);
8062 var EventInstance_1
= __webpack_require__(209);
8063 var EventDateProfile_1
= __webpack_require__(17);
8064 var RecurringEventDef
= /** @class */ (function (_super
) {
8065 tslib_1
.__extends(RecurringEventDef
, _super
);
8066 function RecurringEventDef() {
8067 return _super
!== null && _super
.apply(this, arguments
) || this;
8069 RecurringEventDef
.prototype.isAllDay = function () {
8070 return !this.startTime
&& !this.endTime
;
8072 RecurringEventDef
.prototype.buildInstances = function (unzonedRange
) {
8073 var calendar
= this.source
.calendar
;
8074 var unzonedDate
= unzonedRange
.getStart();
8075 var unzonedEnd
= unzonedRange
.getEnd();
8080 while (unzonedDate
.isBefore(unzonedEnd
)) {
8081 // if everyday, or this particular day-of-week
8082 if (!this.dowHash
|| this.dowHash
[unzonedDate
.day()]) {
8083 zonedDayStart
= calendar
.applyTimezone(unzonedDate
);
8084 instanceStart
= zonedDayStart
.clone();
8086 if (this.startTime
) {
8087 instanceStart
.time(this.startTime
);
8090 instanceStart
.stripTime();
8093 instanceEnd
= zonedDayStart
.clone().time(this.endTime
);
8095 instances
.push(new EventInstance_1
.default(this, // definition
8096 new EventDateProfile_1
.default(instanceStart
, instanceEnd
, calendar
)));
8098 unzonedDate
.add(1, 'days');
8102 RecurringEventDef
.prototype.setDow = function (dowNumbers
) {
8103 if (!this.dowHash
) {
8106 for (var i
= 0; i
< dowNumbers
.length
; i
++) {
8107 this.dowHash
[dowNumbers
[i
]] = true;
8110 RecurringEventDef
.prototype.clone = function () {
8111 var def
= _super
.prototype.clone
.call(this);
8112 if (def
.startTime
) {
8113 def
.startTime
= moment
.duration(this.startTime
);
8116 def
.endTime
= moment
.duration(this.endTime
);
8119 def
.dowHash
= $.extend({}, this.dowHash
);
8123 return RecurringEventDef
;
8124 }(EventDef_1
.default));
8125 exports
.default = RecurringEventDef
;
8127 HACK to work with TypeScript mixins
8128 NOTE: if super-method fails, should still attempt to apply
8130 RecurringEventDef
.prototype.applyProps = function (rawProps
) {
8131 var superSuccess
= EventDef_1
.default.prototype.applyProps
.call(this, rawProps
);
8132 if (rawProps
.start
) {
8133 this.startTime
= moment
.duration(rawProps
.start
);
8136 this.endTime
= moment
.duration(rawProps
.end
);
8139 this.setDow(rawProps
.dow
);
8141 return superSuccess
;
8144 // ---------------------------------------------------------------------------------------------------------------------
8145 RecurringEventDef
.defineStandardProps({
8154 /***/ (function(module
, exports
) {
8156 Object
.defineProperty(exports
, "__esModule", { value
: true });
8157 var EventRange
= /** @class */ (function () {
8158 function EventRange(unzonedRange
, eventDef
, eventInstance
) {
8159 this.unzonedRange
= unzonedRange
;
8160 this.eventDef
= eventDef
;
8161 if (eventInstance
) {
8162 this.eventInstance
= eventInstance
;
8167 exports
.default = EventRange
;
8172 /***/ (function(module
, exports
, __webpack_require__
) {
8174 Object
.defineProperty(exports
, "__esModule", { value
: true });
8175 var $ = __webpack_require__(3);
8176 var util_1
= __webpack_require__(35);
8177 var EventInstanceGroup_1
= __webpack_require__(18);
8178 var RecurringEventDef_1
= __webpack_require__(210);
8179 var EventSource_1
= __webpack_require__(6);
8180 var BUSINESS_HOUR_EVENT_DEFAULTS
= {
8183 dow
: [1, 2, 3, 4, 5],
8184 rendering
: 'inverse-background'
8185 // classNames are defined in businessHoursSegClasses
8187 var BusinessHourGenerator
= /** @class */ (function () {
8188 function BusinessHourGenerator(rawComplexDef
, calendar
) {
8189 this.rawComplexDef
= rawComplexDef
;
8190 this.calendar
= calendar
;
8192 BusinessHourGenerator
.prototype.buildEventInstanceGroup = function (isAllDay
, unzonedRange
) {
8193 var eventDefs
= this.buildEventDefs(isAllDay
);
8194 var eventInstanceGroup
;
8195 if (eventDefs
.length
) {
8196 eventInstanceGroup
= new EventInstanceGroup_1
.default(util_1
.eventDefsToEventInstances(eventDefs
, unzonedRange
));
8197 // so that inverse-background rendering can happen even when no eventRanges in view
8198 eventInstanceGroup
.explicitEventDef
= eventDefs
[0];
8199 return eventInstanceGroup
;
8202 BusinessHourGenerator
.prototype.buildEventDefs = function (isAllDay
) {
8203 var rawComplexDef
= this.rawComplexDef
;
8205 var requireDow
= false;
8208 if (rawComplexDef
=== true) {
8209 rawDefs
= [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
8211 else if ($.isPlainObject(rawComplexDef
)) {
8212 rawDefs
= [rawComplexDef
];
8214 else if ($.isArray(rawComplexDef
)) {
8215 rawDefs
= rawComplexDef
;
8216 requireDow
= true; // every sub-definition NEEDS a day-of-week
8218 for (i
= 0; i
< rawDefs
.length
; i
++) {
8219 if (!requireDow
|| rawDefs
[i
].dow
) {
8220 defs
.push(this.buildEventDef(isAllDay
, rawDefs
[i
]));
8225 BusinessHourGenerator
.prototype.buildEventDef = function (isAllDay
, rawDef
) {
8226 var fullRawDef
= $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS
, rawDef
);
8228 fullRawDef
.start
= null;
8229 fullRawDef
.end
= null;
8231 return RecurringEventDef_1
.default.parse(fullRawDef
, new EventSource_1
.default(this.calendar
) // dummy source
8234 return BusinessHourGenerator
;
8236 exports
.default = BusinessHourGenerator
;
8241 /***/ (function(module
, exports
, __webpack_require__
) {
8243 Object
.defineProperty(exports
, "__esModule", { value
: true });
8244 var tslib_1
= __webpack_require__(2);
8245 var Theme_1
= __webpack_require__(19);
8246 var StandardTheme
= /** @class */ (function (_super
) {
8247 tslib_1
.__extends(StandardTheme
, _super
);
8248 function StandardTheme() {
8249 return _super
!== null && _super
.apply(this, arguments
) || this;
8251 return StandardTheme
;
8252 }(Theme_1
.default));
8253 exports
.default = StandardTheme
;
8254 StandardTheme
.prototype.classes
= {
8255 widget
: 'fc-unthemed',
8256 widgetHeader
: 'fc-widget-header',
8257 widgetContent
: 'fc-widget-content',
8258 buttonGroup
: 'fc-button-group',
8259 button
: 'fc-button',
8260 cornerLeft
: 'fc-corner-left',
8261 cornerRight
: 'fc-corner-right',
8262 stateDefault
: 'fc-state-default',
8263 stateActive
: 'fc-state-active',
8264 stateDisabled
: 'fc-state-disabled',
8265 stateHover
: 'fc-state-hover',
8266 stateDown
: 'fc-state-down',
8267 popoverHeader
: 'fc-widget-header',
8268 popoverContent
: 'fc-widget-content',
8270 headerRow
: 'fc-widget-header',
8271 dayRow
: 'fc-widget-content',
8273 listView
: 'fc-widget-content'
8275 StandardTheme
.prototype.baseIconClass
= 'fc-icon';
8276 StandardTheme
.prototype.iconClasses
= {
8278 prev
: 'fc-icon-left-single-arrow',
8279 next
: 'fc-icon-right-single-arrow',
8280 prevYear
: 'fc-icon-left-double-arrow',
8281 nextYear
: 'fc-icon-right-double-arrow'
8283 StandardTheme
.prototype.iconOverrideOption
= 'buttonIcons';
8284 StandardTheme
.prototype.iconOverrideCustomButtonOption
= 'icon';
8285 StandardTheme
.prototype.iconOverridePrefix
= 'fc-icon-';
8290 /***/ (function(module
, exports
, __webpack_require__
) {
8292 Object
.defineProperty(exports
, "__esModule", { value
: true });
8293 var tslib_1
= __webpack_require__(2);
8294 var Theme_1
= __webpack_require__(19);
8295 var JqueryUiTheme
= /** @class */ (function (_super
) {
8296 tslib_1
.__extends(JqueryUiTheme
, _super
);
8297 function JqueryUiTheme() {
8298 return _super
!== null && _super
.apply(this, arguments
) || this;
8300 return JqueryUiTheme
;
8301 }(Theme_1
.default));
8302 exports
.default = JqueryUiTheme
;
8303 JqueryUiTheme
.prototype.classes
= {
8304 widget
: 'ui-widget',
8305 widgetHeader
: 'ui-widget-header',
8306 widgetContent
: 'ui-widget-content',
8307 buttonGroup
: 'fc-button-group',
8308 button
: 'ui-button',
8309 cornerLeft
: 'ui-corner-left',
8310 cornerRight
: 'ui-corner-right',
8311 stateDefault
: 'ui-state-default',
8312 stateActive
: 'ui-state-active',
8313 stateDisabled
: 'ui-state-disabled',
8314 stateHover
: 'ui-state-hover',
8315 stateDown
: 'ui-state-down',
8316 today
: 'ui-state-highlight',
8317 popoverHeader
: 'ui-widget-header',
8318 popoverContent
: 'ui-widget-content',
8320 headerRow
: 'ui-widget-header',
8321 dayRow
: 'ui-widget-content',
8323 listView
: 'ui-widget-content'
8325 JqueryUiTheme
.prototype.baseIconClass
= 'ui-icon';
8326 JqueryUiTheme
.prototype.iconClasses
= {
8327 close
: 'ui-icon-closethick',
8328 prev
: 'ui-icon-circle-triangle-w',
8329 next
: 'ui-icon-circle-triangle-e',
8330 prevYear
: 'ui-icon-seek-prev',
8331 nextYear
: 'ui-icon-seek-next'
8333 JqueryUiTheme
.prototype.iconOverrideOption
= 'themeButtonIcons';
8334 JqueryUiTheme
.prototype.iconOverrideCustomButtonOption
= 'themeIcon';
8335 JqueryUiTheme
.prototype.iconOverridePrefix
= 'ui-icon-';
8340 /***/ (function(module
, exports
, __webpack_require__
) {
8342 Object
.defineProperty(exports
, "__esModule", { value
: true });
8343 var tslib_1
= __webpack_require__(2);
8344 var $ = __webpack_require__(3);
8345 var Promise_1
= __webpack_require__(20);
8346 var EventSource_1
= __webpack_require__(6);
8347 var FuncEventSource
= /** @class */ (function (_super
) {
8348 tslib_1
.__extends(FuncEventSource
, _super
);
8349 function FuncEventSource() {
8350 return _super
!== null && _super
.apply(this, arguments
) || this;
8352 FuncEventSource
.parse = function (rawInput
, calendar
) {
8354 // normalize raw input
8355 if ($.isFunction(rawInput
.events
)) {
8356 rawProps
= rawInput
;
8358 else if ($.isFunction(rawInput
)) {
8359 rawProps
= { events
: rawInput
};
8362 return EventSource_1
.default.parse
.call(this, rawProps
, calendar
);
8366 FuncEventSource
.prototype.fetch = function (start
, end
, timezone
) {
8368 this.calendar
.pushLoading();
8369 return Promise_1
.default.construct(function (onResolve
) {
8370 _this
.func
.call(_this
.calendar
, start
.clone(), end
.clone(), timezone
, function (rawEventDefs
) {
8371 _this
.calendar
.popLoading();
8372 onResolve(_this
.parseEventDefs(rawEventDefs
));
8376 FuncEventSource
.prototype.getPrimitive = function () {
8379 FuncEventSource
.prototype.applyManualStandardProps = function (rawProps
) {
8380 var superSuccess
= _super
.prototype.applyManualStandardProps
.call(this, rawProps
);
8381 this.func
= rawProps
.events
;
8382 return superSuccess
;
8384 return FuncEventSource
;
8385 }(EventSource_1
.default));
8386 exports
.default = FuncEventSource
;
8387 FuncEventSource
.defineStandardProps({
8388 events
: false // don't automatically transfer
8394 /***/ (function(module
, exports
, __webpack_require__
) {
8396 Object
.defineProperty(exports
, "__esModule", { value
: true });
8397 var tslib_1
= __webpack_require__(2);
8398 var $ = __webpack_require__(3);
8399 var util_1
= __webpack_require__(4);
8400 var Promise_1
= __webpack_require__(20);
8401 var EventSource_1
= __webpack_require__(6);
8402 var JsonFeedEventSource
= /** @class */ (function (_super
) {
8403 tslib_1
.__extends(JsonFeedEventSource
, _super
);
8404 function JsonFeedEventSource() {
8405 return _super
!== null && _super
.apply(this, arguments
) || this;
8407 JsonFeedEventSource
.parse = function (rawInput
, calendar
) {
8409 // normalize raw input
8410 if (typeof rawInput
.url
=== 'string') {
8411 rawProps
= rawInput
;
8413 else if (typeof rawInput
=== 'string') {
8414 rawProps
= { url
: rawInput
};
8417 return EventSource_1
.default.parse
.call(this, rawProps
, calendar
);
8421 JsonFeedEventSource
.prototype.fetch = function (start
, end
, timezone
) {
8423 var ajaxSettings
= this.ajaxSettings
;
8424 var onSuccess
= ajaxSettings
.success
;
8425 var onError
= ajaxSettings
.error
;
8426 var requestParams
= this.buildRequestParams(start
, end
, timezone
);
8427 // todo: eventually handle the promise's then,
8428 // don't intercept success/error
8429 // tho will be a breaking API change
8430 this.calendar
.pushLoading();
8431 return Promise_1
.default.construct(function (onResolve
, onReject
) {
8432 $.ajax($.extend({}, // destination
8433 JsonFeedEventSource
.AJAX_DEFAULTS
, ajaxSettings
, {
8435 data
: requestParams
,
8436 success: function (rawEventDefs
, status
, xhr
) {
8438 _this
.calendar
.popLoading();
8440 callbackRes
= util_1
.applyAll(onSuccess
, _this
, [rawEventDefs
, status
, xhr
]); // redirect `this`
8441 if ($.isArray(callbackRes
)) {
8442 rawEventDefs
= callbackRes
;
8444 onResolve(_this
.parseEventDefs(rawEventDefs
));
8450 error: function (xhr
, statusText
, errorThrown
) {
8451 _this
.calendar
.popLoading();
8452 util_1
.applyAll(onError
, _this
, [xhr
, statusText
, errorThrown
]); // redirect `this`
8458 JsonFeedEventSource
.prototype.buildRequestParams = function (start
, end
, timezone
) {
8459 var calendar
= this.calendar
;
8460 var ajaxSettings
= this.ajaxSettings
;
8464 var customRequestParams
;
8466 startParam
= this.startParam
;
8467 if (startParam
== null) {
8468 startParam
= calendar
.opt('startParam');
8470 endParam
= this.endParam
;
8471 if (endParam
== null) {
8472 endParam
= calendar
.opt('endParam');
8474 timezoneParam
= this.timezoneParam
;
8475 if (timezoneParam
== null) {
8476 timezoneParam
= calendar
.opt('timezoneParam');
8478 // retrieve any outbound GET/POST $.ajax data from the options
8479 if ($.isFunction(ajaxSettings
.data
)) {
8480 // supplied as a function that returns a key/value object
8481 customRequestParams
= ajaxSettings
.data();
8484 // probably supplied as a straight key/value object
8485 customRequestParams
= ajaxSettings
.data
|| {};
8487 $.extend(params
, customRequestParams
);
8488 params
[startParam
] = start
.format();
8489 params
[endParam
] = end
.format();
8490 if (timezone
&& timezone
!== 'local') {
8491 params
[timezoneParam
] = timezone
;
8495 JsonFeedEventSource
.prototype.getPrimitive = function () {
8498 JsonFeedEventSource
.prototype.applyMiscProps = function (rawProps
) {
8499 this.ajaxSettings
= rawProps
;
8501 JsonFeedEventSource
.AJAX_DEFAULTS
= {
8505 return JsonFeedEventSource
;
8506 }(EventSource_1
.default));
8507 exports
.default = JsonFeedEventSource
;
8508 JsonFeedEventSource
.defineStandardProps({
8509 // automatically transfer (true)...
8519 /***/ (function(module
, exports
, __webpack_require__
) {
8521 Object
.defineProperty(exports
, "__esModule", { value
: true });
8522 var EmitterMixin_1
= __webpack_require__(11);
8523 var TaskQueue
= /** @class */ (function () {
8524 function TaskQueue() {
8526 this.isPaused
= false;
8527 this.isRunning
= false;
8529 TaskQueue
.prototype.queue = function () {
8531 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
8532 args
[_i
] = arguments
[_i
];
8534 this.q
.push
.apply(this.q
, args
); // append
8537 TaskQueue
.prototype.pause = function () {
8538 this.isPaused
= true;
8540 TaskQueue
.prototype.resume = function () {
8541 this.isPaused
= false;
8544 TaskQueue
.prototype.getIsIdle = function () {
8545 return !this.isRunning
&& !this.isPaused
;
8547 TaskQueue
.prototype.tryStart = function () {
8548 if (!this.isRunning
&& this.canRunNext()) {
8549 this.isRunning
= true;
8550 this.trigger('start');
8551 this.runRemaining();
8554 TaskQueue
.prototype.canRunNext = function () {
8555 return !this.isPaused
&& this.q
.length
;
8557 TaskQueue
.prototype.runRemaining = function () {
8562 task
= this.q
.shift(); // always freshly reference q. might have been reassigned.
8563 res
= this.runTask(task
);
8564 if (res
&& res
.then
) {
8565 res
.then(function () {
8566 if (_this
.canRunNext()) {
8567 _this
.runRemaining();
8570 return; // prevent marking as stopped
8572 } while (this.canRunNext());
8573 this.trigger('stop'); // not really a 'stop' ... more of a 'drained'
8574 this.isRunning
= false;
8575 // if 'stop' handler added more tasks.... TODO: write test for this
8578 TaskQueue
.prototype.runTask = function (task
) {
8579 return task(); // task *is* the function, but subclasses can change the format of a task
8583 exports
.default = TaskQueue
;
8584 EmitterMixin_1
.default.mixInto(TaskQueue
);
8589 /***/ (function(module
, exports
, __webpack_require__
) {
8591 Object
.defineProperty(exports
, "__esModule", { value
: true });
8592 var tslib_1
= __webpack_require__(2);
8593 var TaskQueue_1
= __webpack_require__(217);
8594 var RenderQueue
= /** @class */ (function (_super
) {
8595 tslib_1
.__extends(RenderQueue
, _super
);
8596 function RenderQueue(waitsByNamespace
) {
8597 var _this
= _super
.call(this) || this;
8598 _this
.waitsByNamespace
= waitsByNamespace
|| {};
8601 RenderQueue
.prototype.queue = function (taskFunc
, namespace, type
) {
8604 namespace: namespace,
8609 waitMs
= this.waitsByNamespace
[namespace];
8611 if (this.waitNamespace
) {
8612 if (namespace === this.waitNamespace
&& waitMs
!= null) {
8613 this.delayWait(waitMs
);
8620 if (this.compoundTask(task
)) {
8621 if (!this.waitNamespace
&& waitMs
!= null) {
8622 this.startWait(namespace, waitMs
);
8629 RenderQueue
.prototype.startWait = function (namespace, waitMs
) {
8630 this.waitNamespace
= namespace;
8631 this.spawnWait(waitMs
);
8633 RenderQueue
.prototype.delayWait = function (waitMs
) {
8634 clearTimeout(this.waitId
);
8635 this.spawnWait(waitMs
);
8637 RenderQueue
.prototype.spawnWait = function (waitMs
) {
8639 this.waitId
= setTimeout(function () {
8640 _this
.waitNamespace
= null;
8644 RenderQueue
.prototype.clearWait = function () {
8645 if (this.waitNamespace
) {
8646 clearTimeout(this.waitId
);
8648 this.waitNamespace
= null;
8651 RenderQueue
.prototype.canRunNext = function () {
8652 if (!_super
.prototype.canRunNext
.call(this)) {
8655 // waiting for a certain namespace to stop receiving tasks?
8656 if (this.waitNamespace
) {
8658 // if there was a different namespace task in the meantime,
8659 // that forces all previously-waiting tasks to suddenly execute.
8660 // TODO: find a way to do this in constant time.
8661 for (var i
= 0; i
< q
.length
; i
++) {
8662 if (q
[i
].namespace !== this.waitNamespace
) {
8663 return true; // allow execution
8670 RenderQueue
.prototype.runTask = function (task
) {
8673 RenderQueue
.prototype.compoundTask = function (newTask
) {
8675 var shouldAppend
= true;
8678 if (newTask
.namespace && newTask
.type
=== 'destroy') {
8679 // remove all init/add/remove ops with same namespace, regardless of order
8680 for (i
= q
.length
- 1; i
>= 0; i
--) {
8682 switch (task
.type
) {
8684 shouldAppend
= false;
8685 // the latest destroy is cancelled out by not doing the init
8690 q
.splice(i
, 1); // remove task
8697 return shouldAppend
;
8700 }(TaskQueue_1
.default));
8701 exports
.default = RenderQueue
;
8706 /***/ (function(module
, exports
, __webpack_require__
) {
8708 Object
.defineProperty(exports
, "__esModule", { value
: true });
8709 var tslib_1
= __webpack_require__(2);
8710 var $ = __webpack_require__(3);
8711 var moment
= __webpack_require__(0);
8712 var util_1
= __webpack_require__(4);
8713 var moment_ext_1
= __webpack_require__(10);
8714 var date_formatting_1
= __webpack_require__(47);
8715 var Component_1
= __webpack_require__(237);
8716 var util_2
= __webpack_require__(35);
8717 var DateComponent
= /** @class */ (function (_super
) {
8718 tslib_1
.__extends(DateComponent
, _super
);
8719 function DateComponent(_view
, _options
) {
8720 var _this
= _super
.call(this) || this;
8721 _this
.isRTL
= false; // frequently accessed options
8722 _this
.hitsNeededDepth
= 0; // necessary because multiple callers might need the same hits
8723 _this
.hasAllDayBusinessHours
= false; // TODO: unify with largeUnit and isTimeScale?
8724 _this
.isDatesRendered
= false;
8725 // hack to set options prior to the this.opt calls
8727 _this
['view'] = _view
;
8730 _this
['options'] = _options
;
8732 _this
.uid
= String(DateComponent
.guid
++);
8733 _this
.childrenByUid
= {};
8734 _this
.nextDayThreshold
= moment
.duration(_this
.opt('nextDayThreshold'));
8735 _this
.isRTL
= _this
.opt('isRTL');
8736 if (_this
.fillRendererClass
) {
8737 _this
.fillRenderer
= new _this
.fillRendererClass(_this
);
8739 if (_this
.eventRendererClass
) {
8740 _this
.eventRenderer
= new _this
.eventRendererClass(_this
, _this
.fillRenderer
);
8742 if (_this
.helperRendererClass
&& _this
.eventRenderer
) {
8743 _this
.helperRenderer
= new _this
.helperRendererClass(_this
, _this
.eventRenderer
);
8745 if (_this
.businessHourRendererClass
&& _this
.fillRenderer
) {
8746 _this
.businessHourRenderer
= new _this
.businessHourRendererClass(_this
, _this
.fillRenderer
);
8750 DateComponent
.prototype.addChild = function (child
) {
8751 if (!this.childrenByUid
[child
.uid
]) {
8752 this.childrenByUid
[child
.uid
] = child
;
8757 DateComponent
.prototype.removeChild = function (child
) {
8758 if (this.childrenByUid
[child
.uid
]) {
8759 delete this.childrenByUid
[child
.uid
];
8764 // TODO: only do if isInDom?
8765 // TODO: make part of Component, along with children/batch-render system?
8766 DateComponent
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
8767 this.callChildren('updateSize', arguments
);
8770 // -----------------------------------------------------------------------------------------------------------------
8771 DateComponent
.prototype.opt = function (name
) {
8772 return this._getView().opt(name
); // default implementation
8774 DateComponent
.prototype.publiclyTrigger = function () {
8776 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
8777 args
[_i
] = arguments
[_i
];
8779 var calendar
= this._getCalendar();
8780 return calendar
.publiclyTrigger
.apply(calendar
, args
);
8782 DateComponent
.prototype.hasPublicHandlers = function () {
8784 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
8785 args
[_i
] = arguments
[_i
];
8787 var calendar
= this._getCalendar();
8788 return calendar
.hasPublicHandlers
.apply(calendar
, args
);
8791 // -----------------------------------------------------------------------------------------------------------------
8792 DateComponent
.prototype.executeDateRender = function (dateProfile
) {
8793 this.dateProfile
= dateProfile
; // for rendering
8794 this.renderDates(dateProfile
);
8795 this.isDatesRendered
= true;
8796 this.callChildren('executeDateRender', arguments
);
8798 DateComponent
.prototype.executeDateUnrender = function () {
8799 this.callChildren('executeDateUnrender', arguments
);
8800 this.dateProfile
= null;
8801 this.unrenderDates();
8802 this.isDatesRendered
= false;
8804 // date-cell content only
8805 DateComponent
.prototype.renderDates = function (dateProfile
) {
8806 // subclasses should implement
8808 // date-cell content only
8809 DateComponent
.prototype.unrenderDates = function () {
8810 // subclasses should override
8813 // -----------------------------------------------------------------------------------------------------------------
8814 // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator
8815 // should be refreshed. If something falsy is returned, no time indicator is rendered at all.
8816 DateComponent
.prototype.getNowIndicatorUnit = function () {
8817 // subclasses should implement
8819 // Renders a current time indicator at the given datetime
8820 DateComponent
.prototype.renderNowIndicator = function (date
) {
8821 this.callChildren('renderNowIndicator', arguments
);
8823 // Undoes the rendering actions from renderNowIndicator
8824 DateComponent
.prototype.unrenderNowIndicator = function () {
8825 this.callChildren('unrenderNowIndicator', arguments
);
8828 // ---------------------------------------------------------------------------------------------------------------
8829 DateComponent
.prototype.renderBusinessHours = function (businessHourGenerator
) {
8830 if (this.businessHourRenderer
) {
8831 this.businessHourRenderer
.render(businessHourGenerator
);
8833 this.callChildren('renderBusinessHours', arguments
);
8835 // Unrenders previously-rendered business-hours
8836 DateComponent
.prototype.unrenderBusinessHours = function () {
8837 this.callChildren('unrenderBusinessHours', arguments
);
8838 if (this.businessHourRenderer
) {
8839 this.businessHourRenderer
.unrender();
8843 // -----------------------------------------------------------------------------------------------------------------
8844 DateComponent
.prototype.executeEventRender = function (eventsPayload
) {
8845 if (this.eventRenderer
) {
8846 this.eventRenderer
.rangeUpdated(); // poorly named now
8847 this.eventRenderer
.render(eventsPayload
);
8849 else if (this['renderEvents']) {
8850 this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload
));
8852 this.callChildren('executeEventRender', arguments
);
8854 DateComponent
.prototype.executeEventUnrender = function () {
8855 this.callChildren('executeEventUnrender', arguments
);
8856 if (this.eventRenderer
) {
8857 this.eventRenderer
.unrender();
8859 else if (this['destroyEvents']) {
8860 this['destroyEvents']();
8863 DateComponent
.prototype.getBusinessHourSegs = function () {
8864 var segs
= this.getOwnBusinessHourSegs();
8865 this.iterChildren(function (child
) {
8866 segs
.push
.apply(segs
, child
.getBusinessHourSegs());
8870 DateComponent
.prototype.getOwnBusinessHourSegs = function () {
8871 if (this.businessHourRenderer
) {
8872 return this.businessHourRenderer
.getSegs();
8876 DateComponent
.prototype.getEventSegs = function () {
8877 var segs
= this.getOwnEventSegs();
8878 this.iterChildren(function (child
) {
8879 segs
.push
.apply(segs
, child
.getEventSegs());
8883 DateComponent
.prototype.getOwnEventSegs = function () {
8884 if (this.eventRenderer
) {
8885 return this.eventRenderer
.getSegs();
8889 // Event Rendering Triggering
8890 // -----------------------------------------------------------------------------------------------------------------
8891 DateComponent
.prototype.triggerAfterEventsRendered = function () {
8892 this.triggerAfterEventSegsRendered(this.getEventSegs());
8893 this.publiclyTrigger('eventAfterAllRender', {
8898 DateComponent
.prototype.triggerAfterEventSegsRendered = function (segs
) {
8900 // an optimization, because getEventLegacy is expensive
8901 if (this.hasPublicHandlers('eventAfterRender')) {
8902 segs
.forEach(function (seg
) {
8905 legacy
= seg
.footprint
.getEventLegacy();
8906 _this
.publiclyTrigger('eventAfterRender', {
8908 args
: [legacy
, seg
.el
, _this
]
8914 DateComponent
.prototype.triggerBeforeEventsDestroyed = function () {
8915 this.triggerBeforeEventSegsDestroyed(this.getEventSegs());
8917 DateComponent
.prototype.triggerBeforeEventSegsDestroyed = function (segs
) {
8919 if (this.hasPublicHandlers('eventDestroy')) {
8920 segs
.forEach(function (seg
) {
8923 legacy
= seg
.footprint
.getEventLegacy();
8924 _this
.publiclyTrigger('eventDestroy', {
8926 args
: [legacy
, seg
.el
, _this
]
8932 // Event Rendering Utils
8933 // -----------------------------------------------------------------------------------------------------------------
8934 // Hides all rendered event segments linked to the given event
8935 // RECURSIVE with subcomponents
8936 DateComponent
.prototype.showEventsWithId = function (eventDefId
) {
8937 this.getEventSegs().forEach(function (seg
) {
8938 if (seg
.footprint
.eventDef
.id
=== eventDefId
&&
8939 seg
.el
// necessary?
8941 seg
.el
.css('visibility', '');
8944 this.callChildren('showEventsWithId', arguments
);
8946 // Shows all rendered event segments linked to the given event
8947 // RECURSIVE with subcomponents
8948 DateComponent
.prototype.hideEventsWithId = function (eventDefId
) {
8949 this.getEventSegs().forEach(function (seg
) {
8950 if (seg
.footprint
.eventDef
.id
=== eventDefId
&&
8951 seg
.el
// necessary?
8953 seg
.el
.css('visibility', 'hidden');
8956 this.callChildren('hideEventsWithId', arguments
);
8958 // Drag-n-Drop Rendering (for both events and external elements)
8959 // ---------------------------------------------------------------------------------------------------------------
8960 // Renders a visual indication of a event or external-element drag over the given drop zone.
8961 // If an external-element, seg will be `null`.
8962 // Must return elements used for any mock events.
8963 DateComponent
.prototype.renderDrag = function (eventFootprints
, seg
, isTouch
) {
8964 var renderedHelper
= false;
8965 this.iterChildren(function (child
) {
8966 if (child
.renderDrag(eventFootprints
, seg
, isTouch
)) {
8967 renderedHelper
= true;
8970 return renderedHelper
;
8972 // Unrenders a visual indication of an event or external-element being dragged.
8973 DateComponent
.prototype.unrenderDrag = function () {
8974 this.callChildren('unrenderDrag', arguments
);
8977 // ---------------------------------------------------------------------------------------------------------------
8978 // Renders a visual indication of an event being resized.
8979 DateComponent
.prototype.renderEventResize = function (eventFootprints
, seg
, isTouch
) {
8980 this.callChildren('renderEventResize', arguments
);
8982 // Unrenders a visual indication of an event being resized.
8983 DateComponent
.prototype.unrenderEventResize = function () {
8984 this.callChildren('unrenderEventResize', arguments
);
8987 // ---------------------------------------------------------------------------------------------------------------
8988 // Renders a visual indication of the selection
8989 // TODO: rename to `renderSelection` after legacy is gone
8990 DateComponent
.prototype.renderSelectionFootprint = function (componentFootprint
) {
8991 this.renderHighlight(componentFootprint
);
8992 this.callChildren('renderSelectionFootprint', arguments
);
8994 // Unrenders a visual indication of selection
8995 DateComponent
.prototype.unrenderSelection = function () {
8996 this.unrenderHighlight();
8997 this.callChildren('unrenderSelection', arguments
);
9000 // ---------------------------------------------------------------------------------------------------------------
9001 // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data)
9002 DateComponent
.prototype.renderHighlight = function (componentFootprint
) {
9003 if (this.fillRenderer
) {
9004 this.fillRenderer
.renderFootprint('highlight', componentFootprint
, {
9005 getClasses: function () {
9006 return ['fc-highlight'];
9010 this.callChildren('renderHighlight', arguments
);
9012 // Unrenders the emphasis on a date range
9013 DateComponent
.prototype.unrenderHighlight = function () {
9014 if (this.fillRenderer
) {
9015 this.fillRenderer
.unrender('highlight');
9017 this.callChildren('unrenderHighlight', arguments
);
9020 // ---------------------------------------------------------------------------------------------------------------
9021 // just because all DateComponents support this interface
9022 // doesn't mean they need to have their own internal coord system. they can defer to sub-components.
9023 DateComponent
.prototype.hitsNeeded = function () {
9024 if (!(this.hitsNeededDepth
++)) {
9027 this.callChildren('hitsNeeded', arguments
);
9029 DateComponent
.prototype.hitsNotNeeded = function () {
9030 if (this.hitsNeededDepth
&& !(--this.hitsNeededDepth
)) {
9033 this.callChildren('hitsNotNeeded', arguments
);
9035 DateComponent
.prototype.prepareHits = function () {
9036 // subclasses can implement
9038 DateComponent
.prototype.releaseHits = function () {
9039 // subclasses can implement
9041 // Given coordinates from the topleft of the document, return data about the date-related area underneath.
9042 // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged).
9043 // Must have a `grid` property, a reference to this current grid. TODO: avoid this
9044 // The returned object will be processed by getHitFootprint and getHitEl.
9045 DateComponent
.prototype.queryHit = function (leftOffset
, topOffset
) {
9046 var childrenByUid
= this.childrenByUid
;
9049 for (uid
in childrenByUid
) {
9050 hit
= childrenByUid
[uid
].queryHit(leftOffset
, topOffset
);
9057 DateComponent
.prototype.getSafeHitFootprint = function (hit
) {
9058 var footprint
= this.getHitFootprint(hit
);
9059 if (!this.dateProfile
.activeUnzonedRange
.containsRange(footprint
.unzonedRange
)) {
9064 DateComponent
.prototype.getHitFootprint = function (hit
) {
9065 // what about being abstract!?
9067 // Given position-level information about a date-related area within the grid,
9068 // should return a jQuery element that best represents it. passed to dayClick callback.
9069 DateComponent
.prototype.getHitEl = function (hit
) {
9070 // what about being abstract!?
9072 /* Converting eventRange -> eventFootprint
9073 ------------------------------------------------------------------------------------------------------------------*/
9074 DateComponent
.prototype.eventRangesToEventFootprints = function (eventRanges
) {
9075 var eventFootprints
= [];
9077 for (i
= 0; i
< eventRanges
.length
; i
++) {
9078 eventFootprints
.push
.apply(// append
9079 eventFootprints
, this.eventRangeToEventFootprints(eventRanges
[i
]));
9081 return eventFootprints
;
9083 DateComponent
.prototype.eventRangeToEventFootprints = function (eventRange
) {
9084 return [util_2
.eventRangeToEventFootprint(eventRange
)];
9086 /* Converting componentFootprint/eventFootprint -> segs
9087 ------------------------------------------------------------------------------------------------------------------*/
9088 DateComponent
.prototype.eventFootprintsToSegs = function (eventFootprints
) {
9091 for (i
= 0; i
< eventFootprints
.length
; i
++) {
9092 segs
.push
.apply(segs
, this.eventFootprintToSegs(eventFootprints
[i
]));
9096 // Given an event's span (unzoned start/end and other misc data), and the event itself,
9097 // slices into segments and attaches event-derived properties to them.
9098 // eventSpan - { start, end, isStart, isEnd, otherthings... }
9099 DateComponent
.prototype.eventFootprintToSegs = function (eventFootprint
) {
9100 var unzonedRange
= eventFootprint
.componentFootprint
.unzonedRange
;
9104 segs
= this.componentFootprintToSegs(eventFootprint
.componentFootprint
);
9105 for (i
= 0; i
< segs
.length
; i
++) {
9107 if (!unzonedRange
.isStart
) {
9108 seg
.isStart
= false;
9110 if (!unzonedRange
.isEnd
) {
9113 seg
.footprint
= eventFootprint
;
9114 // TODO: rename to seg.eventFootprint
9118 DateComponent
.prototype.componentFootprintToSegs = function (componentFootprint
) {
9122 // ---------------------------------------------------------------------------------------------------------------
9123 DateComponent
.prototype.callChildren = function (methodName
, args
) {
9124 this.iterChildren(function (child
) {
9125 child
[methodName
].apply(child
, args
);
9128 DateComponent
.prototype.iterChildren = function (func
) {
9129 var childrenByUid
= this.childrenByUid
;
9131 for (uid
in childrenByUid
) {
9132 func(childrenByUid
[uid
]);
9135 DateComponent
.prototype._getCalendar = function () {
9137 return t
.calendar
|| t
.view
.calendar
;
9139 DateComponent
.prototype._getView = function () {
9142 DateComponent
.prototype._getDateProfile = function () {
9143 return this._getView().get('dateProfile');
9145 // Generates HTML for an anchor to another view into the calendar.
9146 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
9147 // `gotoOptions` can either be a moment input, or an object with the form:
9148 // { date, type, forceOff }
9149 // `type` is a view-type like "day" or "week". default value is "day".
9150 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
9151 DateComponent
.prototype.buildGotoAnchorHtml = function (gotoOptions
, attrs
, innerHtml
) {
9156 if ($.isPlainObject(gotoOptions
)) {
9157 date
= gotoOptions
.date
;
9158 type
= gotoOptions
.type
;
9159 forceOff
= gotoOptions
.forceOff
;
9162 date
= gotoOptions
; // a single moment input
9164 date
= moment_ext_1
.default(date
); // if a string, parse it
9166 date
: date
.format('YYYY-MM-DD'),
9169 if (typeof attrs
=== 'string') {
9173 attrs
= attrs
? ' ' + util_1
.attrsToStr(attrs
) : ''; // will have a leading space
9174 innerHtml
= innerHtml
|| '';
9175 if (!forceOff
&& this.opt('navLinks')) {
9176 return '<a' + attrs
+
9177 ' data-goto="' + util_1
.htmlEscape(JSON
.stringify(finalOptions
)) + '">' +
9182 return '<span' + attrs
+ '>' +
9187 DateComponent
.prototype.getAllDayHtml = function () {
9188 return this.opt('allDayHtml') || util_1
.htmlEscape(this.opt('allDayText'));
9190 // Computes HTML classNames for a single-day element
9191 DateComponent
.prototype.getDayClasses = function (date
, noThemeHighlight
) {
9192 var view
= this._getView();
9195 if (!this.dateProfile
.activeUnzonedRange
.containsDate(date
)) {
9196 classes
.push('fc-disabled-day'); // TODO: jQuery UI theme?
9199 classes
.push('fc-' + util_1
.dayIDs
[date
.day()]);
9200 if (view
.isDateInOtherMonth(date
, this.dateProfile
)) {
9201 classes
.push('fc-other-month');
9203 today
= view
.calendar
.getNow();
9204 if (date
.isSame(today
, 'day')) {
9205 classes
.push('fc-today');
9206 if (noThemeHighlight
!== true) {
9207 classes
.push(view
.calendar
.theme
.getClass('today'));
9210 else if (date
< today
) {
9211 classes
.push('fc-past');
9214 classes
.push('fc-future');
9219 // Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
9220 // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
9221 // The timezones of the dates within `range` will be respected.
9222 DateComponent
.prototype.formatRange = function (range
, isAllDay
, formatStr
, separator
) {
9223 var end
= range
.end
;
9225 end
= end
.clone().subtract(1); // convert to inclusive. last ms of previous day
9227 return date_formatting_1
.formatRange(range
.start
, end
, formatStr
, separator
, this.isRTL
);
9229 // Compute the number of the give units in the "current" range.
9230 // Will return a floating-point number. Won't round.
9231 DateComponent
.prototype.currentRangeAs = function (unit
) {
9232 return this._getDateProfile().currentUnzonedRange
.as(unit
);
9234 // Returns the date range of the full days the given range visually appears to occupy.
9235 // Returns a plain object with start/end, NOT an UnzonedRange!
9236 DateComponent
.prototype.computeDayRange = function (unzonedRange
) {
9237 var calendar
= this._getCalendar();
9238 var startDay
= calendar
.msToUtcMoment(unzonedRange
.startMs
, true); // the beginning of the day the range starts
9239 var end
= calendar
.msToUtcMoment(unzonedRange
.endMs
);
9240 var endTimeMS
= +end
.time(); // # of milliseconds into `endDay`
9241 var endDay
= end
.clone().stripTime(); // the beginning of the day the range exclusively ends
9242 // If the end time is actually inclusively part of the next day and is equal to or
9243 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
9244 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
9245 if (endTimeMS
&& endTimeMS
>= this.nextDayThreshold
) {
9246 endDay
.add(1, 'days');
9248 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
9249 if (endDay
<= startDay
) {
9250 endDay
= startDay
.clone().add(1, 'days');
9252 return { start
: startDay
, end
: endDay
};
9254 // Does the given range visually appear to occupy more than one day?
9255 DateComponent
.prototype.isMultiDayRange = function (unzonedRange
) {
9256 var dayRange
= this.computeDayRange(unzonedRange
);
9257 return dayRange
.end
.diff(dayRange
.start
, 'days') > 1;
9259 DateComponent
.guid
= 0; // TODO: better system for this?
9260 return DateComponent
;
9261 }(Component_1
.default));
9262 exports
.default = DateComponent
;
9264 function convertEventsPayloadToLegacyArray(eventsPayload
) {
9267 var legacyEvents
= [];
9269 for (eventDefId
in eventsPayload
) {
9270 eventInstances
= eventsPayload
[eventDefId
].eventInstances
;
9271 for (i
= 0; i
< eventInstances
.length
; i
++) {
9272 legacyEvents
.push(eventInstances
[i
].toLegacy());
9275 return legacyEvents
;
9281 /***/ (function(module
, exports
, __webpack_require__
) {
9283 Object
.defineProperty(exports
, "__esModule", { value
: true });
9284 var $ = __webpack_require__(3);
9285 var moment
= __webpack_require__(0);
9286 var util_1
= __webpack_require__(4);
9287 var options_1
= __webpack_require__(32);
9288 var Iterator_1
= __webpack_require__(238);
9289 var GlobalEmitter_1
= __webpack_require__(21);
9290 var EmitterMixin_1
= __webpack_require__(11);
9291 var ListenerMixin_1
= __webpack_require__(7);
9292 var Toolbar_1
= __webpack_require__(239);
9293 var OptionsManager_1
= __webpack_require__(240);
9294 var ViewSpecManager_1
= __webpack_require__(241);
9295 var Constraints_1
= __webpack_require__(207);
9296 var locale_1
= __webpack_require__(31);
9297 var moment_ext_1
= __webpack_require__(10);
9298 var UnzonedRange_1
= __webpack_require__(5);
9299 var ComponentFootprint_1
= __webpack_require__(12);
9300 var EventDateProfile_1
= __webpack_require__(17);
9301 var EventManager_1
= __webpack_require__(242);
9302 var BusinessHourGenerator_1
= __webpack_require__(212);
9303 var EventSourceParser_1
= __webpack_require__(38);
9304 var EventDefParser_1
= __webpack_require__(49);
9305 var SingleEventDef_1
= __webpack_require__(13);
9306 var EventDefMutation_1
= __webpack_require__(37);
9307 var EventSource_1
= __webpack_require__(6);
9308 var ThemeRegistry_1
= __webpack_require__(51);
9309 var Calendar
= /** @class */ (function () {
9310 function Calendar(el
, overrides
) {
9311 this.loadingLevel
= 0; // number of simultaneous loading tasks
9312 this.ignoreUpdateViewSize
= 0;
9313 this.freezeContentHeightDepth
= 0;
9314 // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection.
9315 // unneeded() is called in destroy.
9316 GlobalEmitter_1
.default.needed();
9318 this.viewsByType
= {};
9319 this.optionsManager
= new OptionsManager_1
.default(this, overrides
);
9320 this.viewSpecManager
= new ViewSpecManager_1
.default(this.optionsManager
, this);
9321 this.initMomentInternals(); // needs to happen after options hash initialized
9322 this.initCurrentDate();
9323 this.initEventManager();
9324 this.constraints
= new Constraints_1
.default(this.eventManager
, this);
9327 Calendar
.prototype.constructed = function () {
9328 // useful for monkeypatching. used?
9330 Calendar
.prototype.getView = function () {
9333 Calendar
.prototype.publiclyTrigger = function (name
, triggerInfo
) {
9334 var optHandler
= this.opt(name
);
9337 if ($.isPlainObject(triggerInfo
)) {
9338 context
= triggerInfo
.context
;
9339 args
= triggerInfo
.args
;
9341 else if ($.isArray(triggerInfo
)) {
9344 if (context
== null) {
9345 context
= this.el
[0]; // fallback context
9350 this.triggerWith(name
, context
, args
); // Emitter's method
9352 return optHandler
.apply(context
, args
);
9355 Calendar
.prototype.hasPublicHandlers = function (name
) {
9356 return this.hasHandlers(name
) ||
9357 this.opt(name
); // handler specified in options
9359 // Options Public API
9360 // -----------------------------------------------------------------------------------------------------------------
9361 // public getter/setter
9362 Calendar
.prototype.option = function (name
, value
) {
9364 if (typeof name
=== 'string') {
9365 if (value
=== undefined) {
9366 return this.optionsManager
.get(name
);
9370 newOptionHash
[name
] = value
;
9371 this.optionsManager
.add(newOptionHash
);
9374 else if (typeof name
=== 'object') {
9375 this.optionsManager
.add(name
);
9379 Calendar
.prototype.opt = function (name
) {
9380 return this.optionsManager
.get(name
);
9383 // -----------------------------------------------------------------------------------------------------------------
9384 // Given a view name for a custom view or a standard view, creates a ready-to-go View object
9385 Calendar
.prototype.instantiateView = function (viewType
) {
9386 var spec
= this.viewSpecManager
.getViewSpec(viewType
);
9388 throw new Error("View type \"" + viewType
+ "\" is not valid");
9390 return new spec
['class'](this, spec
);
9392 // Returns a boolean about whether the view is okay to instantiate at some point
9393 Calendar
.prototype.isValidViewType = function (viewType
) {
9394 return Boolean(this.viewSpecManager
.getViewSpec(viewType
));
9396 Calendar
.prototype.changeView = function (viewName
, dateOrRange
) {
9398 if (dateOrRange
.start
&& dateOrRange
.end
) {
9399 this.optionsManager
.recordOverrides({
9400 visibleRange
: dateOrRange
9404 this.currentDate
= this.moment(dateOrRange
).stripZone(); // just like gotoDate
9407 this.renderView(viewName
);
9409 // Forces navigation to a view for the given date.
9410 // `viewType` can be a specific view name or a generic one like "week" or "day".
9411 Calendar
.prototype.zoomTo = function (newDate
, viewType
) {
9413 viewType
= viewType
|| 'day'; // day is default zoom
9414 spec
= this.viewSpecManager
.getViewSpec(viewType
) ||
9415 this.viewSpecManager
.getUnitViewSpec(viewType
);
9416 this.currentDate
= newDate
.clone();
9417 this.renderView(spec
? spec
.type
: null);
9420 // -----------------------------------------------------------------------------------------------------------------
9421 Calendar
.prototype.initCurrentDate = function () {
9422 var defaultDateInput
= this.opt('defaultDate');
9423 // compute the initial ambig-timezone date
9424 if (defaultDateInput
!= null) {
9425 this.currentDate
= this.moment(defaultDateInput
).stripZone();
9428 this.currentDate
= this.getNow(); // getNow already returns unzoned
9431 Calendar
.prototype.prev = function () {
9432 var view
= this.view
;
9433 var prevInfo
= view
.dateProfileGenerator
.buildPrev(view
.get('dateProfile'));
9434 if (prevInfo
.isValid
) {
9435 this.currentDate
= prevInfo
.date
;
9439 Calendar
.prototype.next = function () {
9440 var view
= this.view
;
9441 var nextInfo
= view
.dateProfileGenerator
.buildNext(view
.get('dateProfile'));
9442 if (nextInfo
.isValid
) {
9443 this.currentDate
= nextInfo
.date
;
9447 Calendar
.prototype.prevYear = function () {
9448 this.currentDate
.add(-1, 'years');
9451 Calendar
.prototype.nextYear = function () {
9452 this.currentDate
.add(1, 'years');
9455 Calendar
.prototype.today = function () {
9456 this.currentDate
= this.getNow(); // should deny like prev/next?
9459 Calendar
.prototype.gotoDate = function (zonedDateInput
) {
9460 this.currentDate
= this.moment(zonedDateInput
).stripZone();
9463 Calendar
.prototype.incrementDate = function (delta
) {
9464 this.currentDate
.add(moment
.duration(delta
));
9468 Calendar
.prototype.getDate = function () {
9469 return this.applyTimezone(this.currentDate
); // infuse the calendar's timezone
9471 // Loading Triggering
9472 // -----------------------------------------------------------------------------------------------------------------
9473 // Should be called when any type of async data fetching begins
9474 Calendar
.prototype.pushLoading = function () {
9475 if (!(this.loadingLevel
++)) {
9476 this.publiclyTrigger('loading', [true, this.view
]);
9479 // Should be called when any type of async data fetching completes
9480 Calendar
.prototype.popLoading = function () {
9481 if (!(--this.loadingLevel
)) {
9482 this.publiclyTrigger('loading', [false, this.view
]);
9485 // High-level Rendering
9486 // -----------------------------------------------------------------------------------
9487 Calendar
.prototype.render = function () {
9488 if (!this.contentEl
) {
9489 this.initialRender();
9491 else if (this.elementVisible()) {
9492 // mainly for the public API
9494 this.updateViewSize();
9497 Calendar
.prototype.initialRender = function () {
9501 // event delegation for nav links
9502 el
.on('click.fc', 'a[data-goto]', function (ev
) {
9503 var anchorEl
= $(ev
.currentTarget
);
9504 var gotoOptions
= anchorEl
.data('goto'); // will automatically parse JSON
9505 var date
= _this
.moment(gotoOptions
.date
);
9506 var viewType
= gotoOptions
.type
;
9507 // property like "navLinkDayClick". might be a string or a function
9508 var customAction
= _this
.view
.opt('navLink' + util_1
.capitaliseFirstLetter(viewType
) + 'Click');
9509 if (typeof customAction
=== 'function') {
9510 customAction(date
, ev
);
9513 if (typeof customAction
=== 'string') {
9514 viewType
= customAction
;
9516 _this
.zoomTo(date
, viewType
);
9519 // called immediately, and upon option change
9520 this.optionsManager
.watch('settingTheme', ['?theme', '?themeSystem'], function (opts
) {
9521 var themeClass
= ThemeRegistry_1
.getThemeSystemClass(opts
.themeSystem
|| opts
.theme
);
9522 var theme
= new themeClass(_this
.optionsManager
);
9523 var widgetClass
= theme
.getClass('widget');
9524 _this
.theme
= theme
;
9526 el
.addClass(widgetClass
);
9529 var widgetClass
= _this
.theme
.getClass('widget');
9532 el
.removeClass(widgetClass
);
9535 this.optionsManager
.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps
) {
9536 _this
.businessHourGenerator
= new BusinessHourGenerator_1
.default(deps
.businessHours
, _this
);
9538 _this
.view
.set('businessHourGenerator', _this
.businessHourGenerator
);
9541 _this
.businessHourGenerator
= null;
9543 // called immediately, and upon option change.
9544 // HACK: locale often affects isRTL, so we explicitly listen to that too.
9545 this.optionsManager
.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts
) {
9546 el
.toggleClass('fc-ltr', !opts
.isRTL
);
9547 el
.toggleClass('fc-rtl', opts
.isRTL
);
9549 this.contentEl
= $("<div class='fc-view-container'/>").prependTo(el
);
9550 this.initToolbars();
9551 this.renderHeader();
9552 this.renderFooter();
9553 this.renderView(this.opt('defaultView'));
9554 if (this.opt('handleWindowResize')) {
9555 $(window
).resize(this.windowResizeProxy
= util_1
.debounce(// prevents rapid calls
9556 this.windowResize
.bind(this), this.opt('windowResizeDelay')));
9559 Calendar
.prototype.destroy = function () {
9563 this.toolbarsManager
.proxyCall('removeElement');
9564 this.contentEl
.remove();
9565 this.el
.removeClass('fc fc-ltr fc-rtl');
9566 // removes theme-related root className
9567 this.optionsManager
.unwatch('settingTheme');
9568 this.optionsManager
.unwatch('settingBusinessHourGenerator');
9569 this.el
.off('.fc'); // unbind nav link handlers
9570 if (this.windowResizeProxy
) {
9571 $(window
).unbind('resize', this.windowResizeProxy
);
9572 this.windowResizeProxy
= null;
9574 GlobalEmitter_1
.default.unneeded();
9576 Calendar
.prototype.elementVisible = function () {
9577 return this.el
.is(':visible');
9580 // -----------------------------------------------------------------------------------------------------------------
9581 Calendar
.prototype.bindViewHandlers = function (view
) {
9583 view
.watch('titleForCalendar', ['title'], function (deps
) {
9584 if (view
=== _this
.view
) {
9585 _this
.setToolbarsTitle(deps
.title
);
9588 view
.watch('dateProfileForCalendar', ['dateProfile'], function (deps
) {
9589 if (view
=== _this
.view
) {
9590 _this
.currentDate
= deps
.dateProfile
.date
; // might have been constrained by view dates
9591 _this
.updateToolbarButtons(deps
.dateProfile
);
9595 Calendar
.prototype.unbindViewHandlers = function (view
) {
9596 view
.unwatch('titleForCalendar');
9597 view
.unwatch('dateProfileForCalendar');
9600 // -----------------------------------------------------------------------------------
9601 // Renders a view because of a date change, view-type change, or for the first time.
9602 // If not given a viewType, keep the current view but render different dates.
9603 // Accepts an optional scroll state to restore to.
9604 Calendar
.prototype.renderView = function (viewType
) {
9605 var oldView
= this.view
;
9607 this.freezeContentHeight();
9608 if (oldView
&& viewType
&& oldView
.type
!== viewType
) {
9611 // if viewType changed, or the view was never created, create a fresh view
9612 if (!this.view
&& viewType
) {
9613 newView
= this.view
=
9614 this.viewsByType
[viewType
] ||
9615 (this.viewsByType
[viewType
] = this.instantiateView(viewType
));
9616 this.bindViewHandlers(newView
);
9617 newView
.startBatchRender(); // so that setElement+setDate rendering are joined
9618 newView
.setElement($("<div class='fc-view fc-" + viewType
+ "-view' />").appendTo(this.contentEl
));
9619 this.toolbarsManager
.proxyCall('activateButton', viewType
);
9622 // prevent unnecessary change firing
9623 if (this.view
.get('businessHourGenerator') !== this.businessHourGenerator
) {
9624 this.view
.set('businessHourGenerator', this.businessHourGenerator
);
9626 this.view
.setDate(this.currentDate
);
9628 newView
.stopBatchRender();
9631 this.thawContentHeight();
9633 // Unrenders the current view and reflects this change in the Header.
9634 // Unregsiters the `view`, but does not remove from viewByType hash.
9635 Calendar
.prototype.clearView = function () {
9636 var currentView
= this.view
;
9637 this.toolbarsManager
.proxyCall('deactivateButton', currentView
.type
);
9638 this.unbindViewHandlers(currentView
);
9639 currentView
.removeElement();
9640 currentView
.unsetDate(); // so bindViewHandlers doesn't fire with old values next time
9643 // Destroys the view, including the view object. Then, re-instantiates it and renders it.
9644 // Maintains the same scroll state.
9645 // TODO: maintain any other user-manipulated state.
9646 Calendar
.prototype.reinitView = function () {
9647 var oldView
= this.view
;
9648 var scroll
= oldView
.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll
9649 this.freezeContentHeight();
9652 this.renderView(oldView
.type
); // needs the type to freshly render
9653 this.view
.applyScroll(scroll
);
9654 this.thawContentHeight();
9657 // -----------------------------------------------------------------------------------
9658 Calendar
.prototype.getSuggestedViewHeight = function () {
9659 if (this.suggestedViewHeight
== null) {
9662 return this.suggestedViewHeight
;
9664 Calendar
.prototype.isHeightAuto = function () {
9665 return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto';
9667 Calendar
.prototype.updateViewSize = function (isResize
) {
9668 if (isResize
=== void 0) { isResize
= false; }
9669 var view
= this.view
;
9671 if (!this.ignoreUpdateViewSize
&& view
) {
9674 scroll
= view
.queryScroll();
9676 this.ignoreUpdateViewSize
++;
9677 view
.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize
);
9678 this.ignoreUpdateViewSize
--;
9680 view
.applyScroll(scroll
);
9682 return true; // signal success
9685 Calendar
.prototype.calcSize = function () {
9686 if (this.elementVisible()) {
9690 Calendar
.prototype._calcSize = function () {
9691 var contentHeightInput
= this.opt('contentHeight');
9692 var heightInput
= this.opt('height');
9693 if (typeof contentHeightInput
=== 'number') {
9694 this.suggestedViewHeight
= contentHeightInput
;
9696 else if (typeof contentHeightInput
=== 'function') {
9697 this.suggestedViewHeight
= contentHeightInput();
9699 else if (typeof heightInput
=== 'number') {
9700 this.suggestedViewHeight
= heightInput
- this.queryToolbarsHeight();
9702 else if (typeof heightInput
=== 'function') {
9703 this.suggestedViewHeight
= heightInput() - this.queryToolbarsHeight();
9705 else if (heightInput
=== 'parent') {
9706 this.suggestedViewHeight
= this.el
.parent().height() - this.queryToolbarsHeight();
9709 this.suggestedViewHeight
= Math
.round(this.contentEl
.width() /
9710 Math
.max(this.opt('aspectRatio'), .5));
9713 Calendar
.prototype.windowResize = function (ev
) {
9715 // the purpose: so we don't process jqui "resize" events that have bubbled up
9716 // cast to any because .target, which is Element, can't be compared to window for some reason.
9717 ev
.target
=== window
&&
9719 this.view
.isDatesRendered
) {
9720 if (this.updateViewSize(true)) {
9721 this.publiclyTrigger('windowResize', [this.view
]);
9725 /* Height "Freezing"
9726 -----------------------------------------------------------------------------*/
9727 Calendar
.prototype.freezeContentHeight = function () {
9728 if (!(this.freezeContentHeightDepth
++)) {
9729 this.forceFreezeContentHeight();
9732 Calendar
.prototype.forceFreezeContentHeight = function () {
9733 this.contentEl
.css({
9735 height
: this.contentEl
.height(),
9739 Calendar
.prototype.thawContentHeight = function () {
9740 this.freezeContentHeightDepth
--;
9741 // always bring back to natural height
9742 this.contentEl
.css({
9747 // but if there are future thaws, re-freeze
9748 if (this.freezeContentHeightDepth
) {
9749 this.forceFreezeContentHeight();
9753 // -----------------------------------------------------------------------------------------------------------------
9754 Calendar
.prototype.initToolbars = function () {
9755 this.header
= new Toolbar_1
.default(this, this.computeHeaderOptions());
9756 this.footer
= new Toolbar_1
.default(this, this.computeFooterOptions());
9757 this.toolbarsManager
= new Iterator_1
.default([this.header
, this.footer
]);
9759 Calendar
.prototype.computeHeaderOptions = function () {
9761 extraClasses
: 'fc-header-toolbar',
9762 layout
: this.opt('header')
9765 Calendar
.prototype.computeFooterOptions = function () {
9767 extraClasses
: 'fc-footer-toolbar',
9768 layout
: this.opt('footer')
9771 // can be called repeatedly and Header will rerender
9772 Calendar
.prototype.renderHeader = function () {
9773 var header
= this.header
;
9774 header
.setToolbarOptions(this.computeHeaderOptions());
9777 this.el
.prepend(header
.el
);
9780 // can be called repeatedly and Footer will rerender
9781 Calendar
.prototype.renderFooter = function () {
9782 var footer
= this.footer
;
9783 footer
.setToolbarOptions(this.computeFooterOptions());
9786 this.el
.append(footer
.el
);
9789 Calendar
.prototype.setToolbarsTitle = function (title
) {
9790 this.toolbarsManager
.proxyCall('updateTitle', title
);
9792 Calendar
.prototype.updateToolbarButtons = function (dateProfile
) {
9793 var now
= this.getNow();
9794 var view
= this.view
;
9795 var todayInfo
= view
.dateProfileGenerator
.build(now
);
9796 var prevInfo
= view
.dateProfileGenerator
.buildPrev(view
.get('dateProfile'));
9797 var nextInfo
= view
.dateProfileGenerator
.buildNext(view
.get('dateProfile'));
9798 this.toolbarsManager
.proxyCall((todayInfo
.isValid
&& !dateProfile
.currentUnzonedRange
.containsDate(now
)) ?
9800 'disableButton', 'today');
9801 this.toolbarsManager
.proxyCall(prevInfo
.isValid
?
9803 'disableButton', 'prev');
9804 this.toolbarsManager
.proxyCall(nextInfo
.isValid
?
9806 'disableButton', 'next');
9808 Calendar
.prototype.queryToolbarsHeight = function () {
9809 return this.toolbarsManager
.items
.reduce(function (accumulator
, toolbar
) {
9810 var toolbarHeight
= toolbar
.el
? toolbar
.el
.outerHeight(true) : 0; // includes margin
9811 return accumulator
+ toolbarHeight
;
9815 // -----------------------------------------------------------------------------------------------------------------
9816 // this public method receives start/end dates in any format, with any timezone
9817 Calendar
.prototype.select = function (zonedStartInput
, zonedEndInput
) {
9818 this.view
.select(this.buildSelectFootprint
.apply(this, arguments
));
9820 Calendar
.prototype.unselect = function () {
9822 this.view
.unselect();
9825 // Given arguments to the select method in the API, returns a span (unzoned start/end and other info)
9826 Calendar
.prototype.buildSelectFootprint = function (zonedStartInput
, zonedEndInput
) {
9827 var start
= this.moment(zonedStartInput
).stripZone();
9829 if (zonedEndInput
) {
9830 end
= this.moment(zonedEndInput
).stripZone();
9832 else if (start
.hasTime()) {
9833 end
= start
.clone().add(this.defaultTimedEventDuration
);
9836 end
= start
.clone().add(this.defaultAllDayEventDuration
);
9838 return new ComponentFootprint_1
.default(new UnzonedRange_1
.default(start
, end
), !start
.hasTime());
9841 // -----------------------------------------------------------------------------------------------------------------
9842 Calendar
.prototype.initMomentInternals = function () {
9844 this.defaultAllDayEventDuration
= moment
.duration(this.opt('defaultAllDayEventDuration'));
9845 this.defaultTimedEventDuration
= moment
.duration(this.opt('defaultTimedEventDuration'));
9846 // Called immediately, and when any of the options change.
9847 // Happens before any internal objects rebuild or rerender, because this is very core.
9848 this.optionsManager
.watch('buildingMomentLocale', [
9849 '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort',
9850 '?firstDay', '?weekNumberCalculation'
9851 ], function (opts
) {
9852 var weekNumberCalculation
= opts
.weekNumberCalculation
;
9853 var firstDay
= opts
.firstDay
;
9856 if (weekNumberCalculation
=== 'iso') {
9857 weekNumberCalculation
= 'ISO'; // normalize
9859 var localeData
= Object
.create(// make a cheap copy
9860 locale_1
.getMomentLocaleData(opts
.locale
) // will fall back to en
9862 if (opts
.monthNames
) {
9863 localeData
._months
= opts
.monthNames
;
9865 if (opts
.monthNamesShort
) {
9866 localeData
._monthsShort
= opts
.monthNamesShort
;
9868 if (opts
.dayNames
) {
9869 localeData
._weekdays
= opts
.dayNames
;
9871 if (opts
.dayNamesShort
) {
9872 localeData
._weekdaysShort
= opts
.dayNamesShort
;
9874 if (firstDay
== null && weekNumberCalculation
=== 'ISO') {
9877 if (firstDay
!= null) {
9878 _week
= Object
.create(localeData
._week
); // _week: { dow: # }
9879 _week
.dow
= firstDay
;
9880 localeData
._week
= _week
;
9882 if (weekNumberCalculation
=== 'ISO' ||
9883 weekNumberCalculation
=== 'local' ||
9884 typeof weekNumberCalculation
=== 'function') {
9885 localeData
._fullCalendar_weekCalc
= weekNumberCalculation
; // moment-ext will know what to do with it
9887 _this
.localeData
= localeData
;
9888 // If the internal current date object already exists, move to new locale.
9889 // We do NOT need to do this technique for event dates, because this happens when converting to "segments".
9890 if (_this
.currentDate
) {
9891 _this
.localizeMoment(_this
.currentDate
); // sets to localeData
9895 // Builds a moment using the settings of the current calendar: timezone and locale.
9896 // Accepts anything the vanilla moment() constructor accepts.
9897 Calendar
.prototype.moment = function () {
9899 for (var _i
= 0; _i
< arguments
.length
; _i
++) {
9900 args
[_i
] = arguments
[_i
];
9903 if (this.opt('timezone') === 'local') {
9904 mom
= moment_ext_1
.default.apply(null, args
);
9905 // Force the moment to be local, because momentExt doesn't guarantee it.
9906 if (mom
.hasTime()) {
9910 else if (this.opt('timezone') === 'UTC') {
9911 mom
= moment_ext_1
.default.utc
.apply(null, args
); // process as UTC
9914 mom
= moment_ext_1
.default.parseZone
.apply(null, args
); // let the input decide the zone
9916 this.localizeMoment(mom
); // TODO
9919 Calendar
.prototype.msToMoment = function (ms
, forceAllDay
) {
9920 var mom
= moment_ext_1
.default.utc(ms
); // TODO: optimize by using Date.UTC
9925 mom
= this.applyTimezone(mom
); // may or may not apply locale
9927 this.localizeMoment(mom
);
9930 Calendar
.prototype.msToUtcMoment = function (ms
, forceAllDay
) {
9931 var mom
= moment_ext_1
.default.utc(ms
); // TODO: optimize by using Date.UTC
9935 this.localizeMoment(mom
);
9938 // Updates the given moment's locale settings to the current calendar locale settings.
9939 Calendar
.prototype.localizeMoment = function (mom
) {
9940 mom
._locale
= this.localeData
;
9942 // Returns a boolean about whether or not the calendar knows how to calculate
9943 // the timezone offset of arbitrary dates in the current timezone.
9944 Calendar
.prototype.getIsAmbigTimezone = function () {
9945 return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC';
9947 // Returns a copy of the given date in the current timezone. Has no effect on dates without times.
9948 Calendar
.prototype.applyTimezone = function (date
) {
9949 if (!date
.hasTime()) {
9950 return date
.clone();
9952 var zonedDate
= this.moment(date
.toArray());
9953 var timeAdjust
= date
.time().asMilliseconds() - zonedDate
.time().asMilliseconds();
9954 var adjustedZonedDate
;
9955 // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396)
9957 adjustedZonedDate
= zonedDate
.clone().add(timeAdjust
); // add milliseconds
9958 if (date
.time().asMilliseconds() - adjustedZonedDate
.time().asMilliseconds() === 0) {
9959 zonedDate
= adjustedZonedDate
;
9965 Assumes the footprint is non-open-ended.
9967 Calendar
.prototype.footprintToDateProfile = function (componentFootprint
, ignoreEnd
) {
9968 if (ignoreEnd
=== void 0) { ignoreEnd
= false; }
9969 var start
= moment_ext_1
.default.utc(componentFootprint
.unzonedRange
.startMs
);
9972 end
= moment_ext_1
.default.utc(componentFootprint
.unzonedRange
.endMs
);
9974 if (componentFootprint
.isAllDay
) {
9981 start
= this.applyTimezone(start
);
9983 end
= this.applyTimezone(end
);
9986 return new EventDateProfile_1
.default(start
, end
, this);
9988 // Returns a moment for the current date, as defined by the client's computer or from the `now` option.
9989 // Will return an moment with an ambiguous timezone.
9990 Calendar
.prototype.getNow = function () {
9991 var now
= this.opt('now');
9992 if (typeof now
=== 'function') {
9995 return this.moment(now
).stripZone();
9997 // Produces a human-readable string for the given duration.
9998 // Side-effect: changes the locale of the given duration.
9999 Calendar
.prototype.humanizeDuration = function (duration
) {
10000 return duration
.locale(this.opt('locale')).humanize();
10002 // will return `null` if invalid range
10003 Calendar
.prototype.parseUnzonedRange = function (rangeInput
) {
10006 if (rangeInput
.start
) {
10007 start
= this.moment(rangeInput
.start
).stripZone();
10009 if (rangeInput
.end
) {
10010 end
= this.moment(rangeInput
.end
).stripZone();
10012 if (!start
&& !end
) {
10015 if (start
&& end
&& end
.isBefore(start
)) {
10018 return new UnzonedRange_1
.default(start
, end
);
10020 // Event-Date Utilities
10021 // -----------------------------------------------------------------------------------------------------------------
10022 Calendar
.prototype.initEventManager = function () {
10024 var eventManager
= new EventManager_1
.default(this);
10025 var rawSources
= this.opt('eventSources') || [];
10026 var singleRawSource
= this.opt('events');
10027 this.eventManager
= eventManager
;
10028 if (singleRawSource
) {
10029 rawSources
.unshift(singleRawSource
);
10031 eventManager
.on('release', function (eventsPayload
) {
10032 _this
.trigger('eventsReset', eventsPayload
);
10034 eventManager
.freeze();
10035 rawSources
.forEach(function (rawSource
) {
10036 var source
= EventSourceParser_1
.default.parse(rawSource
, _this
);
10038 eventManager
.addSource(source
);
10041 eventManager
.thaw();
10043 Calendar
.prototype.requestEvents = function (start
, end
) {
10044 return this.eventManager
.requestEvents(start
, end
, this.opt('timezone'), !this.opt('lazyFetching'));
10046 // Get an event's normalized end date. If not present, calculate it from the defaults.
10047 Calendar
.prototype.getEventEnd = function (event
) {
10049 return event
.end
.clone();
10052 return this.getDefaultEventEnd(event
.allDay
, event
.start
);
10055 // Given an event's allDay status and start date, return what its fallback end date should be.
10056 // TODO: rename to computeDefaultEventEnd
10057 Calendar
.prototype.getDefaultEventEnd = function (allDay
, zonedStart
) {
10058 var end
= zonedStart
.clone();
10060 end
.stripTime().add(this.defaultAllDayEventDuration
);
10063 end
.add(this.defaultTimedEventDuration
);
10065 if (this.getIsAmbigTimezone()) {
10066 end
.stripZone(); // we don't know what the tzo should be
10070 // Public Events API
10071 // -----------------------------------------------------------------------------------------------------------------
10072 Calendar
.prototype.rerenderEvents = function () {
10073 this.view
.flash('displayingEvents');
10075 Calendar
.prototype.refetchEvents = function () {
10076 this.eventManager
.refetchAllSources();
10078 Calendar
.prototype.renderEvents = function (eventInputs
, isSticky
) {
10079 this.eventManager
.freeze();
10080 for (var i
= 0; i
< eventInputs
.length
; i
++) {
10081 this.renderEvent(eventInputs
[i
], isSticky
);
10083 this.eventManager
.thaw();
10085 Calendar
.prototype.renderEvent = function (eventInput
, isSticky
) {
10086 if (isSticky
=== void 0) { isSticky
= false; }
10087 var eventManager
= this.eventManager
;
10088 var eventDef
= EventDefParser_1
.default.parse(eventInput
, eventInput
.source
|| eventManager
.stickySource
);
10090 eventManager
.addEventDef(eventDef
, isSticky
);
10093 // legacyQuery operates on legacy event instance objects
10094 Calendar
.prototype.removeEvents = function (legacyQuery
) {
10095 var eventManager
= this.eventManager
;
10096 var legacyInstances
= [];
10100 if (legacyQuery
== null) {
10101 eventManager
.removeAllEventDefs(); // persist=true
10104 eventManager
.getEventInstances().forEach(function (eventInstance
) {
10105 legacyInstances
.push(eventInstance
.toLegacy());
10107 legacyInstances
= filterLegacyEventInstances(legacyInstances
, legacyQuery
);
10108 // compute unique IDs
10109 for (i
= 0; i
< legacyInstances
.length
; i
++) {
10110 eventDef
= this.eventManager
.getEventDefByUid(legacyInstances
[i
]._id
);
10111 idMap
[eventDef
.id
] = true;
10113 eventManager
.freeze();
10115 eventManager
.removeEventDefsById(i
); // persist=true
10117 eventManager
.thaw();
10120 // legacyQuery operates on legacy event instance objects
10121 Calendar
.prototype.clientEvents = function (legacyQuery
) {
10122 var legacyEventInstances
= [];
10123 this.eventManager
.getEventInstances().forEach(function (eventInstance
) {
10124 legacyEventInstances
.push(eventInstance
.toLegacy());
10126 return filterLegacyEventInstances(legacyEventInstances
, legacyQuery
);
10128 Calendar
.prototype.updateEvents = function (eventPropsArray
) {
10129 this.eventManager
.freeze();
10130 for (var i
= 0; i
< eventPropsArray
.length
; i
++) {
10131 this.updateEvent(eventPropsArray
[i
]);
10133 this.eventManager
.thaw();
10135 Calendar
.prototype.updateEvent = function (eventProps
) {
10136 var eventDef
= this.eventManager
.getEventDefByUid(eventProps
._id
);
10138 var eventDefMutation
;
10139 if (eventDef
instanceof SingleEventDef_1
.default) {
10140 eventInstance
= eventDef
.buildInstance();
10141 eventDefMutation
= EventDefMutation_1
.default.createFromRawProps(eventInstance
, eventProps
, // raw props
10142 null // largeUnit -- who uses it?
10144 this.eventManager
.mutateEventsWithId(eventDef
.id
, eventDefMutation
); // will release
10147 // Public Event Sources API
10148 // ------------------------------------------------------------------------------------
10149 Calendar
.prototype.getEventSources = function () {
10150 return this.eventManager
.otherSources
.slice(); // clone
10152 Calendar
.prototype.getEventSourceById = function (id
) {
10153 return this.eventManager
.getSourceById(EventSource_1
.default.normalizeId(id
));
10155 Calendar
.prototype.addEventSource = function (sourceInput
) {
10156 var source
= EventSourceParser_1
.default.parse(sourceInput
, this);
10158 this.eventManager
.addSource(source
);
10161 Calendar
.prototype.removeEventSources = function (sourceMultiQuery
) {
10162 var eventManager
= this.eventManager
;
10165 if (sourceMultiQuery
== null) {
10166 this.eventManager
.removeAllSources();
10169 sources
= eventManager
.multiQuerySources(sourceMultiQuery
);
10170 eventManager
.freeze();
10171 for (i
= 0; i
< sources
.length
; i
++) {
10172 eventManager
.removeSource(sources
[i
]);
10174 eventManager
.thaw();
10177 Calendar
.prototype.removeEventSource = function (sourceQuery
) {
10178 var eventManager
= this.eventManager
;
10179 var sources
= eventManager
.querySources(sourceQuery
);
10181 eventManager
.freeze();
10182 for (i
= 0; i
< sources
.length
; i
++) {
10183 eventManager
.removeSource(sources
[i
]);
10185 eventManager
.thaw();
10187 Calendar
.prototype.refetchEventSources = function (sourceMultiQuery
) {
10188 var eventManager
= this.eventManager
;
10189 var sources
= eventManager
.multiQuerySources(sourceMultiQuery
);
10191 eventManager
.freeze();
10192 for (i
= 0; i
< sources
.length
; i
++) {
10193 eventManager
.refetchSource(sources
[i
]);
10195 eventManager
.thaw();
10197 // not for internal use. use options module directly instead.
10198 Calendar
.defaults
= options_1
.globalDefaults
;
10199 Calendar
.englishDefaults
= options_1
.englishDefaults
;
10200 Calendar
.rtlDefaults
= options_1
.rtlDefaults
;
10203 exports
.default = Calendar
;
10204 EmitterMixin_1
.default.mixInto(Calendar
);
10205 ListenerMixin_1
.default.mixInto(Calendar
);
10206 function filterLegacyEventInstances(legacyEventInstances
, legacyQuery
) {
10207 if (legacyQuery
== null) {
10208 return legacyEventInstances
;
10210 else if ($.isFunction(legacyQuery
)) {
10211 return legacyEventInstances
.filter(legacyQuery
);
10214 legacyQuery
+= ''; // normalize to string
10215 return legacyEventInstances
.filter(function (legacyEventInstance
) {
10216 // soft comparison because id not be normalized to string
10217 // tslint:disable-next-line
10218 return legacyEventInstance
.id
== legacyQuery
||
10219 legacyEventInstance
._id
=== legacyQuery
; // can specify internal id, but must exactly match
10227 /***/ (function(module
, exports
, __webpack_require__
) {
10229 Object
.defineProperty(exports
, "__esModule", { value
: true });
10230 var moment
= __webpack_require__(0);
10231 var util_1
= __webpack_require__(4);
10232 var UnzonedRange_1
= __webpack_require__(5);
10233 var DateProfileGenerator
= /** @class */ (function () {
10234 function DateProfileGenerator(_view
) {
10235 this._view
= _view
;
10237 DateProfileGenerator
.prototype.opt = function (name
) {
10238 return this._view
.opt(name
);
10240 DateProfileGenerator
.prototype.trimHiddenDays = function (unzonedRange
) {
10241 return this._view
.trimHiddenDays(unzonedRange
);
10243 DateProfileGenerator
.prototype.msToUtcMoment = function (ms
, forceAllDay
) {
10244 return this._view
.calendar
.msToUtcMoment(ms
, forceAllDay
);
10246 /* Date Range Computation
10247 ------------------------------------------------------------------------------------------------------------------*/
10248 // Builds a structure with info about what the dates/ranges will be for the "prev" view.
10249 DateProfileGenerator
.prototype.buildPrev = function (currentDateProfile
) {
10250 var prevDate
= currentDateProfile
.date
.clone()
10251 .startOf(currentDateProfile
.currentRangeUnit
)
10252 .subtract(currentDateProfile
.dateIncrement
);
10253 return this.build(prevDate
, -1);
10255 // Builds a structure with info about what the dates/ranges will be for the "next" view.
10256 DateProfileGenerator
.prototype.buildNext = function (currentDateProfile
) {
10257 var nextDate
= currentDateProfile
.date
.clone()
10258 .startOf(currentDateProfile
.currentRangeUnit
)
10259 .add(currentDateProfile
.dateIncrement
);
10260 return this.build(nextDate
, 1);
10262 // Builds a structure holding dates/ranges for rendering around the given date.
10263 // Optional direction param indicates whether the date is being incremented/decremented
10264 // from its previous value. decremented = -1, incremented = 1 (default).
10265 DateProfileGenerator
.prototype.build = function (date
, direction
, forceToValid
) {
10266 if (forceToValid
=== void 0) { forceToValid
= false; }
10267 var isDateAllDay
= !date
.hasTime();
10268 var validUnzonedRange
;
10269 var minTime
= null;
10270 var maxTime
= null;
10273 var renderUnzonedRange
;
10274 var activeUnzonedRange
;
10276 validUnzonedRange
= this.buildValidRange();
10277 validUnzonedRange
= this.trimHiddenDays(validUnzonedRange
);
10278 if (forceToValid
) {
10279 date
= this.msToUtcMoment(validUnzonedRange
.constrainDate(date
), // returns MS
10282 currentInfo
= this.buildCurrentRangeInfo(date
, direction
);
10283 isRangeAllDay
= /^(year|month|week|day)$/.test(currentInfo
.unit
);
10284 renderUnzonedRange
= this.buildRenderRange(this.trimHiddenDays(currentInfo
.unzonedRange
), currentInfo
.unit
, isRangeAllDay
);
10285 renderUnzonedRange
= this.trimHiddenDays(renderUnzonedRange
);
10286 activeUnzonedRange
= renderUnzonedRange
.clone();
10287 if (!this.opt('showNonCurrentDates')) {
10288 activeUnzonedRange
= activeUnzonedRange
.intersect(currentInfo
.unzonedRange
);
10290 minTime
= moment
.duration(this.opt('minTime'));
10291 maxTime
= moment
.duration(this.opt('maxTime'));
10292 activeUnzonedRange
= this.adjustActiveRange(activeUnzonedRange
, minTime
, maxTime
);
10293 activeUnzonedRange
= activeUnzonedRange
.intersect(validUnzonedRange
); // might return null
10294 if (activeUnzonedRange
) {
10295 date
= this.msToUtcMoment(activeUnzonedRange
.constrainDate(date
), // returns MS
10298 // it's invalid if the originally requested date is not contained,
10299 // or if the range is completely outside of the valid range.
10300 isValid
= currentInfo
.unzonedRange
.intersectsWith(validUnzonedRange
);
10302 // constraint for where prev/next operations can go and where events can be dragged/resized to.
10303 // an object with optional start and end properties.
10304 validUnzonedRange
: validUnzonedRange
,
10305 // range the view is formally responsible for.
10306 // for example, a month view might have 1st-31st, excluding padded dates
10307 currentUnzonedRange
: currentInfo
.unzonedRange
,
10308 // name of largest unit being displayed, like "month" or "week"
10309 currentRangeUnit
: currentInfo
.unit
,
10310 isRangeAllDay
: isRangeAllDay
,
10311 // dates that display events and accept drag-n-drop
10312 // will be `null` if no dates accept events
10313 activeUnzonedRange
: activeUnzonedRange
,
10314 // date range with a rendered skeleton
10315 // includes not-active days that need some sort of DOM
10316 renderUnzonedRange
: renderUnzonedRange
,
10317 // Duration object that denotes the first visible time of any given day
10319 // Duration object that denotes the exclusive visible end time of any given day
10323 // how far the current date will move for a prev/next operation
10324 dateIncrement
: this.buildDateIncrement(currentInfo
.duration
)
10325 // pass a fallback (might be null) ^
10328 // Builds an object with optional start/end properties.
10329 // Indicates the minimum/maximum dates to display.
10330 // not responsible for trimming hidden days.
10331 DateProfileGenerator
.prototype.buildValidRange = function () {
10332 return this._view
.getUnzonedRangeOption('validRange', this._view
.calendar
.getNow()) ||
10333 new UnzonedRange_1
.default(); // completely open-ended
10335 // Builds a structure with info about the "current" range, the range that is
10336 // highlighted as being the current month for example.
10337 // See build() for a description of `direction`.
10338 // Guaranteed to have `range` and `unit` properties. `duration` is optional.
10339 // TODO: accept a MS-time instead of a moment `date`?
10340 DateProfileGenerator
.prototype.buildCurrentRangeInfo = function (date
, direction
) {
10341 var viewSpec
= this._view
.viewSpec
;
10342 var duration
= null;
10344 var unzonedRange
= null;
10346 if (viewSpec
.duration
) {
10347 duration
= viewSpec
.duration
;
10348 unit
= viewSpec
.durationUnit
;
10349 unzonedRange
= this.buildRangeFromDuration(date
, direction
, duration
, unit
);
10351 else if ((dayCount
= this.opt('dayCount'))) {
10353 unzonedRange
= this.buildRangeFromDayCount(date
, direction
, dayCount
);
10355 else if ((unzonedRange
= this.buildCustomVisibleRange(date
))) {
10356 unit
= util_1
.computeGreatestUnit(unzonedRange
.getStart(), unzonedRange
.getEnd());
10359 duration
= this.getFallbackDuration();
10360 unit
= util_1
.computeGreatestUnit(duration
);
10361 unzonedRange
= this.buildRangeFromDuration(date
, direction
, duration
, unit
);
10363 return { duration
: duration
, unit
: unit
, unzonedRange
: unzonedRange
};
10365 DateProfileGenerator
.prototype.getFallbackDuration = function () {
10366 return moment
.duration({ days
: 1 });
10368 // Returns a new activeUnzonedRange to have time values (un-ambiguate)
10369 // minTime or maxTime causes the range to expand.
10370 DateProfileGenerator
.prototype.adjustActiveRange = function (unzonedRange
, minTime
, maxTime
) {
10371 var start
= unzonedRange
.getStart();
10372 var end
= unzonedRange
.getEnd();
10373 if (this._view
.usesMinMaxTime
) {
10375 start
.time(0).add(minTime
);
10377 if (maxTime
> 24 * 60 * 60 * 1000) {
10378 end
.time(maxTime
- (24 * 60 * 60 * 1000));
10381 return new UnzonedRange_1
.default(start
, end
);
10383 // Builds the "current" range when it is specified as an explicit duration.
10384 // `unit` is the already-computed computeGreatestUnit value of duration.
10385 // TODO: accept a MS-time instead of a moment `date`?
10386 DateProfileGenerator
.prototype.buildRangeFromDuration = function (date
, direction
, duration
, unit
) {
10387 var alignment
= this.opt('dateAlignment');
10388 var dateIncrementInput
;
10389 var dateIncrementDuration
;
10393 // compute what the alignment should be
10395 dateIncrementInput
= this.opt('dateIncrement');
10396 if (dateIncrementInput
) {
10397 dateIncrementDuration
= moment
.duration(dateIncrementInput
);
10398 // use the smaller of the two units
10399 if (dateIncrementDuration
< duration
) {
10400 alignment
= util_1
.computeDurationGreatestUnit(dateIncrementDuration
, dateIncrementInput
);
10410 // if the view displays a single day or smaller
10411 if (duration
.as('days') <= 1) {
10412 if (this._view
.isHiddenDay(start
)) {
10413 start
= this._view
.skipHiddenDays(start
, direction
);
10414 start
.startOf('day');
10417 function computeRes() {
10418 start
= date
.clone().startOf(alignment
);
10419 end
= start
.clone().add(duration
);
10420 res
= new UnzonedRange_1
.default(start
, end
);
10423 // if range is completely enveloped by hidden days, go past the hidden days
10424 if (!this.trimHiddenDays(res
)) {
10425 date
= this._view
.skipHiddenDays(date
, direction
);
10430 // Builds the "current" range when a dayCount is specified.
10431 // TODO: accept a MS-time instead of a moment `date`?
10432 DateProfileGenerator
.prototype.buildRangeFromDayCount = function (date
, direction
, dayCount
) {
10433 var customAlignment
= this.opt('dateAlignment');
10434 var runningCount
= 0;
10435 var start
= date
.clone();
10437 if (customAlignment
) {
10438 start
.startOf(customAlignment
);
10440 start
.startOf('day');
10441 start
= this._view
.skipHiddenDays(start
, direction
);
10442 end
= start
.clone();
10445 if (!this._view
.isHiddenDay(end
)) {
10448 } while (runningCount
< dayCount
);
10449 return new UnzonedRange_1
.default(start
, end
);
10451 // Builds a normalized range object for the "visible" range,
10452 // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time.
10453 // TODO: accept a MS-time instead of a moment `date`?
10454 DateProfileGenerator
.prototype.buildCustomVisibleRange = function (date
) {
10455 var visibleUnzonedRange
= this._view
.getUnzonedRangeOption('visibleRange', this._view
.calendar
.applyTimezone(date
) // correct zone. also generates new obj that avoids mutations
10457 if (visibleUnzonedRange
&& (visibleUnzonedRange
.startMs
== null || visibleUnzonedRange
.endMs
== null)) {
10460 return visibleUnzonedRange
;
10462 // Computes the range that will represent the element/cells for *rendering*,
10463 // but which may have voided days/times.
10464 // not responsible for trimming hidden days.
10465 DateProfileGenerator
.prototype.buildRenderRange = function (currentUnzonedRange
, currentRangeUnit
, isRangeAllDay
) {
10466 return currentUnzonedRange
.clone();
10468 // Compute the duration value that should be added/substracted to the current date
10469 // when a prev/next operation happens.
10470 DateProfileGenerator
.prototype.buildDateIncrement = function (fallback
) {
10471 var dateIncrementInput
= this.opt('dateIncrement');
10472 var customAlignment
;
10473 if (dateIncrementInput
) {
10474 return moment
.duration(dateIncrementInput
);
10476 else if ((customAlignment
= this.opt('dateAlignment'))) {
10477 return moment
.duration(1, customAlignment
);
10479 else if (fallback
) {
10483 return moment
.duration({ days
: 1 });
10486 return DateProfileGenerator
;
10488 exports
.default = DateProfileGenerator
;
10493 /***/ (function(module
, exports
, __webpack_require__
) {
10495 Object
.defineProperty(exports
, "__esModule", { value
: true });
10496 var tslib_1
= __webpack_require__(2);
10497 var $ = __webpack_require__(3);
10498 var moment
= __webpack_require__(0);
10499 var exportHooks
= __webpack_require__(16);
10500 var util_1
= __webpack_require__(4);
10501 var moment_ext_1
= __webpack_require__(10);
10502 var ListenerMixin_1
= __webpack_require__(7);
10503 var HitDragListener_1
= __webpack_require__(23);
10504 var SingleEventDef_1
= __webpack_require__(13);
10505 var EventInstanceGroup_1
= __webpack_require__(18);
10506 var EventSource_1
= __webpack_require__(6);
10507 var Interaction_1
= __webpack_require__(15);
10508 var ExternalDropping
= /** @class */ (function (_super
) {
10509 tslib_1
.__extends(ExternalDropping
, _super
);
10510 function ExternalDropping() {
10511 var _this
= _super
!== null && _super
.apply(this, arguments
) || this;
10512 _this
.isDragging
= false; // jqui-dragging an external element? boolean
10516 component impements:
10517 - eventRangesToEventFootprints
10518 - isEventInstanceGroupAllowed
10519 - isExternalInstanceGroupAllowed
10523 ExternalDropping
.prototype.end = function () {
10524 if (this.dragListener
) {
10525 this.dragListener
.endInteraction();
10528 ExternalDropping
.prototype.bindToDocument = function () {
10529 this.listenTo($(document
), {
10530 dragstart
: this.handleDragStart
,
10531 sortstart
: this.handleDragStart
// jqui
10534 ExternalDropping
.prototype.unbindFromDocument = function () {
10535 this.stopListeningTo($(document
));
10537 // Called when a jQuery UI drag is initiated anywhere in the DOM
10538 ExternalDropping
.prototype.handleDragStart = function (ev
, ui
) {
10541 if (this.opt('droppable')) {
10542 el
= $((ui
? ui
.item
: null) || ev
.target
);
10543 // Test that the dragged element passes the dropAccept selector or filter function.
10544 // FYI, the default is "*" (matches all)
10545 accept
= this.opt('dropAccept');
10546 if ($.isFunction(accept
) ? accept
.call(el
[0], el
) : el
.is(accept
)) {
10547 if (!this.isDragging
) {
10548 this.listenToExternalDrag(el
, ev
, ui
);
10553 // Called when a jQuery UI drag starts and it needs to be monitored for dropping
10554 ExternalDropping
.prototype.listenToExternalDrag = function (el
, ev
, ui
) {
10556 var component
= this.component
;
10557 var view
= this.view
;
10558 var meta
= getDraggedElMeta(el
); // extra data about event drop, including possible event to create
10559 var singleEventDef
; // a null value signals an unsuccessful drag
10560 // listener that tracks mouse movement over date-associated pixel regions
10561 var dragListener
= this.dragListener
= new HitDragListener_1
.default(component
, {
10562 interactionStart: function () {
10563 _this
.isDragging
= true;
10565 hitOver: function (hit
) {
10566 var isAllowed
= true;
10567 var hitFootprint
= hit
.component
.getSafeHitFootprint(hit
); // hit might not belong to this grid
10568 var mutatedEventInstanceGroup
;
10569 if (hitFootprint
) {
10570 singleEventDef
= _this
.computeExternalDrop(hitFootprint
, meta
);
10571 if (singleEventDef
) {
10572 mutatedEventInstanceGroup
= new EventInstanceGroup_1
.default(singleEventDef
.buildInstances());
10573 isAllowed
= meta
.eventProps
? // isEvent?
10574 component
.isEventInstanceGroupAllowed(mutatedEventInstanceGroup
) :
10575 component
.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup
);
10585 singleEventDef
= null;
10586 util_1
.disableCursor();
10588 if (singleEventDef
) {
10589 component
.renderDrag(// called without a seg parameter
10590 component
.eventRangesToEventFootprints(mutatedEventInstanceGroup
.sliceRenderRanges(component
.dateProfile
.renderUnzonedRange
, view
.calendar
)));
10593 hitOut: function () {
10594 singleEventDef
= null; // signal unsuccessful
10596 hitDone: function () {
10597 util_1
.enableCursor();
10598 component
.unrenderDrag();
10600 interactionEnd: function (ev
) {
10601 if (singleEventDef
) {
10602 view
.reportExternalDrop(singleEventDef
, Boolean(meta
.eventProps
), // isEvent
10603 Boolean(meta
.stick
), // isSticky
10606 _this
.isDragging
= false;
10607 _this
.dragListener
= null;
10610 dragListener
.startDrag(ev
); // start listening immediately
10612 // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),
10613 // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null.
10614 // Returning a null value signals an invalid drop hit.
10615 // DOES NOT consider overlap/constraint.
10616 // Assumes both footprints are non-open-ended.
10617 ExternalDropping
.prototype.computeExternalDrop = function (componentFootprint
, meta
) {
10618 var calendar
= this.view
.calendar
;
10619 var start
= moment_ext_1
.default.utc(componentFootprint
.unzonedRange
.startMs
).stripZone();
10622 if (componentFootprint
.isAllDay
) {
10623 // if dropped on an all-day span, and element's metadata specified a time, set it
10624 if (meta
.startTime
) {
10625 start
.time(meta
.startTime
);
10631 if (meta
.duration
) {
10632 end
= start
.clone().add(meta
.duration
);
10634 start
= calendar
.applyTimezone(start
);
10636 end
= calendar
.applyTimezone(end
);
10638 eventDef
= SingleEventDef_1
.default.parse($.extend({}, meta
.eventProps
, {
10641 }), new EventSource_1
.default(calendar
));
10644 return ExternalDropping
;
10645 }(Interaction_1
.default));
10646 exports
.default = ExternalDropping
;
10647 ListenerMixin_1
.default.mixInto(ExternalDropping
);
10648 /* External-Dragging-Element Data
10649 ----------------------------------------------------------------------------------------------------------------------*/
10650 // Require all HTML5 data-* attributes used by FullCalendar to have this prefix.
10651 // A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.
10652 exportHooks
.dataAttrPrefix
= '';
10653 // Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure
10654 // to be used for Event Object creation.
10655 // A defined `.eventProps`, even when empty, indicates that an event should be created.
10656 function getDraggedElMeta(el
) {
10657 var prefix
= exportHooks
.dataAttrPrefix
;
10658 var eventProps
; // properties for creating the event, not related to date/time
10659 var startTime
; // a Duration
10665 eventProps
= el
.data(prefix
+ 'event') || null;
10667 if (typeof eventProps
=== 'object') {
10668 eventProps
= $.extend({}, eventProps
); // make a copy
10673 // pluck special-cased date/time properties
10674 startTime
= eventProps
.start
;
10675 if (startTime
== null) {
10676 startTime
= eventProps
.time
;
10677 } // accept 'time' as well
10678 duration
= eventProps
.duration
;
10679 stick
= eventProps
.stick
;
10680 delete eventProps
.start
;
10681 delete eventProps
.time
;
10682 delete eventProps
.duration
;
10683 delete eventProps
.stick
;
10685 // fallback to standalone attribute values for each of the date/time properties
10686 if (startTime
== null) {
10687 startTime
= el
.data(prefix
+ 'start');
10689 if (startTime
== null) {
10690 startTime
= el
.data(prefix
+ 'time');
10691 } // accept 'time' as well
10692 if (duration
== null) {
10693 duration
= el
.data(prefix
+ 'duration');
10695 if (stick
== null) {
10696 stick
= el
.data(prefix
+ 'stick');
10698 // massage into correct data types
10699 startTime
= startTime
!= null ? moment
.duration(startTime
) : null;
10700 duration
= duration
!= null ? moment
.duration(duration
) : null;
10701 stick
= Boolean(stick
);
10702 return { eventProps
: eventProps
, startTime
: startTime
, duration
: duration
, stick
: stick
};
10708 /***/ (function(module
, exports
, __webpack_require__
) {
10710 Object
.defineProperty(exports
, "__esModule", { value
: true });
10711 var tslib_1
= __webpack_require__(2);
10712 var $ = __webpack_require__(3);
10713 var util_1
= __webpack_require__(4);
10714 var EventDefMutation_1
= __webpack_require__(37);
10715 var EventDefDateMutation_1
= __webpack_require__(50);
10716 var HitDragListener_1
= __webpack_require__(23);
10717 var Interaction_1
= __webpack_require__(15);
10718 var EventResizing
= /** @class */ (function (_super
) {
10719 tslib_1
.__extends(EventResizing
, _super
);
10721 component impements:
10722 - bindSegHandlerToEl
10725 - eventRangesToEventFootprints
10726 - isEventInstanceGroupAllowed
10727 - getSafeHitFootprint
10729 function EventResizing(component
, eventPointing
) {
10730 var _this
= _super
.call(this, component
) || this;
10731 _this
.isResizing
= false;
10732 _this
.eventPointing
= eventPointing
;
10735 EventResizing
.prototype.end = function () {
10736 if (this.dragListener
) {
10737 this.dragListener
.endInteraction();
10740 EventResizing
.prototype.bindToEl = function (el
) {
10741 var component
= this.component
;
10742 component
.bindSegHandlerToEl(el
, 'mousedown', this.handleMouseDown
.bind(this));
10743 component
.bindSegHandlerToEl(el
, 'touchstart', this.handleTouchStart
.bind(this));
10745 EventResizing
.prototype.handleMouseDown = function (seg
, ev
) {
10746 if (this.component
.canStartResize(seg
, ev
)) {
10747 this.buildDragListener(seg
, $(ev
.target
).is('.fc-start-resizer'))
10748 .startInteraction(ev
, { distance
: 5 });
10751 EventResizing
.prototype.handleTouchStart = function (seg
, ev
) {
10752 if (this.component
.canStartResize(seg
, ev
)) {
10753 this.buildDragListener(seg
, $(ev
.target
).is('.fc-start-resizer'))
10754 .startInteraction(ev
);
10757 // Creates a listener that tracks the user as they resize an event segment.
10758 // Generic enough to work with any type of Grid.
10759 EventResizing
.prototype.buildDragListener = function (seg
, isStart
) {
10761 var component
= this.component
;
10762 var view
= this.view
;
10763 var calendar
= view
.calendar
;
10764 var eventManager
= calendar
.eventManager
;
10766 var eventDef
= seg
.footprint
.eventDef
;
10767 var eventInstance
= seg
.footprint
.eventInstance
;
10769 var resizeMutation
; // zoned event date properties. falsy if invalid resize
10770 // Tracks mouse movement over the *grid's* coordinate map
10771 var dragListener
= this.dragListener
= new HitDragListener_1
.default(component
, {
10772 scroll
: this.opt('dragScroll'),
10774 interactionStart: function () {
10775 isDragging
= false;
10777 dragStart: function (ev
) {
10779 // ensure a mouseout on the manipulated event has been reported
10780 _this
.eventPointing
.handleMouseout(seg
, ev
);
10781 _this
.segResizeStart(seg
, ev
);
10783 hitOver: function (hit
, isOrig
, origHit
) {
10784 var isAllowed
= true;
10785 var origHitFootprint
= component
.getSafeHitFootprint(origHit
);
10786 var hitFootprint
= component
.getSafeHitFootprint(hit
);
10787 var mutatedEventInstanceGroup
;
10788 if (origHitFootprint
&& hitFootprint
) {
10789 resizeMutation
= isStart
?
10790 _this
.computeEventStartResizeMutation(origHitFootprint
, hitFootprint
, seg
.footprint
) :
10791 _this
.computeEventEndResizeMutation(origHitFootprint
, hitFootprint
, seg
.footprint
);
10792 if (resizeMutation
) {
10793 mutatedEventInstanceGroup
= eventManager
.buildMutatedEventInstanceGroup(eventDef
.id
, resizeMutation
);
10794 isAllowed
= component
.isEventInstanceGroupAllowed(mutatedEventInstanceGroup
);
10804 resizeMutation
= null;
10805 util_1
.disableCursor();
10807 else if (resizeMutation
.isEmpty()) {
10808 // no change. (FYI, event dates might have zones)
10809 resizeMutation
= null;
10811 if (resizeMutation
) {
10812 view
.hideEventsWithId(seg
.footprint
.eventDef
.id
);
10813 view
.renderEventResize(component
.eventRangesToEventFootprints(mutatedEventInstanceGroup
.sliceRenderRanges(component
.dateProfile
.renderUnzonedRange
, calendar
)), seg
);
10816 hitOut: function () {
10817 resizeMutation
= null;
10819 hitDone: function () {
10820 view
.unrenderEventResize(seg
);
10821 view
.showEventsWithId(seg
.footprint
.eventDef
.id
);
10822 util_1
.enableCursor();
10824 interactionEnd: function (ev
) {
10826 _this
.segResizeStop(seg
, ev
);
10828 if (resizeMutation
) {
10829 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
10830 view
.reportEventResize(eventInstance
, resizeMutation
, el
, ev
);
10832 _this
.dragListener
= null;
10835 return dragListener
;
10837 // Called before event segment resizing starts
10838 EventResizing
.prototype.segResizeStart = function (seg
, ev
) {
10839 this.isResizing
= true;
10840 this.component
.publiclyTrigger('eventResizeStart', {
10841 context
: seg
.el
[0],
10843 seg
.footprint
.getEventLegacy(),
10850 // Called after event segment resizing stops
10851 EventResizing
.prototype.segResizeStop = function (seg
, ev
) {
10852 this.isResizing
= false;
10853 this.component
.publiclyTrigger('eventResizeStop', {
10854 context
: seg
.el
[0],
10856 seg
.footprint
.getEventLegacy(),
10863 // Returns new date-information for an event segment being resized from its start
10864 EventResizing
.prototype.computeEventStartResizeMutation = function (startFootprint
, endFootprint
, origEventFootprint
) {
10865 var origRange
= origEventFootprint
.componentFootprint
.unzonedRange
;
10866 var startDelta
= this.component
.diffDates(endFootprint
.unzonedRange
.getStart(), startFootprint
.unzonedRange
.getStart());
10868 var eventDefMutation
;
10869 if (origRange
.getStart().add(startDelta
) < origRange
.getEnd()) {
10870 dateMutation
= new EventDefDateMutation_1
.default();
10871 dateMutation
.setStartDelta(startDelta
);
10872 eventDefMutation
= new EventDefMutation_1
.default();
10873 eventDefMutation
.setDateMutation(dateMutation
);
10874 return eventDefMutation
;
10878 // Returns new date-information for an event segment being resized from its end
10879 EventResizing
.prototype.computeEventEndResizeMutation = function (startFootprint
, endFootprint
, origEventFootprint
) {
10880 var origRange
= origEventFootprint
.componentFootprint
.unzonedRange
;
10881 var endDelta
= this.component
.diffDates(endFootprint
.unzonedRange
.getEnd(), startFootprint
.unzonedRange
.getEnd());
10883 var eventDefMutation
;
10884 if (origRange
.getEnd().add(endDelta
) > origRange
.getStart()) {
10885 dateMutation
= new EventDefDateMutation_1
.default();
10886 dateMutation
.setEndDelta(endDelta
);
10887 eventDefMutation
= new EventDefMutation_1
.default();
10888 eventDefMutation
.setDateMutation(dateMutation
);
10889 return eventDefMutation
;
10893 return EventResizing
;
10894 }(Interaction_1
.default));
10895 exports
.default = EventResizing
;
10900 /***/ (function(module
, exports
, __webpack_require__
) {
10902 Object
.defineProperty(exports
, "__esModule", { value
: true });
10903 var tslib_1
= __webpack_require__(2);
10904 var util_1
= __webpack_require__(4);
10905 var EventDefMutation_1
= __webpack_require__(37);
10906 var EventDefDateMutation_1
= __webpack_require__(50);
10907 var DragListener_1
= __webpack_require__(54);
10908 var HitDragListener_1
= __webpack_require__(23);
10909 var MouseFollower_1
= __webpack_require__(244);
10910 var Interaction_1
= __webpack_require__(15);
10911 var EventDragging
= /** @class */ (function (_super
) {
10912 tslib_1
.__extends(EventDragging
, _super
);
10914 component implements:
10915 - bindSegHandlerToEl
10918 - eventRangesToEventFootprints
10919 - isEventInstanceGroupAllowed
10921 function EventDragging(component
, eventPointing
) {
10922 var _this
= _super
.call(this, component
) || this;
10923 _this
.isDragging
= false;
10924 _this
.eventPointing
= eventPointing
;
10927 EventDragging
.prototype.end = function () {
10928 if (this.dragListener
) {
10929 this.dragListener
.endInteraction();
10932 EventDragging
.prototype.getSelectionDelay = function () {
10933 var delay
= this.opt('eventLongPressDelay');
10934 if (delay
== null) {
10935 delay
= this.opt('longPressDelay'); // fallback
10939 EventDragging
.prototype.bindToEl = function (el
) {
10940 var component
= this.component
;
10941 component
.bindSegHandlerToEl(el
, 'mousedown', this.handleMousedown
.bind(this));
10942 component
.bindSegHandlerToEl(el
, 'touchstart', this.handleTouchStart
.bind(this));
10944 EventDragging
.prototype.handleMousedown = function (seg
, ev
) {
10945 if (!this.component
.shouldIgnoreMouse() &&
10946 this.component
.canStartDrag(seg
, ev
)) {
10947 this.buildDragListener(seg
).startInteraction(ev
, { distance
: 5 });
10950 EventDragging
.prototype.handleTouchStart = function (seg
, ev
) {
10951 var component
= this.component
;
10953 delay
: this.view
.isEventDefSelected(seg
.footprint
.eventDef
) ? // already selected?
10954 0 : this.getSelectionDelay()
10956 if (component
.canStartDrag(seg
, ev
)) {
10957 this.buildDragListener(seg
).startInteraction(ev
, settings
);
10959 else if (component
.canStartSelection(seg
, ev
)) {
10960 this.buildSelectListener(seg
).startInteraction(ev
, settings
);
10963 // seg isn't draggable, but let's use a generic DragListener
10964 // simply for the delay, so it can be selected.
10965 // Has side effect of setting/unsetting `dragListener`
10966 EventDragging
.prototype.buildSelectListener = function (seg
) {
10968 var view
= this.view
;
10969 var eventDef
= seg
.footprint
.eventDef
;
10970 var eventInstance
= seg
.footprint
.eventInstance
; // null for inverse-background events
10971 if (this.dragListener
) {
10972 return this.dragListener
;
10974 var dragListener
= this.dragListener
= new DragListener_1
.default({
10975 dragStart: function (ev
) {
10976 if (dragListener
.isTouch
&&
10977 !view
.isEventDefSelected(eventDef
) &&
10979 // if not previously selected, will fire after a delay. then, select the event
10980 view
.selectEventInstance(eventInstance
);
10983 interactionEnd: function (ev
) {
10984 _this
.dragListener
= null;
10987 return dragListener
;
10989 // Builds a listener that will track user-dragging on an event segment.
10990 // Generic enough to work with any type of Grid.
10991 // Has side effect of setting/unsetting `dragListener`
10992 EventDragging
.prototype.buildDragListener = function (seg
) {
10994 var component
= this.component
;
10995 var view
= this.view
;
10996 var calendar
= view
.calendar
;
10997 var eventManager
= calendar
.eventManager
;
10999 var eventDef
= seg
.footprint
.eventDef
;
11000 var eventInstance
= seg
.footprint
.eventInstance
; // null for inverse-background events
11002 var mouseFollower
; // A clone of the original element that will move with the mouse
11003 var eventDefMutation
;
11004 if (this.dragListener
) {
11005 return this.dragListener
;
11007 // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
11009 var dragListener
= this.dragListener
= new HitDragListener_1
.default(view
, {
11010 scroll
: this.opt('dragScroll'),
11012 subjectCenter
: true,
11013 interactionStart: function (ev
) {
11014 seg
.component
= component
; // for renderDrag
11015 isDragging
= false;
11016 mouseFollower
= new MouseFollower_1
.default(seg
.el
, {
11017 additionalClass
: 'fc-dragging',
11019 opacity
: dragListener
.isTouch
? null : _this
.opt('dragOpacity'),
11020 revertDuration
: _this
.opt('dragRevertDuration'),
11021 zIndex
: 2 // one above the .fc-view
11023 mouseFollower
.hide(); // don't show until we know this is a real drag
11024 mouseFollower
.start(ev
);
11026 dragStart: function (ev
) {
11027 if (dragListener
.isTouch
&&
11028 !view
.isEventDefSelected(eventDef
) &&
11030 // if not previously selected, will fire after a delay. then, select the event
11031 view
.selectEventInstance(eventInstance
);
11034 // ensure a mouseout on the manipulated event has been reported
11035 _this
.eventPointing
.handleMouseout(seg
, ev
);
11036 _this
.segDragStart(seg
, ev
);
11037 view
.hideEventsWithId(seg
.footprint
.eventDef
.id
);
11039 hitOver: function (hit
, isOrig
, origHit
) {
11040 var isAllowed
= true;
11043 var mutatedEventInstanceGroup
;
11044 // starting hit could be forced (DayGrid.limit)
11048 // hit might not belong to this grid, so query origin grid
11049 origFootprint
= origHit
.component
.getSafeHitFootprint(origHit
);
11050 footprint
= hit
.component
.getSafeHitFootprint(hit
);
11051 if (origFootprint
&& footprint
) {
11052 eventDefMutation
= _this
.computeEventDropMutation(origFootprint
, footprint
, eventDef
);
11053 if (eventDefMutation
) {
11054 mutatedEventInstanceGroup
= eventManager
.buildMutatedEventInstanceGroup(eventDef
.id
, eventDefMutation
);
11055 isAllowed
= component
.isEventInstanceGroupAllowed(mutatedEventInstanceGroup
);
11065 eventDefMutation
= null;
11066 util_1
.disableCursor();
11068 // if a valid drop location, have the subclass render a visual indication
11069 if (eventDefMutation
&&
11070 view
.renderDrag(// truthy if rendered something
11071 component
.eventRangesToEventFootprints(mutatedEventInstanceGroup
.sliceRenderRanges(component
.dateProfile
.renderUnzonedRange
, calendar
)), seg
, dragListener
.isTouch
)) {
11072 mouseFollower
.hide(); // if the subclass is already using a mock event "helper", hide our own
11075 mouseFollower
.show(); // otherwise, have the helper follow the mouse (no snapping)
11078 // needs to have moved hits to be a valid drop
11079 eventDefMutation
= null;
11082 hitOut: function () {
11083 view
.unrenderDrag(seg
); // unrender whatever was done in renderDrag
11084 mouseFollower
.show(); // show in case we are moving out of all hits
11085 eventDefMutation
= null;
11087 hitDone: function () {
11088 util_1
.enableCursor();
11090 interactionEnd: function (ev
) {
11091 delete seg
.component
; // prevent side effects
11092 // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
11093 mouseFollower
.stop(!eventDefMutation
, function () {
11095 view
.unrenderDrag(seg
);
11096 _this
.segDragStop(seg
, ev
);
11098 view
.showEventsWithId(seg
.footprint
.eventDef
.id
);
11099 if (eventDefMutation
) {
11100 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
11101 view
.reportEventDrop(eventInstance
, eventDefMutation
, el
, ev
);
11104 _this
.dragListener
= null;
11107 return dragListener
;
11109 // Called before event segment dragging starts
11110 EventDragging
.prototype.segDragStart = function (seg
, ev
) {
11111 this.isDragging
= true;
11112 this.component
.publiclyTrigger('eventDragStart', {
11113 context
: seg
.el
[0],
11115 seg
.footprint
.getEventLegacy(),
11122 // Called after event segment dragging stops
11123 EventDragging
.prototype.segDragStop = function (seg
, ev
) {
11124 this.isDragging
= false;
11125 this.component
.publiclyTrigger('eventDragStop', {
11126 context
: seg
.el
[0],
11128 seg
.footprint
.getEventLegacy(),
11135 // DOES NOT consider overlap/constraint
11136 EventDragging
.prototype.computeEventDropMutation = function (startFootprint
, endFootprint
, eventDef
) {
11137 var eventDefMutation
= new EventDefMutation_1
.default();
11138 eventDefMutation
.setDateMutation(this.computeEventDateMutation(startFootprint
, endFootprint
));
11139 return eventDefMutation
;
11141 EventDragging
.prototype.computeEventDateMutation = function (startFootprint
, endFootprint
) {
11142 var date0
= startFootprint
.unzonedRange
.getStart();
11143 var date1
= endFootprint
.unzonedRange
.getStart();
11144 var clearEnd
= false;
11145 var forceTimed
= false;
11146 var forceAllDay
= false;
11149 if (startFootprint
.isAllDay
!== endFootprint
.isAllDay
) {
11151 if (endFootprint
.isAllDay
) {
11152 forceAllDay
= true;
11159 dateDelta
= this.component
.diffDates(date1
, date0
);
11160 dateMutation
= new EventDefDateMutation_1
.default();
11161 dateMutation
.clearEnd
= clearEnd
;
11162 dateMutation
.forceTimed
= forceTimed
;
11163 dateMutation
.forceAllDay
= forceAllDay
;
11164 dateMutation
.setDateDelta(dateDelta
);
11165 return dateMutation
;
11167 return EventDragging
;
11168 }(Interaction_1
.default));
11169 exports
.default = EventDragging
;
11174 /***/ (function(module
, exports
, __webpack_require__
) {
11176 Object
.defineProperty(exports
, "__esModule", { value
: true });
11177 var tslib_1
= __webpack_require__(2);
11178 var util_1
= __webpack_require__(4);
11179 var HitDragListener_1
= __webpack_require__(23);
11180 var ComponentFootprint_1
= __webpack_require__(12);
11181 var UnzonedRange_1
= __webpack_require__(5);
11182 var Interaction_1
= __webpack_require__(15);
11183 var DateSelecting
= /** @class */ (function (_super
) {
11184 tslib_1
.__extends(DateSelecting
, _super
);
11186 component must implement:
11187 - bindDateHandlerToEl
11188 - getSafeHitFootprint
11190 - unrenderHighlight
11192 function DateSelecting(component
) {
11193 var _this
= _super
.call(this, component
) || this;
11194 _this
.dragListener
= _this
.buildDragListener();
11197 DateSelecting
.prototype.end = function () {
11198 this.dragListener
.endInteraction();
11200 DateSelecting
.prototype.getDelay = function () {
11201 var delay
= this.opt('selectLongPressDelay');
11202 if (delay
== null) {
11203 delay
= this.opt('longPressDelay'); // fallback
11207 DateSelecting
.prototype.bindToEl = function (el
) {
11209 var component
= this.component
;
11210 var dragListener
= this.dragListener
;
11211 component
.bindDateHandlerToEl(el
, 'mousedown', function (ev
) {
11212 if (_this
.opt('selectable') && !component
.shouldIgnoreMouse()) {
11213 dragListener
.startInteraction(ev
, {
11214 distance
: _this
.opt('selectMinDistance')
11218 component
.bindDateHandlerToEl(el
, 'touchstart', function (ev
) {
11219 if (_this
.opt('selectable') && !component
.shouldIgnoreTouch()) {
11220 dragListener
.startInteraction(ev
, {
11221 delay
: _this
.getDelay()
11225 util_1
.preventSelection(el
);
11227 // Creates a listener that tracks the user's drag across day elements, for day selecting.
11228 DateSelecting
.prototype.buildDragListener = function () {
11230 var component
= this.component
;
11231 var selectionFootprint
; // null if invalid selection
11232 var dragListener
= new HitDragListener_1
.default(component
, {
11233 scroll
: this.opt('dragScroll'),
11234 interactionStart: function () {
11235 selectionFootprint
= null;
11237 dragStart: function (ev
) {
11238 _this
.view
.unselect(ev
); // since we could be rendering a new selection, we want to clear any old one
11240 hitOver: function (hit
, isOrig
, origHit
) {
11241 var origHitFootprint
;
11244 origHitFootprint
= component
.getSafeHitFootprint(origHit
);
11245 hitFootprint
= component
.getSafeHitFootprint(hit
);
11246 if (origHitFootprint
&& hitFootprint
) {
11247 selectionFootprint
= _this
.computeSelection(origHitFootprint
, hitFootprint
);
11250 selectionFootprint
= null;
11252 if (selectionFootprint
) {
11253 component
.renderSelectionFootprint(selectionFootprint
);
11255 else if (selectionFootprint
=== false) {
11256 util_1
.disableCursor();
11260 hitOut: function () {
11261 selectionFootprint
= null;
11262 component
.unrenderSelection();
11264 hitDone: function () {
11265 util_1
.enableCursor();
11267 interactionEnd: function (ev
, isCancelled
) {
11268 if (!isCancelled
&& selectionFootprint
) {
11269 // the selection will already have been rendered. just report it
11270 _this
.view
.reportSelection(selectionFootprint
, ev
);
11274 return dragListener
;
11276 // Given the first and last date-spans of a selection, returns another date-span object.
11277 // Subclasses can override and provide additional data in the span object. Will be passed to renderSelectionFootprint().
11278 // Will return false if the selection is invalid and this should be indicated to the user.
11279 // Will return null/undefined if a selection invalid but no error should be reported.
11280 DateSelecting
.prototype.computeSelection = function (footprint0
, footprint1
) {
11281 var wholeFootprint
= this.computeSelectionFootprint(footprint0
, footprint1
);
11282 if (wholeFootprint
&& !this.isSelectionFootprintAllowed(wholeFootprint
)) {
11285 return wholeFootprint
;
11287 // Given two spans, must return the combination of the two.
11288 // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.
11289 // Assumes both footprints are non-open-ended.
11290 DateSelecting
.prototype.computeSelectionFootprint = function (footprint0
, footprint1
) {
11292 footprint0
.unzonedRange
.startMs
,
11293 footprint0
.unzonedRange
.endMs
,
11294 footprint1
.unzonedRange
.startMs
,
11295 footprint1
.unzonedRange
.endMs
11297 ms
.sort(util_1
.compareNumbers
);
11298 return new ComponentFootprint_1
.default(new UnzonedRange_1
.default(ms
[0], ms
[3]), footprint0
.isAllDay
);
11300 DateSelecting
.prototype.isSelectionFootprintAllowed = function (componentFootprint
) {
11301 return this.component
.dateProfile
.validUnzonedRange
.containsRange(componentFootprint
.unzonedRange
) &&
11302 this.view
.calendar
.constraints
.isSelectionFootprintAllowed(componentFootprint
);
11304 return DateSelecting
;
11305 }(Interaction_1
.default));
11306 exports
.default = DateSelecting
;
11311 /***/ (function(module
, exports
, __webpack_require__
) {
11313 Object
.defineProperty(exports
, "__esModule", { value
: true });
11314 var tslib_1
= __webpack_require__(2);
11315 var moment
= __webpack_require__(0);
11316 var $ = __webpack_require__(3);
11317 var util_1
= __webpack_require__(4);
11318 var Scroller_1
= __webpack_require__(39);
11319 var View_1
= __webpack_require__(41);
11320 var TimeGrid_1
= __webpack_require__(227);
11321 var DayGrid_1
= __webpack_require__(61);
11322 var AGENDA_ALL_DAY_EVENT_LIMIT
= 5;
11323 var agendaTimeGridMethods
;
11324 var agendaDayGridMethods
;
11325 /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
11326 ----------------------------------------------------------------------------------------------------------------------*/
11327 // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
11328 // Responsible for managing width/height.
11329 var AgendaView
= /** @class */ (function (_super
) {
11330 tslib_1
.__extends(AgendaView
, _super
);
11331 function AgendaView(calendar
, viewSpec
) {
11332 var _this
= _super
.call(this, calendar
, viewSpec
) || this;
11333 _this
.usesMinMaxTime
= true; // indicates that minTime/maxTime affects rendering
11334 _this
.timeGrid
= _this
.instantiateTimeGrid();
11335 _this
.addChild(_this
.timeGrid
);
11336 if (_this
.opt('allDaySlot')) {
11337 _this
.dayGrid
= _this
.instantiateDayGrid(); // the all-day subcomponent of this view
11338 _this
.addChild(_this
.dayGrid
);
11340 _this
.scroller
= new Scroller_1
.default({
11341 overflowX
: 'hidden',
11346 // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
11347 AgendaView
.prototype.instantiateTimeGrid = function () {
11348 var timeGrid
= new this.timeGridClass(this);
11349 util_1
.copyOwnProps(agendaTimeGridMethods
, timeGrid
);
11352 // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
11353 AgendaView
.prototype.instantiateDayGrid = function () {
11354 var dayGrid
= new this.dayGridClass(this);
11355 util_1
.copyOwnProps(agendaDayGridMethods
, dayGrid
);
11359 ------------------------------------------------------------------------------------------------------------------*/
11360 AgendaView
.prototype.renderSkeleton = function () {
11361 var timeGridWrapEl
;
11363 this.el
.addClass('fc-agenda-view').html(this.renderSkeletonHtml());
11364 this.scroller
.render();
11365 timeGridWrapEl
= this.scroller
.el
.addClass('fc-time-grid-container');
11366 timeGridEl
= $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl
);
11367 this.el
.find('.fc-body > tr > td').append(timeGridWrapEl
);
11368 this.timeGrid
.headContainerEl
= this.el
.find('.fc-head-container');
11369 this.timeGrid
.setElement(timeGridEl
);
11370 if (this.dayGrid
) {
11371 this.dayGrid
.setElement(this.el
.find('.fc-day-grid'));
11372 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
11373 this.dayGrid
.bottomCoordPadding
= this.dayGrid
.el
.next('hr').outerHeight();
11376 AgendaView
.prototype.unrenderSkeleton = function () {
11377 this.timeGrid
.removeElement();
11378 if (this.dayGrid
) {
11379 this.dayGrid
.removeElement();
11381 this.scroller
.destroy();
11383 // Builds the HTML skeleton for the view.
11384 // The day-grid and time-grid components will render inside containers defined by this HTML.
11385 AgendaView
.prototype.renderSkeletonHtml = function () {
11386 var theme
= this.calendar
.theme
;
11388 '<table class="' + theme
.getClass('tableGrid') + '">' +
11389 (this.opt('columnHeader') ?
11390 '<thead class="fc-head">' +
11392 '<td class="fc-head-container ' + theme
.getClass('widgetHeader') + '"> </td>' +
11396 '<tbody class="fc-body">' +
11398 '<td class="' + theme
.getClass('widgetContent') + '">' +
11400 '<div class="fc-day-grid"/>' +
11401 '<hr class="fc-divider ' + theme
.getClass('widgetHeader') + '"/>' :
11408 // Generates an HTML attribute string for setting the width of the axis, if it is known
11409 AgendaView
.prototype.axisStyleAttr = function () {
11410 if (this.axisWidth
!= null) {
11411 return 'style="width:' + this.axisWidth
+ 'px"';
11416 ------------------------------------------------------------------------------------------------------------------*/
11417 AgendaView
.prototype.getNowIndicatorUnit = function () {
11418 return this.timeGrid
.getNowIndicatorUnit();
11421 ------------------------------------------------------------------------------------------------------------------*/
11422 // Adjusts the vertical dimensions of the view to the specified values
11423 AgendaView
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
11425 var scrollerHeight
;
11426 var scrollbarWidths
;
11427 _super
.prototype.updateSize
.call(this, totalHeight
, isAuto
, isResize
);
11428 // make all axis cells line up, and record the width so newly created axis cells will have it
11429 this.axisWidth
= util_1
.matchCellWidths(this.el
.find('.fc-axis'));
11430 // hack to give the view some height prior to timeGrid's columns being rendered
11431 // TODO: separate setting height from scroller VS timeGrid.
11432 if (!this.timeGrid
.colEls
) {
11434 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
11435 this.scroller
.setHeight(scrollerHeight
);
11439 // set of fake row elements that must compensate when scroller has scrollbars
11440 var noScrollRowEls
= this.el
.find('.fc-row:not(.fc-scroller *)');
11441 // reset all dimensions back to the original state
11442 this.timeGrid
.bottomRuleEl
.hide(); // .show() will be called later if this <hr> is necessary
11443 this.scroller
.clear(); // sets height to 'auto' and clears overflow
11444 util_1
.uncompensateScroll(noScrollRowEls
);
11445 // limit number of events in the all-day area
11446 if (this.dayGrid
) {
11447 this.dayGrid
.removeSegPopover(); // kill the "more" popover if displayed
11448 eventLimit
= this.opt('eventLimit');
11449 if (eventLimit
&& typeof eventLimit
!== 'number') {
11450 eventLimit
= AGENDA_ALL_DAY_EVENT_LIMIT
; // make sure "auto" goes to a real number
11453 this.dayGrid
.limitRows(eventLimit
);
11457 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
11458 this.scroller
.setHeight(scrollerHeight
);
11459 scrollbarWidths
= this.scroller
.getScrollbarWidths();
11460 if (scrollbarWidths
.left
|| scrollbarWidths
.right
) {
11461 // make the all-day and header rows lines up
11462 util_1
.compensateScroll(noScrollRowEls
, scrollbarWidths
);
11463 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
11464 // and reapply the desired height to the scroller.
11465 scrollerHeight
= this.computeScrollerHeight(totalHeight
);
11466 this.scroller
.setHeight(scrollerHeight
);
11468 // guarantees the same scrollbar widths
11469 this.scroller
.lockOverflow(scrollbarWidths
);
11470 // if there's any space below the slats, show the horizontal rule.
11471 // this won't cause any new overflow, because lockOverflow already called.
11472 if (this.timeGrid
.getTotalSlatHeight() < scrollerHeight
) {
11473 this.timeGrid
.bottomRuleEl
.show();
11477 // given a desired total height of the view, returns what the height of the scroller should be
11478 AgendaView
.prototype.computeScrollerHeight = function (totalHeight
) {
11479 return totalHeight
-
11480 util_1
.subtractInnerElHeight(this.el
, this.scroller
.el
); // everything that's NOT the scroller
11483 ------------------------------------------------------------------------------------------------------------------*/
11484 // Computes the initial pre-configured scroll state prior to allowing the user to change it
11485 AgendaView
.prototype.computeInitialDateScroll = function () {
11486 var scrollTime
= moment
.duration(this.opt('scrollTime'));
11487 var top
= this.timeGrid
.computeTimeTop(scrollTime
);
11488 // zoom can give weird floating-point values. rather scroll a little bit further
11489 top
= Math
.ceil(top
);
11491 top
++; // to overcome top border that slots beyond the first have. looks better
11493 return { top
: top
};
11495 AgendaView
.prototype.queryDateScroll = function () {
11496 return { top
: this.scroller
.getScrollTop() };
11498 AgendaView
.prototype.applyDateScroll = function (scroll
) {
11499 if (scroll
.top
!== undefined) {
11500 this.scroller
.setScrollTop(scroll
.top
);
11504 ------------------------------------------------------------------------------------------------------------------*/
11505 // forward all hit-related method calls to the grids (dayGrid might not be defined)
11506 AgendaView
.prototype.getHitFootprint = function (hit
) {
11507 // TODO: hit.component is set as a hack to identify where the hit came from
11508 return hit
.component
.getHitFootprint(hit
);
11510 AgendaView
.prototype.getHitEl = function (hit
) {
11511 // TODO: hit.component is set as a hack to identify where the hit came from
11512 return hit
.component
.getHitEl(hit
);
11515 ------------------------------------------------------------------------------------------------------------------*/
11516 AgendaView
.prototype.executeEventRender = function (eventsPayload
) {
11517 var dayEventsPayload
= {};
11518 var timedEventsPayload
= {};
11520 var eventInstanceGroup
;
11521 // separate the events into all-day and timed
11522 for (id
in eventsPayload
) {
11523 eventInstanceGroup
= eventsPayload
[id
];
11524 if (eventInstanceGroup
.getEventDef().isAllDay()) {
11525 dayEventsPayload
[id
] = eventInstanceGroup
;
11528 timedEventsPayload
[id
] = eventInstanceGroup
;
11531 this.timeGrid
.executeEventRender(timedEventsPayload
);
11532 if (this.dayGrid
) {
11533 this.dayGrid
.executeEventRender(dayEventsPayload
);
11536 /* Dragging/Resizing Routing
11537 ------------------------------------------------------------------------------------------------------------------*/
11538 // A returned value of `true` signals that a mock "helper" event has been rendered.
11539 AgendaView
.prototype.renderDrag = function (eventFootprints
, seg
, isTouch
) {
11540 var groups
= groupEventFootprintsByAllDay(eventFootprints
);
11541 var renderedHelper
= false;
11542 renderedHelper
= this.timeGrid
.renderDrag(groups
.timed
, seg
, isTouch
);
11543 if (this.dayGrid
) {
11544 renderedHelper
= this.dayGrid
.renderDrag(groups
.allDay
, seg
, isTouch
) || renderedHelper
;
11546 return renderedHelper
;
11548 AgendaView
.prototype.renderEventResize = function (eventFootprints
, seg
, isTouch
) {
11549 var groups
= groupEventFootprintsByAllDay(eventFootprints
);
11550 this.timeGrid
.renderEventResize(groups
.timed
, seg
, isTouch
);
11551 if (this.dayGrid
) {
11552 this.dayGrid
.renderEventResize(groups
.allDay
, seg
, isTouch
);
11556 ------------------------------------------------------------------------------------------------------------------*/
11557 // Renders a visual indication of a selection
11558 AgendaView
.prototype.renderSelectionFootprint = function (componentFootprint
) {
11559 if (!componentFootprint
.isAllDay
) {
11560 this.timeGrid
.renderSelectionFootprint(componentFootprint
);
11562 else if (this.dayGrid
) {
11563 this.dayGrid
.renderSelectionFootprint(componentFootprint
);
11567 }(View_1
.default));
11568 exports
.default = AgendaView
;
11569 AgendaView
.prototype.timeGridClass
= TimeGrid_1
.default;
11570 AgendaView
.prototype.dayGridClass
= DayGrid_1
.default;
11571 // Will customize the rendering behavior of the AgendaView's timeGrid
11572 agendaTimeGridMethods
= {
11573 // Generates the HTML that will go before the day-of week header cells
11574 renderHeadIntroHtml: function () {
11575 var view
= this.view
;
11576 var calendar
= view
.calendar
;
11577 var weekStart
= calendar
.msToUtcMoment(this.dateProfile
.renderUnzonedRange
.startMs
, true);
11579 if (this.opt('weekNumbers')) {
11580 weekText
= weekStart
.format(this.opt('smallWeekFormat'));
11582 '<th class="fc-axis fc-week-number ' + calendar
.theme
.getClass('widgetHeader') + '" ' + view
.axisStyleAttr() + '>' +
11583 view
.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
11584 { date
: weekStart
, type
: 'week', forceOff
: this.colCnt
> 1 }, util_1
.htmlEscape(weekText
) // inner HTML
11589 return '<th class="fc-axis ' + calendar
.theme
.getClass('widgetHeader') + '" ' + view
.axisStyleAttr() + '></th>';
11592 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
11593 renderBgIntroHtml: function () {
11594 var view
= this.view
;
11595 return '<td class="fc-axis ' + view
.calendar
.theme
.getClass('widgetContent') + '" ' + view
.axisStyleAttr() + '></td>';
11597 // Generates the HTML that goes before all other types of cells.
11598 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
11599 renderIntroHtml: function () {
11600 var view
= this.view
;
11601 return '<td class="fc-axis" ' + view
.axisStyleAttr() + '></td>';
11604 // Will customize the rendering behavior of the AgendaView's dayGrid
11605 agendaDayGridMethods
= {
11606 // Generates the HTML that goes before the all-day cells
11607 renderBgIntroHtml: function () {
11608 var view
= this.view
;
11610 '<td class="fc-axis ' + view
.calendar
.theme
.getClass('widgetContent') + '" ' + view
.axisStyleAttr() + '>' +
11611 '<span>' + // needed for matchCellWidths
11612 view
.getAllDayHtml() +
11616 // Generates the HTML that goes before all other types of cells.
11617 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
11618 renderIntroHtml: function () {
11619 var view
= this.view
;
11620 return '<td class="fc-axis" ' + view
.axisStyleAttr() + '></td>';
11623 function groupEventFootprintsByAllDay(eventFootprints
) {
11627 for (i
= 0; i
< eventFootprints
.length
; i
++) {
11628 if (eventFootprints
[i
].componentFootprint
.isAllDay
) {
11629 allDay
.push(eventFootprints
[i
]);
11632 timed
.push(eventFootprints
[i
]);
11635 return { allDay
: allDay
, timed
: timed
};
11641 /***/ (function(module
, exports
, __webpack_require__
) {
11643 Object
.defineProperty(exports
, "__esModule", { value
: true });
11644 var tslib_1
= __webpack_require__(2);
11645 var $ = __webpack_require__(3);
11646 var moment
= __webpack_require__(0);
11647 var util_1
= __webpack_require__(4);
11648 var InteractiveDateComponent_1
= __webpack_require__(40);
11649 var BusinessHourRenderer_1
= __webpack_require__(56);
11650 var StandardInteractionsMixin_1
= __webpack_require__(60);
11651 var DayTableMixin_1
= __webpack_require__(55);
11652 var CoordCache_1
= __webpack_require__(53);
11653 var UnzonedRange_1
= __webpack_require__(5);
11654 var ComponentFootprint_1
= __webpack_require__(12);
11655 var TimeGridEventRenderer_1
= __webpack_require__(246);
11656 var TimeGridHelperRenderer_1
= __webpack_require__(247);
11657 var TimeGridFillRenderer_1
= __webpack_require__(248);
11658 /* A component that renders one or more columns of vertical time slots
11659 ----------------------------------------------------------------------------------------------------------------------*/
11660 // We mixin DayTable, even though there is only a single row of days
11661 // potential nice values for the slot-duration and interval-duration
11662 // from largest to smallest
11663 var AGENDA_STOCK_SUB_DURATIONS
= [
11670 var TimeGrid
= /** @class */ (function (_super
) {
11671 tslib_1
.__extends(TimeGrid
, _super
);
11672 function TimeGrid(view
) {
11673 var _this
= _super
.call(this, view
) || this;
11674 _this
.processOptions();
11677 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
11678 TimeGrid
.prototype.componentFootprintToSegs = function (componentFootprint
) {
11679 var segs
= this.sliceRangeByTimes(componentFootprint
.unzonedRange
);
11681 for (i
= 0; i
< segs
.length
; i
++) {
11683 segs
[i
].col
= this.daysPerRow
- 1 - segs
[i
].dayIndex
;
11686 segs
[i
].col
= segs
[i
].dayIndex
;
11692 ------------------------------------------------------------------------------------------------------------------*/
11693 TimeGrid
.prototype.sliceRangeByTimes = function (unzonedRange
) {
11697 for (dayIndex
= 0; dayIndex
< this.daysPerRow
; dayIndex
++) {
11698 segRange
= unzonedRange
.intersect(this.dayRanges
[dayIndex
]);
11701 startMs
: segRange
.startMs
,
11702 endMs
: segRange
.endMs
,
11703 isStart
: segRange
.isStart
,
11704 isEnd
: segRange
.isEnd
,
11712 ------------------------------------------------------------------------------------------------------------------*/
11713 // Parses various options into properties of this object
11714 TimeGrid
.prototype.processOptions = function () {
11715 var slotDuration
= this.opt('slotDuration');
11716 var snapDuration
= this.opt('snapDuration');
11718 slotDuration
= moment
.duration(slotDuration
);
11719 snapDuration
= snapDuration
? moment
.duration(snapDuration
) : slotDuration
;
11720 this.slotDuration
= slotDuration
;
11721 this.snapDuration
= snapDuration
;
11722 this.snapsPerSlot
= slotDuration
/ snapDuration
; // TODO: ensure an integer multiple?
11723 // might be an array value (for TimelineView).
11724 // if so, getting the most granular entry (the last one probably).
11725 input
= this.opt('slotLabelFormat');
11726 if ($.isArray(input
)) {
11727 input
= input
[input
.length
- 1];
11729 this.labelFormat
= input
||
11730 this.opt('smallTimeFormat'); // the computed default
11731 input
= this.opt('slotLabelInterval');
11732 this.labelInterval
= input
?
11733 moment
.duration(input
) :
11734 this.computeLabelInterval(slotDuration
);
11736 // Computes an automatic value for slotLabelInterval
11737 TimeGrid
.prototype.computeLabelInterval = function (slotDuration
) {
11741 // find the smallest stock label interval that results in more than one slots-per-label
11742 for (i
= AGENDA_STOCK_SUB_DURATIONS
.length
- 1; i
>= 0; i
--) {
11743 labelInterval
= moment
.duration(AGENDA_STOCK_SUB_DURATIONS
[i
]);
11744 slotsPerLabel
= util_1
.divideDurationByDuration(labelInterval
, slotDuration
);
11745 if (util_1
.isInt(slotsPerLabel
) && slotsPerLabel
> 1) {
11746 return labelInterval
;
11749 return moment
.duration(slotDuration
); // fall back. clone
11752 ------------------------------------------------------------------------------------------------------------------*/
11753 TimeGrid
.prototype.renderDates = function (dateProfile
) {
11754 this.dateProfile
= dateProfile
;
11755 this.updateDayTable();
11756 this.renderSlats();
11757 this.renderColumns();
11759 TimeGrid
.prototype.unrenderDates = function () {
11760 // this.unrenderSlats(); // don't need this because repeated .html() calls clear
11761 this.unrenderColumns();
11763 TimeGrid
.prototype.renderSkeleton = function () {
11764 var theme
= this.view
.calendar
.theme
;
11765 this.el
.html('<div class="fc-bg"></div>' +
11766 '<div class="fc-slats"></div>' +
11767 '<hr class="fc-divider ' + theme
.getClass('widgetHeader') + '" style="display:none" />');
11768 this.bottomRuleEl
= this.el
.find('hr');
11770 TimeGrid
.prototype.renderSlats = function () {
11771 var theme
= this.view
.calendar
.theme
;
11772 this.slatContainerEl
= this.el
.find('> .fc-slats')
11773 .html(// avoids needing ::unrenderSlats()
11774 '<table class="' + theme
.getClass('tableGrid') + '">' +
11775 this.renderSlatRowHtml() +
11777 this.slatEls
= this.slatContainerEl
.find('tr');
11778 this.slatCoordCache
= new CoordCache_1
.default({
11783 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
11784 TimeGrid
.prototype.renderSlatRowHtml = function () {
11785 var view
= this.view
;
11786 var calendar
= view
.calendar
;
11787 var theme
= calendar
.theme
;
11788 var isRTL
= this.isRTL
;
11789 var dateProfile
= this.dateProfile
;
11791 var slotTime
= moment
.duration(+dateProfile
.minTime
); // wish there was .clone() for durations
11792 var slotIterator
= moment
.duration(0);
11793 var slotDate
; // will be on the view's first day, but we only care about its time
11796 // Calculate the time for each slot
11797 while (slotTime
< dateProfile
.maxTime
) {
11798 slotDate
= calendar
.msToUtcMoment(dateProfile
.renderUnzonedRange
.startMs
).time(slotTime
);
11799 isLabeled
= util_1
.isInt(util_1
.divideDurationByDuration(slotIterator
, this.labelInterval
));
11801 '<td class="fc-axis fc-time ' + theme
.getClass('widgetContent') + '" ' + view
.axisStyleAttr() + '>' +
11803 '<span>' + // for matchCellWidths
11804 util_1
.htmlEscape(slotDate
.format(this.labelFormat
)) +
11809 '<tr data-time="' + slotDate
.format('HH:mm:ss') + '"' +
11810 (isLabeled
? '' : ' class="fc-minor"') +
11812 (!isRTL
? axisHtml
: '') +
11813 '<td class="' + theme
.getClass('widgetContent') + '"/>' +
11814 (isRTL
? axisHtml
: '') +
11816 slotTime
.add(this.slotDuration
);
11817 slotIterator
.add(this.slotDuration
);
11821 TimeGrid
.prototype.renderColumns = function () {
11822 var dateProfile
= this.dateProfile
;
11823 var theme
= this.view
.calendar
.theme
;
11824 this.dayRanges
= this.dayDates
.map(function (dayDate
) {
11825 return new UnzonedRange_1
.default(dayDate
.clone().add(dateProfile
.minTime
), dayDate
.clone().add(dateProfile
.maxTime
));
11827 if (this.headContainerEl
) {
11828 this.headContainerEl
.html(this.renderHeadHtml());
11830 this.el
.find('> .fc-bg').html('<table class="' + theme
.getClass('tableGrid') + '">' +
11831 this.renderBgTrHtml(0) + // row=0
11833 this.colEls
= this.el
.find('.fc-day, .fc-disabled-day');
11834 this.colCoordCache
= new CoordCache_1
.default({
11838 this.renderContentSkeleton();
11840 TimeGrid
.prototype.unrenderColumns = function () {
11841 this.unrenderContentSkeleton();
11843 /* Content Skeleton
11844 ------------------------------------------------------------------------------------------------------------------*/
11845 // Renders the DOM that the view's content will live in
11846 TimeGrid
.prototype.renderContentSkeleton = function () {
11850 for (i
= 0; i
< this.colCnt
; i
++) {
11853 '<div class="fc-content-col">' +
11854 '<div class="fc-event-container fc-helper-container"></div>' +
11855 '<div class="fc-event-container"></div>' +
11856 '<div class="fc-highlight-container"></div>' +
11857 '<div class="fc-bgevent-container"></div>' +
11858 '<div class="fc-business-container"></div>' +
11862 skeletonEl
= this.contentSkeletonEl
= $('<div class="fc-content-skeleton">' +
11864 '<tr>' + cellHtml
+ '</tr>' +
11867 this.colContainerEls
= skeletonEl
.find('.fc-content-col');
11868 this.helperContainerEls
= skeletonEl
.find('.fc-helper-container');
11869 this.fgContainerEls
= skeletonEl
.find('.fc-event-container:not(.fc-helper-container)');
11870 this.bgContainerEls
= skeletonEl
.find('.fc-bgevent-container');
11871 this.highlightContainerEls
= skeletonEl
.find('.fc-highlight-container');
11872 this.businessContainerEls
= skeletonEl
.find('.fc-business-container');
11873 this.bookendCells(skeletonEl
.find('tr')); // TODO: do this on string level
11874 this.el
.append(skeletonEl
);
11876 TimeGrid
.prototype.unrenderContentSkeleton = function () {
11877 if (this.contentSkeletonEl
) {
11878 this.contentSkeletonEl
.remove();
11879 this.contentSkeletonEl
= null;
11880 this.colContainerEls
= null;
11881 this.helperContainerEls
= null;
11882 this.fgContainerEls
= null;
11883 this.bgContainerEls
= null;
11884 this.highlightContainerEls
= null;
11885 this.businessContainerEls
= null;
11888 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
11889 TimeGrid
.prototype.groupSegsByCol = function (segs
) {
11890 var segsByCol
= [];
11892 for (i
= 0; i
< this.colCnt
; i
++) {
11893 segsByCol
.push([]);
11895 for (i
= 0; i
< segs
.length
; i
++) {
11896 segsByCol
[segs
[i
].col
].push(segs
[i
]);
11900 // Given segments grouped by column, insert the segments' elements into a parallel array of container
11901 // elements, each living within a column.
11902 TimeGrid
.prototype.attachSegsByCol = function (segsByCol
, containerEls
) {
11906 for (col
= 0; col
< this.colCnt
; col
++) {
11907 segs
= segsByCol
[col
];
11908 for (i
= 0; i
< segs
.length
; i
++) {
11909 containerEls
.eq(col
).append(segs
[i
].el
);
11914 ------------------------------------------------------------------------------------------------------------------*/
11915 TimeGrid
.prototype.getNowIndicatorUnit = function () {
11916 return 'minute'; // will refresh on the minute
11918 TimeGrid
.prototype.renderNowIndicator = function (date
) {
11919 // HACK: if date columns not ready for some reason (scheduler)
11920 if (!this.colContainerEls
) {
11923 // seg system might be overkill, but it handles scenario where line needs to be rendered
11924 // more than once because of columns with the same date (resources columns for example)
11925 var segs
= this.componentFootprintToSegs(new ComponentFootprint_1
.default(new UnzonedRange_1
.default(date
, date
.valueOf() + 1), // protect against null range
11928 var top
= this.computeDateTop(date
, date
);
11931 // render lines within the columns
11932 for (i
= 0; i
< segs
.length
; i
++) {
11933 nodes
.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>')
11935 .appendTo(this.colContainerEls
.eq(segs
[i
].col
))[0]);
11937 // render an arrow over the axis
11938 if (segs
.length
> 0) {
11939 nodes
.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>')
11941 .appendTo(this.el
.find('.fc-content-skeleton'))[0]);
11943 this.nowIndicatorEls
= $(nodes
);
11945 TimeGrid
.prototype.unrenderNowIndicator = function () {
11946 if (this.nowIndicatorEls
) {
11947 this.nowIndicatorEls
.remove();
11948 this.nowIndicatorEls
= null;
11952 ------------------------------------------------------------------------------------------------------------------*/
11953 TimeGrid
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
11954 _super
.prototype.updateSize
.call(this, totalHeight
, isAuto
, isResize
);
11955 this.slatCoordCache
.build();
11957 this.updateSegVerticals([].concat(this.eventRenderer
.getSegs(), this.businessSegs
|| []));
11960 TimeGrid
.prototype.getTotalSlatHeight = function () {
11961 return this.slatContainerEl
.outerHeight();
11963 // Computes the top coordinate, relative to the bounds of the grid, of the given date.
11964 // `ms` can be a millisecond UTC time OR a UTC moment.
11965 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
11966 TimeGrid
.prototype.computeDateTop = function (ms
, startOfDayDate
) {
11967 return this.computeTimeTop(moment
.duration(ms
- startOfDayDate
.clone().stripTime()));
11969 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
11970 TimeGrid
.prototype.computeTimeTop = function (time
) {
11971 var len
= this.slatEls
.length
;
11972 var dateProfile
= this.dateProfile
;
11973 var slatCoverage
= (time
- dateProfile
.minTime
) / this.slotDuration
; // floating-point value of # of slots covered
11976 // compute a floating-point number for how many slats should be progressed through.
11977 // from 0 to number of slats (inclusive)
11978 // constrained because minTime/maxTime might be customized.
11979 slatCoverage
= Math
.max(0, slatCoverage
);
11980 slatCoverage
= Math
.min(len
, slatCoverage
);
11981 // an integer index of the furthest whole slat
11982 // from 0 to number slats (*exclusive*, so len-1)
11983 slatIndex
= Math
.floor(slatCoverage
);
11984 slatIndex
= Math
.min(slatIndex
, len
- 1);
11985 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
11986 // could be 1.0 if slatCoverage is covering *all* the slots
11987 slatRemainder
= slatCoverage
- slatIndex
;
11988 return this.slatCoordCache
.getTopPosition(slatIndex
) +
11989 this.slatCoordCache
.getHeight(slatIndex
) * slatRemainder
;
11991 // Refreshes the CSS top/bottom coordinates for each segment element.
11992 // Works when called after initial render, after a window resize/zoom for example.
11993 TimeGrid
.prototype.updateSegVerticals = function (segs
) {
11994 this.computeSegVerticals(segs
);
11995 this.assignSegVerticals(segs
);
11997 // For each segment in an array, computes and assigns its top and bottom properties
11998 TimeGrid
.prototype.computeSegVerticals = function (segs
) {
11999 var eventMinHeight
= this.opt('agendaEventMinHeight');
12003 for (i
= 0; i
< segs
.length
; i
++) {
12005 dayDate
= this.dayDates
[seg
.dayIndex
];
12006 seg
.top
= this.computeDateTop(seg
.startMs
, dayDate
);
12007 seg
.bottom
= Math
.max(seg
.top
+ eventMinHeight
, this.computeDateTop(seg
.endMs
, dayDate
));
12010 // Given segments that already have their top/bottom properties computed, applies those values to
12011 // the segments' elements.
12012 TimeGrid
.prototype.assignSegVerticals = function (segs
) {
12015 for (i
= 0; i
< segs
.length
; i
++) {
12017 seg
.el
.css(this.generateSegVerticalCss(seg
));
12020 // Generates an object with CSS properties for the top/bottom coordinates of a segment element
12021 TimeGrid
.prototype.generateSegVerticalCss = function (seg
) {
12024 bottom
: -seg
.bottom
// flipped because needs to be space beyond bottom edge of event container
12028 ------------------------------------------------------------------------------------------------------------------*/
12029 TimeGrid
.prototype.prepareHits = function () {
12030 this.colCoordCache
.build();
12031 this.slatCoordCache
.build();
12033 TimeGrid
.prototype.releaseHits = function () {
12034 this.colCoordCache
.clear();
12035 // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop
12037 TimeGrid
.prototype.queryHit = function (leftOffset
, topOffset
) {
12038 var snapsPerSlot
= this.snapsPerSlot
;
12039 var colCoordCache
= this.colCoordCache
;
12040 var slatCoordCache
= this.slatCoordCache
;
12041 if (colCoordCache
.isLeftInBounds(leftOffset
) && slatCoordCache
.isTopInBounds(topOffset
)) {
12042 var colIndex
= colCoordCache
.getHorizontalIndex(leftOffset
);
12043 var slatIndex
= slatCoordCache
.getVerticalIndex(topOffset
);
12044 if (colIndex
!= null && slatIndex
!= null) {
12045 var slatTop
= slatCoordCache
.getTopOffset(slatIndex
);
12046 var slatHeight
= slatCoordCache
.getHeight(slatIndex
);
12047 var partial
= (topOffset
- slatTop
) / slatHeight
; // floating point number between 0 and 1
12048 var localSnapIndex
= Math
.floor(partial
* snapsPerSlot
); // the snap # relative to start of slat
12049 var snapIndex
= slatIndex
* snapsPerSlot
+ localSnapIndex
;
12050 var snapTop
= slatTop
+ (localSnapIndex
/ snapsPerSlot
) * slatHeight
;
12051 var snapBottom
= slatTop
+ ((localSnapIndex
+ 1) / snapsPerSlot
) * slatHeight
;
12056 left
: colCoordCache
.getLeftOffset(colIndex
),
12057 right
: colCoordCache
.getRightOffset(colIndex
),
12064 TimeGrid
.prototype.getHitFootprint = function (hit
) {
12065 var start
= this.getCellDate(0, hit
.col
); // row=0
12066 var time
= this.computeSnapTime(hit
.snap
); // pass in the snap-index
12069 end
= start
.clone().add(this.snapDuration
);
12070 return new ComponentFootprint_1
.default(new UnzonedRange_1
.default(start
, end
), false // all-day?
12073 // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
12074 TimeGrid
.prototype.computeSnapTime = function (snapIndex
) {
12075 return moment
.duration(this.dateProfile
.minTime
+ this.snapDuration
* snapIndex
);
12077 TimeGrid
.prototype.getHitEl = function (hit
) {
12078 return this.colEls
.eq(hit
.col
);
12080 /* Event Drag Visualization
12081 ------------------------------------------------------------------------------------------------------------------*/
12082 // Renders a visual indication of an event being dragged over the specified date(s).
12083 // A returned value of `true` signals that a mock "helper" event has been rendered.
12084 TimeGrid
.prototype.renderDrag = function (eventFootprints
, seg
, isTouch
) {
12087 if (eventFootprints
.length
) {
12088 this.helperRenderer
.renderEventDraggingFootprints(eventFootprints
, seg
, isTouch
);
12089 // signal that a helper has been rendered
12094 for (i
= 0; i
< eventFootprints
.length
; i
++) {
12095 this.renderHighlight(eventFootprints
[i
].componentFootprint
);
12099 // Unrenders any visual indication of an event being dragged
12100 TimeGrid
.prototype.unrenderDrag = function () {
12101 this.unrenderHighlight();
12102 this.helperRenderer
.unrender();
12104 /* Event Resize Visualization
12105 ------------------------------------------------------------------------------------------------------------------*/
12106 // Renders a visual indication of an event being resized
12107 TimeGrid
.prototype.renderEventResize = function (eventFootprints
, seg
, isTouch
) {
12108 this.helperRenderer
.renderEventResizingFootprints(eventFootprints
, seg
, isTouch
);
12110 // Unrenders any visual indication of an event being resized
12111 TimeGrid
.prototype.unrenderEventResize = function () {
12112 this.helperRenderer
.unrender();
12115 ------------------------------------------------------------------------------------------------------------------*/
12116 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
12117 TimeGrid
.prototype.renderSelectionFootprint = function (componentFootprint
) {
12118 if (this.opt('selectHelper')) {
12119 this.helperRenderer
.renderComponentFootprint(componentFootprint
);
12122 this.renderHighlight(componentFootprint
);
12125 // Unrenders any visual indication of a selection
12126 TimeGrid
.prototype.unrenderSelection = function () {
12127 this.helperRenderer
.unrender();
12128 this.unrenderHighlight();
12131 }(InteractiveDateComponent_1
.default));
12132 exports
.default = TimeGrid
;
12133 TimeGrid
.prototype.eventRendererClass
= TimeGridEventRenderer_1
.default;
12134 TimeGrid
.prototype.businessHourRendererClass
= BusinessHourRenderer_1
.default;
12135 TimeGrid
.prototype.helperRendererClass
= TimeGridHelperRenderer_1
.default;
12136 TimeGrid
.prototype.fillRendererClass
= TimeGridFillRenderer_1
.default;
12137 StandardInteractionsMixin_1
.default.mixInto(TimeGrid
);
12138 DayTableMixin_1
.default.mixInto(TimeGrid
);
12143 /***/ (function(module
, exports
, __webpack_require__
) {
12145 Object
.defineProperty(exports
, "__esModule", { value
: true });
12146 var tslib_1
= __webpack_require__(2);
12147 var UnzonedRange_1
= __webpack_require__(5);
12148 var DateProfileGenerator_1
= __webpack_require__(221);
12149 var BasicViewDateProfileGenerator
= /** @class */ (function (_super
) {
12150 tslib_1
.__extends(BasicViewDateProfileGenerator
, _super
);
12151 function BasicViewDateProfileGenerator() {
12152 return _super
!== null && _super
.apply(this, arguments
) || this;
12154 // Computes the date range that will be rendered.
12155 BasicViewDateProfileGenerator
.prototype.buildRenderRange = function (currentUnzonedRange
, currentRangeUnit
, isRangeAllDay
) {
12156 var renderUnzonedRange
= _super
.prototype.buildRenderRange
.call(this, currentUnzonedRange
, currentRangeUnit
, isRangeAllDay
); // an UnzonedRange
12157 var start
= this.msToUtcMoment(renderUnzonedRange
.startMs
, isRangeAllDay
);
12158 var end
= this.msToUtcMoment(renderUnzonedRange
.endMs
, isRangeAllDay
);
12159 // year and month views should be aligned with weeks. this is already done for week
12160 if (/^(year|month)$/.test(currentRangeUnit
)) {
12161 start
.startOf('week');
12162 // make end-of-week if not already
12163 if (end
.weekday()) {
12164 end
.add(1, 'week').startOf('week'); // exclusively move backwards
12167 return new UnzonedRange_1
.default(start
, end
);
12169 return BasicViewDateProfileGenerator
;
12170 }(DateProfileGenerator_1
.default));
12171 exports
.default = BasicViewDateProfileGenerator
;
12176 /***/ (function(module
, exports
, __webpack_require__
) {
12178 Object
.defineProperty(exports
, "__esModule", { value
: true });
12179 var tslib_1
= __webpack_require__(2);
12180 var moment
= __webpack_require__(0);
12181 var util_1
= __webpack_require__(4);
12182 var BasicView_1
= __webpack_require__(62);
12183 var MonthViewDateProfileGenerator_1
= __webpack_require__(253);
12184 /* A month view with day cells running in rows (one-per-week) and columns
12185 ----------------------------------------------------------------------------------------------------------------------*/
12186 var MonthView
= /** @class */ (function (_super
) {
12187 tslib_1
.__extends(MonthView
, _super
);
12188 function MonthView() {
12189 return _super
!== null && _super
.apply(this, arguments
) || this;
12191 // Overrides the default BasicView behavior to have special multi-week auto-height logic
12192 MonthView
.prototype.setGridHeight = function (height
, isAuto
) {
12193 // if auto, make the height of each row the height that it would be if there were 6 weeks
12195 height
*= this.dayGrid
.rowCnt
/ 6;
12197 util_1
.distributeHeight(this.dayGrid
.rowEls
, height
, !isAuto
); // if auto, don't compensate for height-hogging rows
12199 MonthView
.prototype.isDateInOtherMonth = function (date
, dateProfile
) {
12200 return date
.month() !== moment
.utc(dateProfile
.currentUnzonedRange
.startMs
).month(); // TODO: optimize
12203 }(BasicView_1
.default));
12204 exports
.default = MonthView
;
12205 MonthView
.prototype.dateProfileGeneratorClass
= MonthViewDateProfileGenerator_1
.default;
12210 /***/ (function(module
, exports
, __webpack_require__
) {
12212 Object
.defineProperty(exports
, "__esModule", { value
: true });
12213 var tslib_1
= __webpack_require__(2);
12214 var $ = __webpack_require__(3);
12215 var util_1
= __webpack_require__(4);
12216 var UnzonedRange_1
= __webpack_require__(5);
12217 var View_1
= __webpack_require__(41);
12218 var Scroller_1
= __webpack_require__(39);
12219 var ListEventRenderer_1
= __webpack_require__(254);
12220 var ListEventPointing_1
= __webpack_require__(255);
12222 Responsible for the scroller, and forwarding event-related actions into the "grid".
12224 var ListView
= /** @class */ (function (_super
) {
12225 tslib_1
.__extends(ListView
, _super
);
12226 function ListView(calendar
, viewSpec
) {
12227 var _this
= _super
.call(this, calendar
, viewSpec
) || this;
12228 _this
.segSelector
= '.fc-list-item'; // which elements accept event actions
12229 _this
.scroller
= new Scroller_1
.default({
12230 overflowX
: 'hidden',
12235 ListView
.prototype.renderSkeleton = function () {
12236 this.el
.addClass('fc-list-view ' +
12237 this.calendar
.theme
.getClass('listView'));
12238 this.scroller
.render();
12239 this.scroller
.el
.appendTo(this.el
);
12240 this.contentEl
= this.scroller
.scrollEl
; // shortcut
12242 ListView
.prototype.unrenderSkeleton = function () {
12243 this.scroller
.destroy(); // will remove the Grid too
12245 ListView
.prototype.updateSize = function (totalHeight
, isAuto
, isResize
) {
12246 _super
.prototype.updateSize
.call(this, totalHeight
, isAuto
, isResize
);
12247 this.scroller
.clear(); // sets height to 'auto' and clears overflow
12249 this.scroller
.setHeight(this.computeScrollerHeight(totalHeight
));
12252 ListView
.prototype.computeScrollerHeight = function (totalHeight
) {
12253 return totalHeight
-
12254 util_1
.subtractInnerElHeight(this.el
, this.scroller
.el
); // everything that's NOT the scroller
12256 ListView
.prototype.renderDates = function (dateProfile
) {
12257 var calendar
= this.calendar
;
12258 var dayStart
= calendar
.msToUtcMoment(dateProfile
.renderUnzonedRange
.startMs
, true);
12259 var viewEnd
= calendar
.msToUtcMoment(dateProfile
.renderUnzonedRange
.endMs
, true);
12261 var dayRanges
= [];
12262 while (dayStart
< viewEnd
) {
12263 dayDates
.push(dayStart
.clone());
12264 dayRanges
.push(new UnzonedRange_1
.default(dayStart
, dayStart
.clone().add(1, 'day')));
12265 dayStart
.add(1, 'day');
12267 this.dayDates
= dayDates
;
12268 this.dayRanges
= dayRanges
;
12269 // all real rendering happens in EventRenderer
12272 ListView
.prototype.componentFootprintToSegs = function (footprint
) {
12273 var dayRanges
= this.dayRanges
;
12278 for (dayIndex
= 0; dayIndex
< dayRanges
.length
; dayIndex
++) {
12279 segRange
= footprint
.unzonedRange
.intersect(dayRanges
[dayIndex
]);
12282 startMs
: segRange
.startMs
,
12283 endMs
: segRange
.endMs
,
12284 isStart
: segRange
.isStart
,
12285 isEnd
: segRange
.isEnd
,
12289 // detect when footprint won't go fully into the next day,
12290 // and mutate the latest seg to the be the end.
12291 if (!seg
.isEnd
&& !footprint
.isAllDay
&&
12292 dayIndex
+ 1 < dayRanges
.length
&&
12293 footprint
.unzonedRange
.endMs
< dayRanges
[dayIndex
+ 1].startMs
+ this.nextDayThreshold
) {
12294 seg
.endMs
= footprint
.unzonedRange
.endMs
;
12302 ListView
.prototype.renderEmptyMessage = function () {
12303 this.contentEl
.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
12304 '<div class="fc-list-empty-wrap1">' +
12305 '<div class="fc-list-empty">' +
12306 util_1
.htmlEscape(this.opt('noEventsMessage')) +
12311 // render the event segments in the view
12312 ListView
.prototype.renderSegList = function (allSegs
) {
12313 var segsByDay
= this.groupSegsByDay(allSegs
); // sparse array
12317 var tableEl
= $('<table class="fc-list-table ' + this.calendar
.theme
.getClass('tableList') + '"><tbody/></table>');
12318 var tbodyEl
= tableEl
.find('tbody');
12319 for (dayIndex
= 0; dayIndex
< segsByDay
.length
; dayIndex
++) {
12320 daySegs
= segsByDay
[dayIndex
];
12322 // append a day header
12323 tbodyEl
.append(this.dayHeaderHtml(this.dayDates
[dayIndex
]));
12324 this.eventRenderer
.sortEventSegs(daySegs
);
12325 for (i
= 0; i
< daySegs
.length
; i
++) {
12326 tbodyEl
.append(daySegs
[i
].el
); // append event row
12330 this.contentEl
.empty().append(tableEl
);
12332 // Returns a sparse array of arrays, segs grouped by their dayIndex
12333 ListView
.prototype.groupSegsByDay = function (segs
) {
12334 var segsByDay
= []; // sparse array
12337 for (i
= 0; i
< segs
.length
; i
++) {
12339 (segsByDay
[seg
.dayIndex
] || (segsByDay
[seg
.dayIndex
] = []))
12344 // generates the HTML for the day headers that live amongst the event rows
12345 ListView
.prototype.dayHeaderHtml = function (dayDate
) {
12346 var mainFormat
= this.opt('listDayFormat');
12347 var altFormat
= this.opt('listDayAltFormat');
12348 return '<tr class="fc-list-heading" data-date="' + dayDate
.format('YYYY-MM-DD') + '">' +
12349 '<td class="' + (this.calendar
.theme
.getClass('tableListHeading') ||
12350 this.calendar
.theme
.getClass('widgetHeader')) + '" colspan="3">' +
12352 this.buildGotoAnchorHtml(dayDate
, { 'class': 'fc-list-heading-main' }, util_1
.htmlEscape(dayDate
.format(mainFormat
)) // inner HTML
12356 this.buildGotoAnchorHtml(dayDate
, { 'class': 'fc-list-heading-alt' }, util_1
.htmlEscape(dayDate
.format(altFormat
)) // inner HTML
12363 }(View_1
.default));
12364 exports
.default = ListView
;
12365 ListView
.prototype.eventRendererClass
= ListEventRenderer_1
.default;
12366 ListView
.prototype.eventPointingClass
= ListEventPointing_1
.default;
12376 /***/ (function(module
, exports
, __webpack_require__
) {
12378 var $ = __webpack_require__(3);
12379 var exportHooks
= __webpack_require__(16);
12380 var util_1
= __webpack_require__(4);
12381 var Calendar_1
= __webpack_require__(220);
12382 // for intentional side-effects
12383 __webpack_require__(10);
12384 __webpack_require__(47);
12385 __webpack_require__(256);
12386 __webpack_require__(257);
12387 __webpack_require__(260);
12388 __webpack_require__(261);
12389 __webpack_require__(262);
12390 __webpack_require__(263);
12391 $.fullCalendar
= exportHooks
;
12392 $.fn
.fullCalendar = function (options
) {
12393 var args
= Array
.prototype.slice
.call(arguments
, 1); // for a possible method call
12394 var res
= this; // what this function will return (this jQuery object by default)
12395 this.each(function (i
, _element
) {
12396 var element
= $(_element
);
12397 var calendar
= element
.data('fullCalendar'); // get the existing calendar object (if any)
12398 var singleRes
; // the returned value of this single method call
12400 if (typeof options
=== 'string') {
12401 if (options
=== 'getCalendar') {
12406 else if (options
=== 'destroy') {
12408 calendar
.destroy();
12409 element
.removeData('fullCalendar');
12412 else if (!calendar
) {
12413 util_1
.warn('Attempting to call a FullCalendar method on an element with no calendar.');
12415 else if ($.isFunction(calendar
[options
])) {
12416 singleRes
= calendar
[options
].apply(calendar
, args
);
12418 res
= singleRes
; // record the first method call result
12420 if (options
=== 'destroy') {
12421 element
.removeData('fullCalendar');
12425 util_1
.warn("'" + options
+ "' is an unknown FullCalendar method.");
12428 else if (!calendar
) {
12429 calendar
= new Calendar_1
.default(element
, options
);
12430 element
.data('fullCalendar', calendar
);
12436 module
.exports
= exportHooks
;
12441 /***/ (function(module
, exports
, __webpack_require__
) {
12443 Object
.defineProperty(exports
, "__esModule", { value
: true });
12444 var tslib_1
= __webpack_require__(2);
12445 var Model_1
= __webpack_require__(48);
12446 var Component
= /** @class */ (function (_super
) {
12447 tslib_1
.__extends(Component
, _super
);
12448 function Component() {
12449 return _super
!== null && _super
.apply(this, arguments
) || this;
12451 Component
.prototype.setElement = function (el
) {
12453 this.bindGlobalHandlers();
12454 this.renderSkeleton();
12455 this.set('isInDom', true);
12457 Component
.prototype.removeElement = function () {
12458 this.unset('isInDom');
12459 this.unrenderSkeleton();
12460 this.unbindGlobalHandlers();
12462 // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
12463 // We don't null-out the View's other jQuery element references upon destroy,
12464 // so we shouldn't kill this.el either.
12466 Component
.prototype.bindGlobalHandlers = function () {
12467 // subclasses can override
12469 Component
.prototype.unbindGlobalHandlers = function () {
12470 // subclasses can override
12473 NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender
12475 // Renders the basic structure of the view before any content is rendered
12476 Component
.prototype.renderSkeleton = function () {
12477 // subclasses should implement
12479 // Unrenders the basic structure of the view
12480 Component
.prototype.unrenderSkeleton = function () {
12481 // subclasses should implement
12484 }(Model_1
.default));
12485 exports
.default = Component
;
12490 /***/ (function(module
, exports
) {
12492 Object
.defineProperty(exports
, "__esModule", { value
: true });
12493 var Iterator
= /** @class */ (function () {
12494 function Iterator(items
) {
12495 this.items
= items
|| [];
12497 /* Calls a method on every item passing the arguments through */
12498 Iterator
.prototype.proxyCall = function (methodName
) {
12500 for (var _i
= 1; _i
< arguments
.length
; _i
++) {
12501 args
[_i
- 1] = arguments
[_i
];
12504 this.items
.forEach(function (item
) {
12505 results
.push(item
[methodName
].apply(item
, args
));
12511 exports
.default = Iterator
;
12516 /***/ (function(module
, exports
, __webpack_require__
) {
12518 Object
.defineProperty(exports
, "__esModule", { value
: true });
12519 var $ = __webpack_require__(3);
12520 var util_1
= __webpack_require__(4);
12521 /* Toolbar with buttons and title
12522 ----------------------------------------------------------------------------------------------------------------------*/
12523 var Toolbar
= /** @class */ (function () {
12524 function Toolbar(calendar
, toolbarOptions
) {
12525 this.el
= null; // mirrors local `el`
12526 this.viewsWithButtons
= [];
12527 this.calendar
= calendar
;
12528 this.toolbarOptions
= toolbarOptions
;
12530 // method to update toolbar-specific options, not calendar-wide options
12531 Toolbar
.prototype.setToolbarOptions = function (newToolbarOptions
) {
12532 this.toolbarOptions
= newToolbarOptions
;
12534 // can be called repeatedly and will rerender
12535 Toolbar
.prototype.render = function () {
12536 var sections
= this.toolbarOptions
.layout
;
12540 el
= this.el
= $("<div class='fc-toolbar " + this.toolbarOptions
.extraClasses
+ "'/>");
12545 el
.append(this.renderSection('left'))
12546 .append(this.renderSection('right'))
12547 .append(this.renderSection('center'))
12548 .append('<div class="fc-clear"/>');
12551 this.removeElement();
12554 Toolbar
.prototype.removeElement = function () {
12560 Toolbar
.prototype.renderSection = function (position
) {
12562 var calendar
= this.calendar
;
12563 var theme
= calendar
.theme
;
12564 var optionsManager
= calendar
.optionsManager
;
12565 var viewSpecManager
= calendar
.viewSpecManager
;
12566 var sectionEl
= $('<div class="fc-' + position
+ '"/>');
12567 var buttonStr
= this.toolbarOptions
.layout
[position
];
12568 var calendarCustomButtons
= optionsManager
.get('customButtons') || {};
12569 var calendarButtonTextOverrides
= optionsManager
.overrides
.buttonText
|| {};
12570 var calendarButtonText
= optionsManager
.get('buttonText') || {};
12572 $.each(buttonStr
.split(' '), function (i
, buttonGroupStr
) {
12573 var groupChildren
= $();
12574 var isOnlyButtons
= true;
12576 $.each(buttonGroupStr
.split(','), function (j
, buttonName
) {
12577 var customButtonProps
;
12580 var buttonIcon
; // only one of these will be set
12581 var buttonText
; // "
12582 var buttonInnerHtml
;
12585 var buttonAriaAttr
;
12586 if (buttonName
=== 'title') {
12587 groupChildren
= groupChildren
.add($('<h2> </h2>')); // we always want it to take up height
12588 isOnlyButtons
= false;
12591 if ((customButtonProps
= calendarCustomButtons
[buttonName
])) {
12592 buttonClick = function (ev
) {
12593 if (customButtonProps
.click
) {
12594 customButtonProps
.click
.call(buttonEl
[0], ev
);
12597 (buttonIcon
= theme
.getCustomButtonIconClass(customButtonProps
)) ||
12598 (buttonIcon
= theme
.getIconClass(buttonName
)) ||
12599 (buttonText
= customButtonProps
.text
);
12601 else if ((viewSpec
= viewSpecManager
.getViewSpec(buttonName
))) {
12602 _this
.viewsWithButtons
.push(buttonName
);
12603 buttonClick = function () {
12604 calendar
.changeView(buttonName
);
12606 (buttonText
= viewSpec
.buttonTextOverride
) ||
12607 (buttonIcon
= theme
.getIconClass(buttonName
)) ||
12608 (buttonText
= viewSpec
.buttonTextDefault
);
12610 else if (calendar
[buttonName
]) {
12611 buttonClick = function () {
12612 calendar
[buttonName
]();
12614 (buttonText
= calendarButtonTextOverrides
[buttonName
]) ||
12615 (buttonIcon
= theme
.getIconClass(buttonName
)) ||
12616 (buttonText
= calendarButtonText
[buttonName
]);
12617 // ^ everything else is considered default
12621 'fc-' + buttonName
+ '-button',
12622 theme
.getClass('button'),
12623 theme
.getClass('stateDefault')
12626 buttonInnerHtml
= util_1
.htmlEscape(buttonText
);
12627 buttonAriaAttr
= '';
12629 else if (buttonIcon
) {
12630 buttonInnerHtml
= "<span class='" + buttonIcon
+ "'></span>";
12631 buttonAriaAttr
= ' aria-label="' + buttonName
+ '"';
12633 buttonEl
= $(// type="button" so that it doesn't submit a form
12634 '<button type="button" class="' + buttonClasses
.join(' ') + '"' +
12636 '>' + buttonInnerHtml
+ '</button>')
12637 .click(function (ev
) {
12638 // don't process clicks for disabled buttons
12639 if (!buttonEl
.hasClass(theme
.getClass('stateDisabled'))) {
12641 // after the click action, if the button becomes the "active" tab, or disabled,
12642 // it should never have a hover class, so remove it now.
12643 if (buttonEl
.hasClass(theme
.getClass('stateActive')) ||
12644 buttonEl
.hasClass(theme
.getClass('stateDisabled'))) {
12645 buttonEl
.removeClass(theme
.getClass('stateHover'));
12649 .mousedown(function () {
12650 // the *down* effect (mouse pressed in).
12651 // only on buttons that are not the "active" tab, or disabled
12653 .not('.' + theme
.getClass('stateActive'))
12654 .not('.' + theme
.getClass('stateDisabled'))
12655 .addClass(theme
.getClass('stateDown'));
12657 .mouseup(function () {
12658 // undo the *down* effect
12659 buttonEl
.removeClass(theme
.getClass('stateDown'));
12661 .hover(function () {
12662 // the *hover* effect.
12663 // only on buttons that are not the "active" tab, or disabled
12665 .not('.' + theme
.getClass('stateActive'))
12666 .not('.' + theme
.getClass('stateDisabled'))
12667 .addClass(theme
.getClass('stateHover'));
12669 // undo the *hover* effect
12671 .removeClass(theme
.getClass('stateHover'))
12672 .removeClass(theme
.getClass('stateDown')); // if mouseleave happens before mouseup
12674 groupChildren
= groupChildren
.add(buttonEl
);
12678 if (isOnlyButtons
) {
12680 .first().addClass(theme
.getClass('cornerLeft')).end()
12681 .last().addClass(theme
.getClass('cornerRight')).end();
12683 if (groupChildren
.length
> 1) {
12684 groupEl
= $('<div/>');
12685 if (isOnlyButtons
) {
12686 groupEl
.addClass(theme
.getClass('buttonGroup'));
12688 groupEl
.append(groupChildren
);
12689 sectionEl
.append(groupEl
);
12692 sectionEl
.append(groupChildren
); // 1 or 0 children
12698 Toolbar
.prototype.updateTitle = function (text
) {
12700 this.el
.find('h2').text(text
);
12703 Toolbar
.prototype.activateButton = function (buttonName
) {
12705 this.el
.find('.fc-' + buttonName
+ '-button')
12706 .addClass(this.calendar
.theme
.getClass('stateActive'));
12709 Toolbar
.prototype.deactivateButton = function (buttonName
) {
12711 this.el
.find('.fc-' + buttonName
+ '-button')
12712 .removeClass(this.calendar
.theme
.getClass('stateActive'));
12715 Toolbar
.prototype.disableButton = function (buttonName
) {
12717 this.el
.find('.fc-' + buttonName
+ '-button')
12718 .prop('disabled', true)
12719 .addClass(this.calendar
.theme
.getClass('stateDisabled'));
12722 Toolbar
.prototype.enableButton = function (buttonName
) {
12724 this.el
.find('.fc-' + buttonName
+ '-button')
12725 .prop('disabled', false)
12726 .removeClass(this.calendar
.theme
.getClass('stateDisabled'));
12729 Toolbar
.prototype.getViewsWithButtons = function () {
12730 return this.viewsWithButtons
;
12734 exports
.default = Toolbar
;
12739 /***/ (function(module
, exports
, __webpack_require__
) {
12741 Object
.defineProperty(exports
, "__esModule", { value
: true });
12742 var tslib_1
= __webpack_require__(2);
12743 var $ = __webpack_require__(3);
12744 var util_1
= __webpack_require__(4);
12745 var options_1
= __webpack_require__(32);
12746 var locale_1
= __webpack_require__(31);
12747 var Model_1
= __webpack_require__(48);
12748 var OptionsManager
= /** @class */ (function (_super
) {
12749 tslib_1
.__extends(OptionsManager
, _super
);
12750 function OptionsManager(_calendar
, overrides
) {
12751 var _this
= _super
.call(this) || this;
12752 _this
._calendar
= _calendar
;
12753 _this
.overrides
= $.extend({}, overrides
); // make a copy
12754 _this
.dynamicOverrides
= {};
12758 OptionsManager
.prototype.add = function (newOptionHash
) {
12761 this.recordOverrides(newOptionHash
); // will trigger this model's watchers
12762 for (optionName
in newOptionHash
) {
12765 // special-case handling of single option change.
12766 // if only one option change, `optionName` will be its name.
12767 if (optionCnt
=== 1) {
12768 if (optionName
=== 'height' || optionName
=== 'contentHeight' || optionName
=== 'aspectRatio') {
12769 this._calendar
.updateViewSize(true); // isResize=true
12772 else if (optionName
=== 'defaultDate') {
12773 return; // can't change date this way. use gotoDate instead
12775 else if (optionName
=== 'businessHours') {
12776 return; // this model already reacts to this
12778 else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName
)) {
12779 return; // doesn't affect rendering. only interactions.
12781 else if (optionName
=== 'timezone') {
12782 this._calendar
.view
.flash('initialEvents');
12786 // catch-all. rerender the header and footer and rebuild/rerender the current view
12787 this._calendar
.renderHeader();
12788 this._calendar
.renderFooter();
12789 // even non-current views will be affected by this option change. do before rerender
12791 this._calendar
.viewsByType
= {};
12792 this._calendar
.reinitView();
12794 // Computes the flattened options hash for the calendar and assigns to `this.options`.
12795 // Assumes this.overrides and this.dynamicOverrides have already been initialized.
12796 OptionsManager
.prototype.compute = function () {
12798 var localeDefaults
;
12802 locale
= util_1
.firstDefined(// explicit locale option given?
12803 this.dynamicOverrides
.locale
, this.overrides
.locale
);
12804 localeDefaults
= locale_1
.localeOptionHash
[locale
];
12805 if (!localeDefaults
) {
12806 locale
= options_1
.globalDefaults
.locale
;
12807 localeDefaults
= locale_1
.localeOptionHash
[locale
] || {};
12809 isRTL
= util_1
.firstDefined(// based on options computed so far, is direction RTL?
12810 this.dynamicOverrides
.isRTL
, this.overrides
.isRTL
, localeDefaults
.isRTL
, options_1
.globalDefaults
.isRTL
);
12811 dirDefaults
= isRTL
? options_1
.rtlDefaults
: {};
12812 this.dirDefaults
= dirDefaults
;
12813 this.localeDefaults
= localeDefaults
;
12814 rawOptions
= options_1
.mergeOptions([
12815 options_1
.globalDefaults
,
12819 this.dynamicOverrides
12821 locale_1
.populateInstanceComputableOptions(rawOptions
); // fill in gaps with computed options
12822 this.reset(rawOptions
);
12824 // stores the new options internally, but does not rerender anything.
12825 OptionsManager
.prototype.recordOverrides = function (newOptionHash
) {
12827 for (optionName
in newOptionHash
) {
12828 this.dynamicOverrides
[optionName
] = newOptionHash
[optionName
];
12830 this._calendar
.viewSpecManager
.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it
12831 this.compute(); // this.options needs to be recomputed after the dynamic override
12833 return OptionsManager
;
12834 }(Model_1
.default));
12835 exports
.default = OptionsManager
;
12840 /***/ (function(module
, exports
, __webpack_require__
) {
12842 Object
.defineProperty(exports
, "__esModule", { value
: true });
12843 var moment
= __webpack_require__(0);
12844 var $ = __webpack_require__(3);
12845 var ViewRegistry_1
= __webpack_require__(22);
12846 var util_1
= __webpack_require__(4);
12847 var options_1
= __webpack_require__(32);
12848 var locale_1
= __webpack_require__(31);
12849 var ViewSpecManager
= /** @class */ (function () {
12850 function ViewSpecManager(optionsManager
, _calendar
) {
12851 this.optionsManager
= optionsManager
;
12852 this._calendar
= _calendar
;
12855 ViewSpecManager
.prototype.clearCache = function () {
12856 this.viewSpecCache
= {};
12858 // Gets information about how to create a view. Will use a cache.
12859 ViewSpecManager
.prototype.getViewSpec = function (viewType
) {
12860 var cache
= this.viewSpecCache
;
12861 return cache
[viewType
] || (cache
[viewType
] = this.buildViewSpec(viewType
));
12863 // Given a duration singular unit, like "week" or "day", finds a matching view spec.
12864 // Preference is given to views that have corresponding buttons.
12865 ViewSpecManager
.prototype.getUnitViewSpec = function (unit
) {
12869 if ($.inArray(unit
, util_1
.unitsDesc
) !== -1) {
12870 // put views that have buttons first. there will be duplicates, but oh well
12871 viewTypes
= this._calendar
.header
.getViewsWithButtons(); // TODO: include footer as well?
12872 $.each(ViewRegistry_1
.viewHash
, function (viewType
) {
12873 viewTypes
.push(viewType
);
12875 for (i
= 0; i
< viewTypes
.length
; i
++) {
12876 spec
= this.getViewSpec(viewTypes
[i
]);
12878 if (spec
.singleUnit
=== unit
) {
12885 // Builds an object with information on how to create a given view
12886 ViewSpecManager
.prototype.buildViewSpec = function (requestedViewType
) {
12887 var viewOverrides
= this.optionsManager
.overrides
.views
|| {};
12888 var specChain
= []; // for the view. lowest to highest priority
12889 var defaultsChain
= []; // for the view. lowest to highest priority
12890 var overridesChain
= []; // for the view. lowest to highest priority
12891 var viewType
= requestedViewType
;
12892 var spec
; // for the view
12893 var overrides
; // for the view
12897 // iterate from the specific view definition to a more general one until we hit an actual View class
12899 spec
= ViewRegistry_1
.viewHash
[viewType
];
12900 overrides
= viewOverrides
[viewType
];
12901 viewType
= null; // clear. might repopulate for another iteration
12902 if (typeof spec
=== 'function') {
12903 spec
= { 'class': spec
};
12906 specChain
.unshift(spec
);
12907 defaultsChain
.unshift(spec
.defaults
|| {});
12908 durationInput
= durationInput
|| spec
.duration
;
12909 viewType
= viewType
|| spec
.type
;
12912 overridesChain
.unshift(overrides
); // view-specific option hashes have options at zero-level
12913 durationInput
= durationInput
|| overrides
.duration
;
12914 viewType
= viewType
|| overrides
.type
;
12917 spec
= util_1
.mergeProps(specChain
);
12918 spec
.type
= requestedViewType
;
12919 if (!spec
['class']) {
12922 // fall back to top-level `duration` option
12923 durationInput
= durationInput
||
12924 this.optionsManager
.dynamicOverrides
.duration
||
12925 this.optionsManager
.overrides
.duration
;
12926 if (durationInput
) {
12927 duration
= moment
.duration(durationInput
);
12928 if (duration
.valueOf()) {
12929 unit
= util_1
.computeDurationGreatestUnit(duration
, durationInput
);
12930 spec
.duration
= duration
;
12931 spec
.durationUnit
= unit
;
12932 // view is a single-unit duration, like "week" or "day"
12933 // incorporate options for this. lowest priority
12934 if (duration
.as(unit
) === 1) {
12935 spec
.singleUnit
= unit
;
12936 overridesChain
.unshift(viewOverrides
[unit
] || {});
12940 spec
.defaults
= options_1
.mergeOptions(defaultsChain
);
12941 spec
.overrides
= options_1
.mergeOptions(overridesChain
);
12942 this.buildViewSpecOptions(spec
);
12943 this.buildViewSpecButtonText(spec
, requestedViewType
);
12946 // Builds and assigns a view spec's options object from its already-assigned defaults and overrides
12947 ViewSpecManager
.prototype.buildViewSpecOptions = function (spec
) {
12948 var optionsManager
= this.optionsManager
;
12949 spec
.options
= options_1
.mergeOptions([
12950 options_1
.globalDefaults
,
12952 optionsManager
.dirDefaults
,
12953 optionsManager
.localeDefaults
,
12954 optionsManager
.overrides
,
12956 optionsManager
.dynamicOverrides
// dynamically set via setter. highest precedence
12958 locale_1
.populateInstanceComputableOptions(spec
.options
);
12960 // Computes and assigns a view spec's buttonText-related options
12961 ViewSpecManager
.prototype.buildViewSpecButtonText = function (spec
, requestedViewType
) {
12962 var optionsManager
= this.optionsManager
;
12963 // given an options object with a possible `buttonText` hash, lookup the buttonText for the
12964 // requested view, falling back to a generic unit entry like "week" or "day"
12965 function queryButtonText(options
) {
12966 var buttonText
= options
.buttonText
|| {};
12967 return buttonText
[requestedViewType
] ||
12968 // view can decide to look up a certain key
12969 (spec
.buttonTextKey
? buttonText
[spec
.buttonTextKey
] : null) ||
12970 // a key like "month"
12971 (spec
.singleUnit
? buttonText
[spec
.singleUnit
] : null);
12973 // highest to lowest priority
12974 spec
.buttonTextOverride
=
12975 queryButtonText(optionsManager
.dynamicOverrides
) ||
12976 queryButtonText(optionsManager
.overrides
) || // constructor-specified buttonText lookup hash takes precedence
12977 spec
.overrides
.buttonText
; // `buttonText` for view-specific options is a string
12978 // highest to lowest priority. mirrors buildViewSpecOptions
12979 spec
.buttonTextDefault
=
12980 queryButtonText(optionsManager
.localeDefaults
) ||
12981 queryButtonText(optionsManager
.dirDefaults
) ||
12982 spec
.defaults
.buttonText
|| // a single string. from ViewSubclass.defaults
12983 queryButtonText(options_1
.globalDefaults
) ||
12984 (spec
.duration
? this._calendar
.humanizeDuration(spec
.duration
) : null) || // like "3 days"
12985 requestedViewType
; // fall back to given view name
12987 return ViewSpecManager
;
12989 exports
.default = ViewSpecManager
;
12994 /***/ (function(module
, exports
, __webpack_require__
) {
12996 Object
.defineProperty(exports
, "__esModule", { value
: true });
12997 var $ = __webpack_require__(3);
12998 var util_1
= __webpack_require__(4);
12999 var EventPeriod_1
= __webpack_require__(243);
13000 var ArrayEventSource_1
= __webpack_require__(52);
13001 var EventSource_1
= __webpack_require__(6);
13002 var EventSourceParser_1
= __webpack_require__(38);
13003 var SingleEventDef_1
= __webpack_require__(13);
13004 var EventInstanceGroup_1
= __webpack_require__(18);
13005 var EmitterMixin_1
= __webpack_require__(11);
13006 var ListenerMixin_1
= __webpack_require__(7);
13007 var EventManager
= /** @class */ (function () {
13008 function EventManager(calendar
) {
13009 this.calendar
= calendar
;
13010 this.stickySource
= new ArrayEventSource_1
.default(calendar
);
13011 this.otherSources
= [];
13013 EventManager
.prototype.requestEvents = function (start
, end
, timezone
, force
) {
13015 !this.currentPeriod
||
13016 !this.currentPeriod
.isWithinRange(start
, end
) ||
13017 timezone
!== this.currentPeriod
.timezone
) {
13018 this.setPeriod(// will change this.currentPeriod
13019 new EventPeriod_1
.default(start
, end
, timezone
));
13021 return this.currentPeriod
.whenReleased();
13023 // Source Adding/Removing
13024 // -----------------------------------------------------------------------------------------------------------------
13025 EventManager
.prototype.addSource = function (eventSource
) {
13026 this.otherSources
.push(eventSource
);
13027 if (this.currentPeriod
) {
13028 this.currentPeriod
.requestSource(eventSource
); // might release
13031 EventManager
.prototype.removeSource = function (doomedSource
) {
13032 util_1
.removeExact(this.otherSources
, doomedSource
);
13033 if (this.currentPeriod
) {
13034 this.currentPeriod
.purgeSource(doomedSource
); // might release
13037 EventManager
.prototype.removeAllSources = function () {
13038 this.otherSources
= [];
13039 if (this.currentPeriod
) {
13040 this.currentPeriod
.purgeAllSources(); // might release
13043 // Source Refetching
13044 // -----------------------------------------------------------------------------------------------------------------
13045 EventManager
.prototype.refetchSource = function (eventSource
) {
13046 var currentPeriod
= this.currentPeriod
;
13047 if (currentPeriod
) {
13048 currentPeriod
.freeze();
13049 currentPeriod
.purgeSource(eventSource
);
13050 currentPeriod
.requestSource(eventSource
);
13051 currentPeriod
.thaw();
13054 EventManager
.prototype.refetchAllSources = function () {
13055 var currentPeriod
= this.currentPeriod
;
13056 if (currentPeriod
) {
13057 currentPeriod
.freeze();
13058 currentPeriod
.purgeAllSources();
13059 currentPeriod
.requestSources(this.getSources());
13060 currentPeriod
.thaw();
13064 // -----------------------------------------------------------------------------------------------------------------
13065 EventManager
.prototype.getSources = function () {
13066 return [this.stickySource
].concat(this.otherSources
);
13068 // like querySources, but accepts multple match criteria (like multiple IDs)
13069 EventManager
.prototype.multiQuerySources = function (matchInputs
) {
13070 // coerce into an array
13071 if (!matchInputs
) {
13074 else if (!$.isArray(matchInputs
)) {
13075 matchInputs
= [matchInputs
];
13077 var matchingSources
= [];
13079 // resolve raw inputs to real event source objects
13080 for (i
= 0; i
< matchInputs
.length
; i
++) {
13081 matchingSources
.push
.apply(// append
13082 matchingSources
, this.querySources(matchInputs
[i
]));
13084 return matchingSources
;
13086 // matchInput can either by a real event source object, an ID, or the function/URL for the source.
13087 // returns an array of matching source objects.
13088 EventManager
.prototype.querySources = function (matchInput
) {
13089 var sources
= this.otherSources
;
13092 // given a proper event source object
13093 for (i
= 0; i
< sources
.length
; i
++) {
13094 source
= sources
[i
];
13095 if (source
=== matchInput
) {
13100 source
= this.getSourceById(EventSource_1
.default.normalizeId(matchInput
));
13104 // parse as an event source
13105 matchInput
= EventSourceParser_1
.default.parse(matchInput
, this.calendar
);
13107 return $.grep(sources
, function (source
) {
13108 return isSourcesEquivalent(matchInput
, source
);
13113 ID assumed to already be normalized
13115 EventManager
.prototype.getSourceById = function (id
) {
13116 return $.grep(this.otherSources
, function (source
) {
13117 return source
.id
&& source
.id
=== id
;
13121 // -----------------------------------------------------------------------------------------------------------------
13122 EventManager
.prototype.setPeriod = function (eventPeriod
) {
13123 if (this.currentPeriod
) {
13124 this.unbindPeriod(this.currentPeriod
);
13125 this.currentPeriod
= null;
13127 this.currentPeriod
= eventPeriod
;
13128 this.bindPeriod(eventPeriod
);
13129 eventPeriod
.requestSources(this.getSources());
13131 EventManager
.prototype.bindPeriod = function (eventPeriod
) {
13132 this.listenTo(eventPeriod
, 'release', function (eventsPayload
) {
13133 this.trigger('release', eventsPayload
);
13136 EventManager
.prototype.unbindPeriod = function (eventPeriod
) {
13137 this.stopListeningTo(eventPeriod
);
13139 // Event Getting/Adding/Removing
13140 // -----------------------------------------------------------------------------------------------------------------
13141 EventManager
.prototype.getEventDefByUid = function (uid
) {
13142 if (this.currentPeriod
) {
13143 return this.currentPeriod
.getEventDefByUid(uid
);
13146 EventManager
.prototype.addEventDef = function (eventDef
, isSticky
) {
13148 this.stickySource
.addEventDef(eventDef
);
13150 if (this.currentPeriod
) {
13151 this.currentPeriod
.addEventDef(eventDef
); // might release
13154 EventManager
.prototype.removeEventDefsById = function (eventId
) {
13155 this.getSources().forEach(function (eventSource
) {
13156 eventSource
.removeEventDefsById(eventId
);
13158 if (this.currentPeriod
) {
13159 this.currentPeriod
.removeEventDefsById(eventId
); // might release
13162 EventManager
.prototype.removeAllEventDefs = function () {
13163 this.getSources().forEach(function (eventSource
) {
13164 eventSource
.removeAllEventDefs();
13166 if (this.currentPeriod
) {
13167 this.currentPeriod
.removeAllEventDefs();
13171 // -----------------------------------------------------------------------------------------------------------------
13173 Returns an undo function.
13175 EventManager
.prototype.mutateEventsWithId = function (eventDefId
, eventDefMutation
) {
13176 var currentPeriod
= this.currentPeriod
;
13178 var undoFuncs
= [];
13179 if (currentPeriod
) {
13180 currentPeriod
.freeze();
13181 eventDefs
= currentPeriod
.getEventDefsById(eventDefId
);
13182 eventDefs
.forEach(function (eventDef
) {
13183 // add/remove esp because id might change
13184 currentPeriod
.removeEventDef(eventDef
);
13185 undoFuncs
.push(eventDefMutation
.mutateSingle(eventDef
));
13186 currentPeriod
.addEventDef(eventDef
);
13188 currentPeriod
.thaw();
13189 return function () {
13190 currentPeriod
.freeze();
13191 for (var i
= 0; i
< eventDefs
.length
; i
++) {
13192 currentPeriod
.removeEventDef(eventDefs
[i
]);
13194 currentPeriod
.addEventDef(eventDefs
[i
]);
13196 currentPeriod
.thaw();
13199 return function () { };
13202 copies and then mutates
13204 EventManager
.prototype.buildMutatedEventInstanceGroup = function (eventDefId
, eventDefMutation
) {
13205 var eventDefs
= this.getEventDefsById(eventDefId
);
13208 var allInstances
= [];
13209 for (i
= 0; i
< eventDefs
.length
; i
++) {
13210 defCopy
= eventDefs
[i
].clone();
13211 if (defCopy
instanceof SingleEventDef_1
.default) {
13212 eventDefMutation
.mutateSingle(defCopy
);
13213 allInstances
.push
.apply(allInstances
, // append
13214 defCopy
.buildInstances());
13217 return new EventInstanceGroup_1
.default(allInstances
);
13220 // -----------------------------------------------------------------------------------------------------------------
13221 EventManager
.prototype.freeze = function () {
13222 if (this.currentPeriod
) {
13223 this.currentPeriod
.freeze();
13226 EventManager
.prototype.thaw = function () {
13227 if (this.currentPeriod
) {
13228 this.currentPeriod
.thaw();
13231 // methods that simply forward to EventPeriod
13232 EventManager
.prototype.getEventDefsById = function (eventDefId
) {
13233 return this.currentPeriod
.getEventDefsById(eventDefId
);
13235 EventManager
.prototype.getEventInstances = function () {
13236 return this.currentPeriod
.getEventInstances();
13238 EventManager
.prototype.getEventInstancesWithId = function (eventDefId
) {
13239 return this.currentPeriod
.getEventInstancesWithId(eventDefId
);
13241 EventManager
.prototype.getEventInstancesWithoutId = function (eventDefId
) {
13242 return this.currentPeriod
.getEventInstancesWithoutId(eventDefId
);
13244 return EventManager
;
13246 exports
.default = EventManager
;
13247 EmitterMixin_1
.default.mixInto(EventManager
);
13248 ListenerMixin_1
.default.mixInto(EventManager
);
13249 function isSourcesEquivalent(source0
, source1
) {
13250 return source0
.getPrimitive() === source1
.getPrimitive();
13256 /***/ (function(module
, exports
, __webpack_require__
) {
13258 Object
.defineProperty(exports
, "__esModule", { value
: true });
13259 var $ = __webpack_require__(3);
13260 var util_1
= __webpack_require__(4);
13261 var Promise_1
= __webpack_require__(20);
13262 var EmitterMixin_1
= __webpack_require__(11);
13263 var UnzonedRange_1
= __webpack_require__(5);
13264 var EventInstanceGroup_1
= __webpack_require__(18);
13265 var EventPeriod
= /** @class */ (function () {
13266 function EventPeriod(start
, end
, timezone
) {
13267 this.pendingCnt
= 0;
13268 this.freezeDepth
= 0;
13269 this.stuntedReleaseCnt
= 0;
13270 this.releaseCnt
= 0;
13271 this.start
= start
;
13273 this.timezone
= timezone
;
13274 this.unzonedRange
= new UnzonedRange_1
.default(start
.clone().stripZone(), end
.clone().stripZone());
13275 this.requestsByUid
= {};
13276 this.eventDefsByUid
= {};
13277 this.eventDefsById
= {};
13278 this.eventInstanceGroupsById
= {};
13280 EventPeriod
.prototype.isWithinRange = function (start
, end
) {
13281 // TODO: use a range util function?
13282 return !start
.isBefore(this.start
) && !end
.isAfter(this.end
);
13284 // Requesting and Purging
13285 // -----------------------------------------------------------------------------------------------------------------
13286 EventPeriod
.prototype.requestSources = function (sources
) {
13288 for (var i
= 0; i
< sources
.length
; i
++) {
13289 this.requestSource(sources
[i
]);
13293 EventPeriod
.prototype.requestSource = function (source
) {
13295 var request
= { source
: source
, status
: 'pending', eventDefs
: null };
13296 this.requestsByUid
[source
.uid
] = request
;
13297 this.pendingCnt
+= 1;
13298 source
.fetch(this.start
, this.end
, this.timezone
).then(function (eventDefs
) {
13299 if (request
.status
!== 'cancelled') {
13300 request
.status
= 'completed';
13301 request
.eventDefs
= eventDefs
;
13302 _this
.addEventDefs(eventDefs
);
13303 _this
.pendingCnt
--;
13304 _this
.tryRelease();
13307 if (request
.status
!== 'cancelled') {
13308 request
.status
= 'failed';
13309 _this
.pendingCnt
--;
13310 _this
.tryRelease();
13314 EventPeriod
.prototype.purgeSource = function (source
) {
13315 var request
= this.requestsByUid
[source
.uid
];
13317 delete this.requestsByUid
[source
.uid
];
13318 if (request
.status
=== 'pending') {
13319 request
.status
= 'cancelled';
13323 else if (request
.status
=== 'completed') {
13324 request
.eventDefs
.forEach(this.removeEventDef
.bind(this));
13328 EventPeriod
.prototype.purgeAllSources = function () {
13329 var requestsByUid
= this.requestsByUid
;
13332 var completedCnt
= 0;
13333 for (uid
in requestsByUid
) {
13334 request
= requestsByUid
[uid
];
13335 if (request
.status
=== 'pending') {
13336 request
.status
= 'cancelled';
13338 else if (request
.status
=== 'completed') {
13342 this.requestsByUid
= {};
13343 this.pendingCnt
= 0;
13344 if (completedCnt
) {
13345 this.removeAllEventDefs(); // might release
13348 // Event Definitions
13349 // -----------------------------------------------------------------------------------------------------------------
13350 EventPeriod
.prototype.getEventDefByUid = function (eventDefUid
) {
13351 return this.eventDefsByUid
[eventDefUid
];
13353 EventPeriod
.prototype.getEventDefsById = function (eventDefId
) {
13354 var a
= this.eventDefsById
[eventDefId
];
13356 return a
.slice(); // clone
13360 EventPeriod
.prototype.addEventDefs = function (eventDefs
) {
13361 for (var i
= 0; i
< eventDefs
.length
; i
++) {
13362 this.addEventDef(eventDefs
[i
]);
13365 EventPeriod
.prototype.addEventDef = function (eventDef
) {
13366 var eventDefsById
= this.eventDefsById
;
13367 var eventDefId
= eventDef
.id
;
13368 var eventDefs
= eventDefsById
[eventDefId
] || (eventDefsById
[eventDefId
] = []);
13369 var eventInstances
= eventDef
.buildInstances(this.unzonedRange
);
13371 eventDefs
.push(eventDef
);
13372 this.eventDefsByUid
[eventDef
.uid
] = eventDef
;
13373 for (i
= 0; i
< eventInstances
.length
; i
++) {
13374 this.addEventInstance(eventInstances
[i
], eventDefId
);
13377 EventPeriod
.prototype.removeEventDefsById = function (eventDefId
) {
13379 this.getEventDefsById(eventDefId
).forEach(function (eventDef
) {
13380 _this
.removeEventDef(eventDef
);
13383 EventPeriod
.prototype.removeAllEventDefs = function () {
13384 var isEmpty
= $.isEmptyObject(this.eventDefsByUid
);
13385 this.eventDefsByUid
= {};
13386 this.eventDefsById
= {};
13387 this.eventInstanceGroupsById
= {};
13392 EventPeriod
.prototype.removeEventDef = function (eventDef
) {
13393 var eventDefsById
= this.eventDefsById
;
13394 var eventDefs
= eventDefsById
[eventDef
.id
];
13395 delete this.eventDefsByUid
[eventDef
.uid
];
13397 util_1
.removeExact(eventDefs
, eventDef
);
13398 if (!eventDefs
.length
) {
13399 delete eventDefsById
[eventDef
.id
];
13401 this.removeEventInstancesForDef(eventDef
);
13405 // -----------------------------------------------------------------------------------------------------------------
13406 EventPeriod
.prototype.getEventInstances = function () {
13407 var eventInstanceGroupsById
= this.eventInstanceGroupsById
;
13408 var eventInstances
= [];
13410 for (id
in eventInstanceGroupsById
) {
13411 eventInstances
.push
.apply(eventInstances
, // append
13412 eventInstanceGroupsById
[id
].eventInstances
);
13414 return eventInstances
;
13416 EventPeriod
.prototype.getEventInstancesWithId = function (eventDefId
) {
13417 var eventInstanceGroup
= this.eventInstanceGroupsById
[eventDefId
];
13418 if (eventInstanceGroup
) {
13419 return eventInstanceGroup
.eventInstances
.slice(); // clone
13423 EventPeriod
.prototype.getEventInstancesWithoutId = function (eventDefId
) {
13424 var eventInstanceGroupsById
= this.eventInstanceGroupsById
;
13425 var matchingInstances
= [];
13427 for (id
in eventInstanceGroupsById
) {
13428 if (id
!== eventDefId
) {
13429 matchingInstances
.push
.apply(matchingInstances
, // append
13430 eventInstanceGroupsById
[id
].eventInstances
);
13433 return matchingInstances
;
13435 EventPeriod
.prototype.addEventInstance = function (eventInstance
, eventDefId
) {
13436 var eventInstanceGroupsById
= this.eventInstanceGroupsById
;
13437 var eventInstanceGroup
= eventInstanceGroupsById
[eventDefId
] ||
13438 (eventInstanceGroupsById
[eventDefId
] = new EventInstanceGroup_1
.default());
13439 eventInstanceGroup
.eventInstances
.push(eventInstance
);
13442 EventPeriod
.prototype.removeEventInstancesForDef = function (eventDef
) {
13443 var eventInstanceGroupsById
= this.eventInstanceGroupsById
;
13444 var eventInstanceGroup
= eventInstanceGroupsById
[eventDef
.id
];
13446 if (eventInstanceGroup
) {
13447 removeCnt
= util_1
.removeMatching(eventInstanceGroup
.eventInstances
, function (currentEventInstance
) {
13448 return currentEventInstance
.def
=== eventDef
;
13450 if (!eventInstanceGroup
.eventInstances
.length
) {
13451 delete eventInstanceGroupsById
[eventDef
.id
];
13458 // Releasing and Freezing
13459 // -----------------------------------------------------------------------------------------------------------------
13460 EventPeriod
.prototype.tryRelease = function () {
13461 if (!this.pendingCnt
) {
13462 if (!this.freezeDepth
) {
13466 this.stuntedReleaseCnt
++;
13470 EventPeriod
.prototype.release = function () {
13472 this.trigger('release', this.eventInstanceGroupsById
);
13474 EventPeriod
.prototype.whenReleased = function () {
13476 if (this.releaseCnt
) {
13477 return Promise_1
.default.resolve(this.eventInstanceGroupsById
);
13480 return Promise_1
.default.construct(function (onResolve
) {
13481 _this
.one('release', onResolve
);
13485 EventPeriod
.prototype.freeze = function () {
13486 if (!(this.freezeDepth
++)) {
13487 this.stuntedReleaseCnt
= 0;
13490 EventPeriod
.prototype.thaw = function () {
13491 if (!(--this.freezeDepth
) && this.stuntedReleaseCnt
&& !this.pendingCnt
) {
13495 return EventPeriod
;
13497 exports
.default = EventPeriod
;
13498 EmitterMixin_1
.default.mixInto(EventPeriod
);
13503 /***/ (function(module
, exports
, __webpack_require__
) {
13505 Object
.defineProperty(exports
, "__esModule", { value
: true });
13506 var $ = __webpack_require__(3);
13507 var util_1
= __webpack_require__(4);
13508 var ListenerMixin_1
= __webpack_require__(7);
13509 /* Creates a clone of an element and lets it track the mouse as it moves
13510 ----------------------------------------------------------------------------------------------------------------------*/
13511 var MouseFollower
= /** @class */ (function () {
13512 function MouseFollower(sourceEl
, options
) {
13513 this.isFollowing
= false;
13514 this.isHidden
= false;
13515 this.isAnimating
= false; // doing the revert animation?
13516 this.options
= options
= options
|| {};
13517 this.sourceEl
= sourceEl
;
13518 this.parentEl
= options
.parentEl
? $(options
.parentEl
) : sourceEl
.parent(); // default to sourceEl's parent
13520 // Causes the element to start following the mouse
13521 MouseFollower
.prototype.start = function (ev
) {
13522 if (!this.isFollowing
) {
13523 this.isFollowing
= true;
13524 this.y0
= util_1
.getEvY(ev
);
13525 this.x0
= util_1
.getEvX(ev
);
13527 this.leftDelta
= 0;
13528 if (!this.isHidden
) {
13529 this.updatePosition();
13531 if (util_1
.getEvIsTouch(ev
)) {
13532 this.listenTo($(document
), 'touchmove', this.handleMove
);
13535 this.listenTo($(document
), 'mousemove', this.handleMove
);
13539 // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
13540 // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.
13541 MouseFollower
.prototype.stop = function (shouldRevert
, callback
) {
13543 var revertDuration
= this.options
.revertDuration
;
13544 var complete = function () {
13545 _this
.isAnimating
= false;
13546 _this
.removeElement();
13547 _this
.top0
= _this
.left0
= null; // reset state for future updatePosition calls
13552 if (this.isFollowing
&& !this.isAnimating
) {
13553 this.isFollowing
= false;
13554 this.stopListeningTo($(document
));
13555 if (shouldRevert
&& revertDuration
&& !this.isHidden
) {
13556 this.isAnimating
= true;
13561 duration
: revertDuration
,
13570 // Gets the tracking element. Create it if necessary
13571 MouseFollower
.prototype.getEl = function () {
13574 el
= this.el
= this.sourceEl
.clone()
13575 .addClass(this.options
.additionalClass
|| '')
13577 position
: 'absolute',
13579 display
: this.isHidden
? 'none' : '',
13583 width
: this.sourceEl
.width(),
13584 height
: this.sourceEl
.height(),
13585 opacity
: this.options
.opacity
|| '',
13586 zIndex
: this.options
.zIndex
13588 // we don't want long taps or any mouse interaction causing selection/menus.
13589 // would use preventSelection(), but that prevents selectstart, causing problems.
13590 el
.addClass('fc-unselectable');
13591 el
.appendTo(this.parentEl
);
13595 // Removes the tracking element if it has already been created
13596 MouseFollower
.prototype.removeElement = function () {
13602 // Update the CSS position of the tracking element
13603 MouseFollower
.prototype.updatePosition = function () {
13606 this.getEl(); // ensure this.el
13607 // make sure origin info was computed
13608 if (this.top0
== null) {
13609 sourceOffset
= this.sourceEl
.offset();
13610 origin
= this.el
.offsetParent().offset();
13611 this.top0
= sourceOffset
.top
- origin
.top
;
13612 this.left0
= sourceOffset
.left
- origin
.left
;
13615 top
: this.top0
+ this.topDelta
,
13616 left
: this.left0
+ this.leftDelta
13619 // Gets called when the user moves the mouse
13620 MouseFollower
.prototype.handleMove = function (ev
) {
13621 this.topDelta
= util_1
.getEvY(ev
) - this.y0
;
13622 this.leftDelta
= util_1
.getEvX(ev
) - this.x0
;
13623 if (!this.isHidden
) {
13624 this.updatePosition();
13627 // Temporarily makes the tracking element invisible. Can be called before following starts
13628 MouseFollower
.prototype.hide = function () {
13629 if (!this.isHidden
) {
13630 this.isHidden
= true;
13636 // Show the tracking element after it has been temporarily hidden
13637 MouseFollower
.prototype.show = function () {
13638 if (this.isHidden
) {
13639 this.isHidden
= false;
13640 this.updatePosition();
13641 this.getEl().show();
13644 return MouseFollower
;
13646 exports
.default = MouseFollower
;
13647 ListenerMixin_1
.default.mixInto(MouseFollower
);
13652 /***/ (function(module
, exports
, __webpack_require__
) {
13654 Object
.defineProperty(exports
, "__esModule", { value
: true });
13655 var tslib_1
= __webpack_require__(2);
13656 var HitDragListener_1
= __webpack_require__(23);
13657 var Interaction_1
= __webpack_require__(15);
13658 var DateClicking
= /** @class */ (function (_super
) {
13659 tslib_1
.__extends(DateClicking
, _super
);
13661 component must implement:
13662 - bindDateHandlerToEl
13663 - getSafeHitFootprint
13666 function DateClicking(component
) {
13667 var _this
= _super
.call(this, component
) || this;
13668 _this
.dragListener
= _this
.buildDragListener();
13671 DateClicking
.prototype.end = function () {
13672 this.dragListener
.endInteraction();
13674 DateClicking
.prototype.bindToEl = function (el
) {
13675 var component
= this.component
;
13676 var dragListener
= this.dragListener
;
13677 component
.bindDateHandlerToEl(el
, 'mousedown', function (ev
) {
13678 if (!component
.shouldIgnoreMouse()) {
13679 dragListener
.startInteraction(ev
);
13682 component
.bindDateHandlerToEl(el
, 'touchstart', function (ev
) {
13683 if (!component
.shouldIgnoreTouch()) {
13684 dragListener
.startInteraction(ev
);
13688 // Creates a listener that tracks the user's drag across day elements, for day clicking.
13689 DateClicking
.prototype.buildDragListener = function () {
13691 var component
= this.component
;
13692 var dayClickHit
; // null if invalid dayClick
13693 var dragListener
= new HitDragListener_1
.default(component
, {
13694 scroll
: this.opt('dragScroll'),
13695 interactionStart: function () {
13696 dayClickHit
= dragListener
.origHit
;
13698 hitOver: function (hit
, isOrig
, origHit
) {
13699 // if user dragged to another cell at any point, it can no longer be a dayClick
13701 dayClickHit
= null;
13704 hitOut: function () {
13705 dayClickHit
= null;
13707 interactionEnd: function (ev
, isCancelled
) {
13708 var componentFootprint
;
13709 if (!isCancelled
&& dayClickHit
) {
13710 componentFootprint
= component
.getSafeHitFootprint(dayClickHit
);
13711 if (componentFootprint
) {
13712 _this
.view
.triggerDayClick(componentFootprint
, component
.getHitEl(dayClickHit
), ev
);
13717 // because dragListener won't be called with any time delay, "dragging" will begin immediately,
13718 // which will kill any touchmoving/scrolling. Prevent this.
13719 dragListener
.shouldCancelTouchScroll
= false;
13720 dragListener
.scrollAlwaysKills
= true;
13721 return dragListener
;
13723 return DateClicking
;
13724 }(Interaction_1
.default));
13725 exports
.default = DateClicking
;
13730 /***/ (function(module
, exports
, __webpack_require__
) {
13732 Object
.defineProperty(exports
, "__esModule", { value
: true });
13733 var tslib_1
= __webpack_require__(2);
13734 var util_1
= __webpack_require__(4);
13735 var EventRenderer_1
= __webpack_require__(42);
13737 Only handles foreground segs.
13738 Does not own rendering. Use for low-level util methods by TimeGrid.
13740 var TimeGridEventRenderer
= /** @class */ (function (_super
) {
13741 tslib_1
.__extends(TimeGridEventRenderer
, _super
);
13742 function TimeGridEventRenderer(timeGrid
, fillRenderer
) {
13743 var _this
= _super
.call(this, timeGrid
, fillRenderer
) || this;
13744 _this
.timeGrid
= timeGrid
;
13747 TimeGridEventRenderer
.prototype.renderFgSegs = function (segs
) {
13748 this.renderFgSegsIntoContainers(segs
, this.timeGrid
.fgContainerEls
);
13750 // Given an array of foreground segments, render a DOM element for each, computes position,
13751 // and attaches to the column inner-container elements.
13752 TimeGridEventRenderer
.prototype.renderFgSegsIntoContainers = function (segs
, containerEls
) {
13755 segsByCol
= this.timeGrid
.groupSegsByCol(segs
);
13756 for (col
= 0; col
< this.timeGrid
.colCnt
; col
++) {
13757 this.updateFgSegCoords(segsByCol
[col
]);
13759 this.timeGrid
.attachSegsByCol(segsByCol
, containerEls
);
13761 TimeGridEventRenderer
.prototype.unrenderFgSegs = function () {
13763 this.fgSegs
.forEach(function (seg
) {
13768 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
13769 TimeGridEventRenderer
.prototype.computeEventTimeFormat = function () {
13770 return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM)
13772 // Computes a default `displayEventEnd` value if one is not expliclty defined
13773 TimeGridEventRenderer
.prototype.computeDisplayEventEnd = function () {
13776 // Renders the HTML for a single event segment's default rendering
13777 TimeGridEventRenderer
.prototype.fgSegHtml = function (seg
, disableResizing
) {
13778 var view
= this.view
;
13779 var calendar
= view
.calendar
;
13780 var componentFootprint
= seg
.footprint
.componentFootprint
;
13781 var isAllDay
= componentFootprint
.isAllDay
;
13782 var eventDef
= seg
.footprint
.eventDef
;
13783 var isDraggable
= view
.isEventDefDraggable(eventDef
);
13784 var isResizableFromStart
= !disableResizing
&& seg
.isStart
&& view
.isEventDefResizableFromStart(eventDef
);
13785 var isResizableFromEnd
= !disableResizing
&& seg
.isEnd
&& view
.isEventDefResizableFromEnd(eventDef
);
13786 var classes
= this.getSegClasses(seg
, isDraggable
, isResizableFromStart
|| isResizableFromEnd
);
13787 var skinCss
= util_1
.cssToStr(this.getSkinCss(eventDef
));
13789 var fullTimeText
; // more verbose time text. for the print stylesheet
13790 var startTimeText
; // just the start time text
13791 classes
.unshift('fc-time-grid-event', 'fc-v-event');
13792 // if the event appears to span more than one day...
13793 if (view
.isMultiDayRange(componentFootprint
.unzonedRange
)) {
13794 // Don't display time text on segments that run entirely through a day.
13795 // That would appear as midnight-midnight and would look dumb.
13796 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
13797 if (seg
.isStart
|| seg
.isEnd
) {
13798 var zonedStart
= calendar
.msToMoment(seg
.startMs
);
13799 var zonedEnd
= calendar
.msToMoment(seg
.endMs
);
13800 timeText
= this._getTimeText(zonedStart
, zonedEnd
, isAllDay
);
13801 fullTimeText
= this._getTimeText(zonedStart
, zonedEnd
, isAllDay
, 'LT');
13802 startTimeText
= this._getTimeText(zonedStart
, zonedEnd
, isAllDay
, null, false); // displayEnd=false
13806 // Display the normal time text for the *event's* times
13807 timeText
= this.getTimeText(seg
.footprint
);
13808 fullTimeText
= this.getTimeText(seg
.footprint
, 'LT');
13809 startTimeText
= this.getTimeText(seg
.footprint
, null, false); // displayEnd=false
13811 return '<a class="' + classes
.join(' ') + '"' +
13813 ' href="' + util_1
.htmlEscape(eventDef
.url
) + '"' :
13816 ' style="' + skinCss
+ '"' :
13819 '<div class="fc-content">' +
13821 '<div class="fc-time"' +
13822 ' data-start="' + util_1
.htmlEscape(startTimeText
) + '"' +
13823 ' data-full="' + util_1
.htmlEscape(fullTimeText
) + '"' +
13825 '<span>' + util_1
.htmlEscape(timeText
) + '</span>' +
13829 '<div class="fc-title">' +
13830 util_1
.htmlEscape(eventDef
.title
) +
13834 '<div class="fc-bg"/>' +
13835 /* TODO: write CSS for this
13836 (isResizableFromStart ?
13837 '<div class="fc-resizer fc-start-resizer" />' :
13841 (isResizableFromEnd
?
13842 '<div class="fc-resizer fc-end-resizer" />' :
13846 // Given segments that are assumed to all live in the *same column*,
13847 // compute their verical/horizontal coordinates and assign to their elements.
13848 TimeGridEventRenderer
.prototype.updateFgSegCoords = function (segs
) {
13849 this.timeGrid
.computeSegVerticals(segs
); // horizontals relies on this
13850 this.computeFgSegHorizontals(segs
); // compute horizontal coordinates, z-index's, and reorder the array
13851 this.timeGrid
.assignSegVerticals(segs
);
13852 this.assignFgSegHorizontals(segs
);
13854 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
13855 // NOTE: Also reorders the given array by date!
13856 TimeGridEventRenderer
.prototype.computeFgSegHorizontals = function (segs
) {
13860 this.sortEventSegs(segs
); // order by certain criteria
13861 levels
= buildSlotSegLevels(segs
);
13862 computeForwardSlotSegs(levels
);
13863 if ((level0
= levels
[0])) {
13864 for (i
= 0; i
< level0
.length
; i
++) {
13865 computeSlotSegPressures(level0
[i
]);
13867 for (i
= 0; i
< level0
.length
; i
++) {
13868 this.computeFgSegForwardBack(level0
[i
], 0, 0);
13872 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13873 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13874 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13876 // The segment might be part of a "series", which means consecutive segments with the same pressure
13877 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13878 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13879 // coordinate of the first segment in the series.
13880 TimeGridEventRenderer
.prototype.computeFgSegForwardBack = function (seg
, seriesBackwardPressure
, seriesBackwardCoord
) {
13881 var forwardSegs
= seg
.forwardSegs
;
13883 if (seg
.forwardCoord
=== undefined) {
13884 if (!forwardSegs
.length
) {
13885 // if there are no forward segments, this segment should butt up against the edge
13886 seg
.forwardCoord
= 1;
13889 // sort highest pressure first
13890 this.sortForwardSegs(forwardSegs
);
13891 // this segment's forwardCoord will be calculated from the backwardCoord of the
13892 // highest-pressure forward segment.
13893 this.computeFgSegForwardBack(forwardSegs
[0], seriesBackwardPressure
+ 1, seriesBackwardCoord
);
13894 seg
.forwardCoord
= forwardSegs
[0].backwardCoord
;
13896 // calculate the backwardCoord from the forwardCoord. consider the series
13897 seg
.backwardCoord
= seg
.forwardCoord
-
13898 (seg
.forwardCoord
- seriesBackwardCoord
) / // available width for series
13899 (seriesBackwardPressure
+ 1); // # of segments in the series
13900 // use this segment's coordinates to computed the coordinates of the less-pressurized
13901 // forward segments
13902 for (i
= 0; i
< forwardSegs
.length
; i
++) {
13903 this.computeFgSegForwardBack(forwardSegs
[i
], 0, seg
.forwardCoord
);
13907 TimeGridEventRenderer
.prototype.sortForwardSegs = function (forwardSegs
) {
13908 forwardSegs
.sort(util_1
.proxy(this, 'compareForwardSegs'));
13910 // A cmp function for determining which forward segment to rely on more when computing coordinates.
13911 TimeGridEventRenderer
.prototype.compareForwardSegs = function (seg1
, seg2
) {
13912 // put higher-pressure first
13913 return seg2
.forwardPressure
- seg1
.forwardPressure
||
13914 // put segments that are closer to initial edge first (and favor ones with no coords yet)
13915 (seg1
.backwardCoord
|| 0) - (seg2
.backwardCoord
|| 0) ||
13916 // do normal sorting...
13917 this.compareEventSegs(seg1
, seg2
);
13919 // Given foreground event segments that have already had their position coordinates computed,
13920 // assigns position-related CSS values to their elements.
13921 TimeGridEventRenderer
.prototype.assignFgSegHorizontals = function (segs
) {
13924 for (i
= 0; i
< segs
.length
; i
++) {
13926 seg
.el
.css(this.generateFgSegHorizontalCss(seg
));
13927 // if the height is short, add a className for alternate styling
13928 if (seg
.bottom
- seg
.top
< 30) {
13929 seg
.el
.addClass('fc-short');
13933 // Generates an object with CSS properties/values that should be applied to an event segment element.
13934 // Contains important positioning-related properties that should be applied to any event element, customized or not.
13935 TimeGridEventRenderer
.prototype.generateFgSegHorizontalCss = function (seg
) {
13936 var shouldOverlap
= this.opt('slotEventOverlap');
13937 var backwardCoord
= seg
.backwardCoord
; // the left side if LTR. the right side if RTL. floating-point
13938 var forwardCoord
= seg
.forwardCoord
; // the right side if LTR. the left side if RTL. floating-point
13939 var props
= this.timeGrid
.generateSegVerticalCss(seg
); // get top/bottom first
13940 var isRTL
= this.timeGrid
.isRTL
;
13941 var left
; // amount of space from left edge, a fraction of the total width
13942 var right
; // amount of space from right edge, a fraction of the total width
13943 if (shouldOverlap
) {
13944 // double the width, but don't go beyond the maximum forward coordinate (1.0)
13945 forwardCoord
= Math
.min(1, backwardCoord
+ (forwardCoord
- backwardCoord
) * 2);
13948 left
= 1 - forwardCoord
;
13949 right
= backwardCoord
;
13952 left
= backwardCoord
;
13953 right
= 1 - forwardCoord
;
13955 props
.zIndex
= seg
.level
+ 1; // convert from 0-base to 1-based
13956 props
.left
= left
* 100 + '%';
13957 props
.right
= right
* 100 + '%';
13958 if (shouldOverlap
&& seg
.forwardPressure
) {
13959 // add padding to the edge so that forward stacked events don't cover the resizer's icon
13960 props
[isRTL
? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13964 return TimeGridEventRenderer
;
13965 }(EventRenderer_1
.default));
13966 exports
.default = TimeGridEventRenderer
;
13967 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
13968 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
13969 function buildSlotSegLevels(segs
) {
13974 for (i
= 0; i
< segs
.length
; i
++) {
13976 // go through all the levels and stop on the first level where there are no collisions
13977 for (j
= 0; j
< levels
.length
; j
++) {
13978 if (!computeSlotSegCollisions(seg
, levels
[j
]).length
) {
13983 (levels
[j
] || (levels
[j
] = [])).push(seg
);
13987 // For every segment, figure out the other segments that are in subsequent
13988 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13989 function computeForwardSlotSegs(levels
) {
13995 for (i
= 0; i
< levels
.length
; i
++) {
13997 for (j
= 0; j
< level
.length
; j
++) {
13999 seg
.forwardSegs
= [];
14000 for (k
= i
+ 1; k
< levels
.length
; k
++) {
14001 computeSlotSegCollisions(seg
, levels
[k
], seg
.forwardSegs
);
14006 // Figure out which path forward (via seg.forwardSegs) results in the longest path until
14007 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
14008 function computeSlotSegPressures(seg
) {
14009 var forwardSegs
= seg
.forwardSegs
;
14010 var forwardPressure
= 0;
14013 if (seg
.forwardPressure
=== undefined) {
14014 for (i
= 0; i
< forwardSegs
.length
; i
++) {
14015 forwardSeg
= forwardSegs
[i
];
14016 // figure out the child's maximum forward path
14017 computeSlotSegPressures(forwardSeg
);
14018 // either use the existing maximum, or use the child's forward pressure
14019 // plus one (for the forwardSeg itself)
14020 forwardPressure
= Math
.max(forwardPressure
, 1 + forwardSeg
.forwardPressure
);
14022 seg
.forwardPressure
= forwardPressure
;
14025 // Find all the segments in `otherSegs` that vertically collide with `seg`.
14026 // Append into an optionally-supplied `results` array and return.
14027 function computeSlotSegCollisions(seg
, otherSegs
, results
) {
14028 if (results
=== void 0) { results
= []; }
14029 for (var i
= 0; i
< otherSegs
.length
; i
++) {
14030 if (isSlotSegCollision(seg
, otherSegs
[i
])) {
14031 results
.push(otherSegs
[i
]);
14036 // Do these segments occupy the same vertical space?
14037 function isSlotSegCollision(seg1
, seg2
) {
14038 return seg1
.bottom
> seg2
.top
&& seg1
.top
< seg2
.bottom
;
14044 /***/ (function(module
, exports
, __webpack_require__
) {
14046 Object
.defineProperty(exports
, "__esModule", { value
: true });
14047 var tslib_1
= __webpack_require__(2);
14048 var $ = __webpack_require__(3);
14049 var HelperRenderer_1
= __webpack_require__(58);
14050 var TimeGridHelperRenderer
= /** @class */ (function (_super
) {
14051 tslib_1
.__extends(TimeGridHelperRenderer
, _super
);
14052 function TimeGridHelperRenderer() {
14053 return _super
!== null && _super
.apply(this, arguments
) || this;
14055 TimeGridHelperRenderer
.prototype.renderSegs = function (segs
, sourceSeg
) {
14056 var helperNodes
= [];
14060 // TODO: not good to call eventRenderer this way
14061 this.eventRenderer
.renderFgSegsIntoContainers(segs
, this.component
.helperContainerEls
);
14062 // Try to make the segment that is in the same row as sourceSeg look the same
14063 for (i
= 0; i
< segs
.length
; i
++) {
14065 if (sourceSeg
&& sourceSeg
.col
=== seg
.col
) {
14066 sourceEl
= sourceSeg
.el
;
14068 left
: sourceEl
.css('left'),
14069 right
: sourceEl
.css('right'),
14070 'margin-left': sourceEl
.css('margin-left'),
14071 'margin-right': sourceEl
.css('margin-right')
14074 helperNodes
.push(seg
.el
[0]);
14076 return $(helperNodes
); // must return the elements rendered
14078 return TimeGridHelperRenderer
;
14079 }(HelperRenderer_1
.default));
14080 exports
.default = TimeGridHelperRenderer
;
14085 /***/ (function(module
, exports
, __webpack_require__
) {
14087 Object
.defineProperty(exports
, "__esModule", { value
: true });
14088 var tslib_1
= __webpack_require__(2);
14089 var FillRenderer_1
= __webpack_require__(57);
14090 var TimeGridFillRenderer
= /** @class */ (function (_super
) {
14091 tslib_1
.__extends(TimeGridFillRenderer
, _super
);
14092 function TimeGridFillRenderer() {
14093 return _super
!== null && _super
.apply(this, arguments
) || this;
14095 TimeGridFillRenderer
.prototype.attachSegEls = function (type
, segs
) {
14096 var timeGrid
= this.component
;
14098 // TODO: more efficient lookup
14099 if (type
=== 'bgEvent') {
14100 containerEls
= timeGrid
.bgContainerEls
;
14102 else if (type
=== 'businessHours') {
14103 containerEls
= timeGrid
.businessContainerEls
;
14105 else if (type
=== 'highlight') {
14106 containerEls
= timeGrid
.highlightContainerEls
;
14108 timeGrid
.updateSegVerticals(segs
);
14109 timeGrid
.attachSegsByCol(timeGrid
.groupSegsByCol(segs
), containerEls
);
14110 return segs
.map(function (seg
) {
14114 return TimeGridFillRenderer
;
14115 }(FillRenderer_1
.default));
14116 exports
.default = TimeGridFillRenderer
;
14121 /***/ (function(module
, exports
, __webpack_require__
) {
14123 /* A rectangular panel that is absolutely positioned over other content
14124 ------------------------------------------------------------------------------------------------------------------------
14126 - className (string)
14127 - content (HTML string or jQuery element set)
14131 - right (the x coord of where the right edge should be. not a "CSS" right)
14132 - autoHide (boolean)
14136 Object
.defineProperty(exports
, "__esModule", { value
: true });
14137 var $ = __webpack_require__(3);
14138 var util_1
= __webpack_require__(4);
14139 var ListenerMixin_1
= __webpack_require__(7);
14140 var Popover
= /** @class */ (function () {
14141 function Popover(options
) {
14142 this.isHidden
= true;
14143 this.margin
= 10; // the space required between the popover and the edges of the scroll container
14144 this.options
= options
|| {};
14146 // Shows the popover on the specified position. Renders it if not already
14147 Popover
.prototype.show = function () {
14148 if (this.isHidden
) {
14154 this.isHidden
= false;
14155 this.trigger('show');
14158 // Hides the popover, through CSS, but does not remove it from the DOM
14159 Popover
.prototype.hide = function () {
14160 if (!this.isHidden
) {
14162 this.isHidden
= true;
14163 this.trigger('hide');
14166 // Creates `this.el` and renders content inside of it
14167 Popover
.prototype.render = function () {
14169 var options
= this.options
;
14170 this.el
= $('<div class="fc-popover"/>')
14171 .addClass(options
.className
|| '')
14173 // position initially to the top left to avoid creating scrollbars
14177 .append(options
.content
)
14178 .appendTo(options
.parentEl
);
14179 // when a click happens on anything inside with a 'fc-close' className, hide the popover
14180 this.el
.on('click', '.fc-close', function () {
14183 if (options
.autoHide
) {
14184 this.listenTo($(document
), 'mousedown', this.documentMousedown
);
14187 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
14188 Popover
.prototype.documentMousedown = function (ev
) {
14189 // only hide the popover if the click happened outside the popover
14190 if (this.el
&& !$(ev
.target
).closest(this.el
).length
) {
14194 // Hides and unregisters any handlers
14195 Popover
.prototype.removeElement = function () {
14201 this.stopListeningTo($(document
), 'mousedown');
14203 // Positions the popover optimally, using the top/left/right options
14204 Popover
.prototype.position = function () {
14205 var options
= this.options
;
14206 var origin
= this.el
.offsetParent().offset();
14207 var width
= this.el
.outerWidth();
14208 var height
= this.el
.outerHeight();
14209 var windowEl
= $(window
);
14210 var viewportEl
= util_1
.getScrollParent(this.el
);
14213 var viewportOffset
;
14214 var top
; // the "position" (not "offset") values for the popover
14216 // compute top and left
14217 top
= options
.top
|| 0;
14218 if (options
.left
!== undefined) {
14219 left
= options
.left
;
14221 else if (options
.right
!== undefined) {
14222 left
= options
.right
- width
; // derive the left value from the right value
14227 if (viewportEl
.is(window
) || viewportEl
.is(document
)) {
14228 viewportEl
= windowEl
;
14229 viewportTop
= 0; // the window is always at the top left
14230 viewportLeft
= 0; // (and .offset() won't work if called here)
14233 viewportOffset
= viewportEl
.offset();
14234 viewportTop
= viewportOffset
.top
;
14235 viewportLeft
= viewportOffset
.left
;
14237 // if the window is scrolled, it causes the visible area to be further down
14238 viewportTop
+= windowEl
.scrollTop();
14239 viewportLeft
+= windowEl
.scrollLeft();
14240 // constrain to the view port. if constrained by two edges, give precedence to top/left
14241 if (options
.viewportConstrain
!== false) {
14242 top
= Math
.min(top
, viewportTop
+ viewportEl
.outerHeight() - height
- this.margin
);
14243 top
= Math
.max(top
, viewportTop
+ this.margin
);
14244 left
= Math
.min(left
, viewportLeft
+ viewportEl
.outerWidth() - width
- this.margin
);
14245 left
= Math
.max(left
, viewportLeft
+ this.margin
);
14248 top
: top
- origin
.top
,
14249 left
: left
- origin
.left
14252 // Triggers a callback. Calls a function in the option hash of the same name.
14253 // Arguments beyond the first `name` are forwarded on.
14254 // TODO: better code reuse for this. Repeat code
14255 Popover
.prototype.trigger = function (name
) {
14256 if (this.options
[name
]) {
14257 this.options
[name
].apply(this, Array
.prototype.slice
.call(arguments
, 1));
14262 exports
.default = Popover
;
14263 ListenerMixin_1
.default.mixInto(Popover
);
14268 /***/ (function(module
, exports
, __webpack_require__
) {
14270 Object
.defineProperty(exports
, "__esModule", { value
: true });
14271 var tslib_1
= __webpack_require__(2);
14272 var $ = __webpack_require__(3);
14273 var util_1
= __webpack_require__(4);
14274 var EventRenderer_1
= __webpack_require__(42);
14275 /* Event-rendering methods for the DayGrid class
14276 ----------------------------------------------------------------------------------------------------------------------*/
14277 var DayGridEventRenderer
= /** @class */ (function (_super
) {
14278 tslib_1
.__extends(DayGridEventRenderer
, _super
);
14279 function DayGridEventRenderer(dayGrid
, fillRenderer
) {
14280 var _this
= _super
.call(this, dayGrid
, fillRenderer
) || this;
14281 _this
.dayGrid
= dayGrid
;
14284 DayGridEventRenderer
.prototype.renderBgRanges = function (eventRanges
) {
14285 // don't render timed background events
14286 eventRanges
= $.grep(eventRanges
, function (eventRange
) {
14287 return eventRange
.eventDef
.isAllDay();
14289 _super
.prototype.renderBgRanges
.call(this, eventRanges
);
14291 // Renders the given foreground event segments onto the grid
14292 DayGridEventRenderer
.prototype.renderFgSegs = function (segs
) {
14293 var rowStructs
= this.rowStructs
= this.renderSegRows(segs
);
14294 // append to each row's content skeleton
14295 this.dayGrid
.rowEls
.each(function (i
, rowNode
) {
14296 $(rowNode
).find('.fc-content-skeleton > table').append(rowStructs
[i
].tbodyEl
);
14299 // Unrenders all currently rendered foreground event segments
14300 DayGridEventRenderer
.prototype.unrenderFgSegs = function () {
14301 var rowStructs
= this.rowStructs
|| [];
14303 while ((rowStruct
= rowStructs
.pop())) {
14304 rowStruct
.tbodyEl
.remove();
14306 this.rowStructs
= null;
14308 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
14309 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
14310 // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
14311 DayGridEventRenderer
.prototype.renderSegRows = function (segs
) {
14312 var rowStructs
= [];
14315 segRows
= this.groupSegRows(segs
); // group into nested arrays
14316 // iterate each row of segment groupings
14317 for (row
= 0; row
< segRows
.length
; row
++) {
14318 rowStructs
.push(this.renderSegRow(row
, segRows
[row
]));
14322 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
14323 // the segments. Returns object with a bunch of internal data about how the render was calculated.
14324 // NOTE: modifies rowSegs
14325 DayGridEventRenderer
.prototype.renderSegRow = function (row
, rowSegs
) {
14326 var colCnt
= this.dayGrid
.colCnt
;
14327 var segLevels
= this.buildSegLevels(rowSegs
); // group into sub-arrays of levels
14328 var levelCnt
= Math
.max(1, segLevels
.length
); // ensure at least one level
14329 var tbody
= $('<tbody/>');
14330 var segMatrix
= []; // lookup for which segments are rendered into which level+col cells
14331 var cellMatrix
= []; // lookup for all <td> elements of the level+col matrix
14332 var loneCellMatrix
= []; // lookup for <td> elements that only take up a single column
14340 // populates empty cells from the current column (`col`) to `endCol`
14341 function emptyCellsUntil(endCol
) {
14342 while (col
< endCol
) {
14343 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
14344 td
= (loneCellMatrix
[i
- 1] || [])[col
];
14346 td
.attr('rowspan', parseInt(td
.attr('rowspan') || 1, 10) + 1);
14352 cellMatrix
[i
][col
] = td
;
14353 loneCellMatrix
[i
][col
] = td
;
14357 for (i
= 0; i
< levelCnt
; i
++) {
14358 levelSegs
= segLevels
[i
];
14361 segMatrix
.push([]);
14362 cellMatrix
.push([]);
14363 loneCellMatrix
.push([]);
14364 // levelCnt might be 1 even though there are no actual levels. protect against this.
14365 // this single empty row is useful for styling.
14367 for (j
= 0; j
< levelSegs
.length
; j
++) {
14368 seg
= levelSegs
[j
];
14369 emptyCellsUntil(seg
.leftCol
);
14370 // create a container that occupies or more columns. append the event element.
14371 td
= $('<td class="fc-event-container"/>').append(seg
.el
);
14372 if (seg
.leftCol
!== seg
.rightCol
) {
14373 td
.attr('colspan', seg
.rightCol
- seg
.leftCol
+ 1);
14376 loneCellMatrix
[i
][col
] = td
;
14378 while (col
<= seg
.rightCol
) {
14379 cellMatrix
[i
][col
] = td
;
14380 segMatrix
[i
][col
] = seg
;
14386 emptyCellsUntil(colCnt
); // finish off the row
14387 this.dayGrid
.bookendCells(tr
);
14393 cellMatrix
: cellMatrix
,
14394 segMatrix
: segMatrix
,
14395 segLevels
: segLevels
,
14399 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
14400 // NOTE: modifies segs
14401 DayGridEventRenderer
.prototype.buildSegLevels = function (segs
) {
14406 // Give preference to elements with certain criteria, so they have
14407 // a chance to be closer to the top.
14408 this.sortEventSegs(segs
);
14409 for (i
= 0; i
< segs
.length
; i
++) {
14411 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
14412 for (j
= 0; j
< levels
.length
; j
++) {
14413 if (!isDaySegCollision(seg
, levels
[j
])) {
14417 // `j` now holds the desired subrow index
14419 // create new level array if needed and append segment
14420 (levels
[j
] || (levels
[j
] = [])).push(seg
);
14422 // order segments left-to-right. very important if calendar is RTL
14423 for (j
= 0; j
< levels
.length
; j
++) {
14424 levels
[j
].sort(compareDaySegCols
);
14428 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
14429 DayGridEventRenderer
.prototype.groupSegRows = function (segs
) {
14432 for (i
= 0; i
< this.dayGrid
.rowCnt
; i
++) {
14435 for (i
= 0; i
< segs
.length
; i
++) {
14436 segRows
[segs
[i
].row
].push(segs
[i
]);
14440 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
14441 DayGridEventRenderer
.prototype.computeEventTimeFormat = function () {
14442 return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p"
14444 // Computes a default `displayEventEnd` value if one is not expliclty defined
14445 DayGridEventRenderer
.prototype.computeDisplayEventEnd = function () {
14446 return this.dayGrid
.colCnt
=== 1; // we'll likely have space if there's only one day
14448 // Builds the HTML to be used for the default element for an individual segment
14449 DayGridEventRenderer
.prototype.fgSegHtml = function (seg
, disableResizing
) {
14450 var view
= this.view
;
14451 var eventDef
= seg
.footprint
.eventDef
;
14452 var isAllDay
= seg
.footprint
.componentFootprint
.isAllDay
;
14453 var isDraggable
= view
.isEventDefDraggable(eventDef
);
14454 var isResizableFromStart
= !disableResizing
&& isAllDay
&&
14455 seg
.isStart
&& view
.isEventDefResizableFromStart(eventDef
);
14456 var isResizableFromEnd
= !disableResizing
&& isAllDay
&&
14457 seg
.isEnd
&& view
.isEventDefResizableFromEnd(eventDef
);
14458 var classes
= this.getSegClasses(seg
, isDraggable
, isResizableFromStart
|| isResizableFromEnd
);
14459 var skinCss
= util_1
.cssToStr(this.getSkinCss(eventDef
));
14463 classes
.unshift('fc-day-grid-event', 'fc-h-event');
14464 // Only display a timed events time if it is the starting segment
14466 timeText
= this.getTimeText(seg
.footprint
);
14468 timeHtml
= '<span class="fc-time">' + util_1
.htmlEscape(timeText
) + '</span>';
14472 '<span class="fc-title">' +
14473 (util_1
.htmlEscape(eventDef
.title
|| '') || ' ') + // we always want one line of height
14475 return '<a class="' + classes
.join(' ') + '"' +
14477 ' href="' + util_1
.htmlEscape(eventDef
.url
) + '"' :
14480 ' style="' + skinCss
+ '"' :
14483 '<div class="fc-content">' +
14484 (this.dayGrid
.isRTL
?
14485 titleHtml
+ ' ' + timeHtml
: // put a natural space in between
14486 timeHtml
+ ' ' + titleHtml
//
14489 (isResizableFromStart
?
14490 '<div class="fc-resizer fc-start-resizer" />' :
14492 (isResizableFromEnd
?
14493 '<div class="fc-resizer fc-end-resizer" />' :
14497 return DayGridEventRenderer
;
14498 }(EventRenderer_1
.default));
14499 exports
.default = DayGridEventRenderer
;
14500 // Computes whether two segments' columns collide. They are assumed to be in the same row.
14501 function isDaySegCollision(seg
, otherSegs
) {
14504 for (i
= 0; i
< otherSegs
.length
; i
++) {
14505 otherSeg
= otherSegs
[i
];
14506 if (otherSeg
.leftCol
<= seg
.rightCol
&&
14507 otherSeg
.rightCol
>= seg
.leftCol
) {
14513 // A cmp function for determining the leftmost event
14514 function compareDaySegCols(a
, b
) {
14515 return a
.leftCol
- b
.leftCol
;
14521 /***/ (function(module
, exports
, __webpack_require__
) {
14523 Object
.defineProperty(exports
, "__esModule", { value
: true });
14524 var tslib_1
= __webpack_require__(2);
14525 var $ = __webpack_require__(3);
14526 var HelperRenderer_1
= __webpack_require__(58);
14527 var DayGridHelperRenderer
= /** @class */ (function (_super
) {
14528 tslib_1
.__extends(DayGridHelperRenderer
, _super
);
14529 function DayGridHelperRenderer() {
14530 return _super
!== null && _super
.apply(this, arguments
) || this;
14532 // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null.
14533 DayGridHelperRenderer
.prototype.renderSegs = function (segs
, sourceSeg
) {
14534 var helperNodes
= [];
14536 // TODO: not good to call eventRenderer this way
14537 rowStructs
= this.eventRenderer
.renderSegRows(segs
);
14538 // inject each new event skeleton into each associated row
14539 this.component
.rowEls
.each(function (row
, rowNode
) {
14540 var rowEl
= $(rowNode
); // the .fc-row
14541 var skeletonEl
= $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned
14544 // If there is an original segment, match the top position. Otherwise, put it at the row's top level
14545 if (sourceSeg
&& sourceSeg
.row
=== row
) {
14546 skeletonTop
= sourceSeg
.el
.position().top
;
14549 skeletonTopEl
= rowEl
.find('.fc-content-skeleton tbody');
14550 if (!skeletonTopEl
.length
) {
14551 skeletonTopEl
= rowEl
.find('.fc-content-skeleton table');
14553 skeletonTop
= skeletonTopEl
.position().top
;
14555 skeletonEl
.css('top', skeletonTop
)
14557 .append(rowStructs
[row
].tbodyEl
);
14558 rowEl
.append(skeletonEl
);
14559 helperNodes
.push(skeletonEl
[0]);
14561 return $(helperNodes
); // must return the elements rendered
14563 return DayGridHelperRenderer
;
14564 }(HelperRenderer_1
.default));
14565 exports
.default = DayGridHelperRenderer
;
14570 /***/ (function(module
, exports
, __webpack_require__
) {
14572 Object
.defineProperty(exports
, "__esModule", { value
: true });
14573 var tslib_1
= __webpack_require__(2);
14574 var $ = __webpack_require__(3);
14575 var FillRenderer_1
= __webpack_require__(57);
14576 var DayGridFillRenderer
= /** @class */ (function (_super
) {
14577 tslib_1
.__extends(DayGridFillRenderer
, _super
);
14578 function DayGridFillRenderer() {
14579 var _this
= _super
!== null && _super
.apply(this, arguments
) || this;
14580 _this
.fillSegTag
= 'td'; // override the default tag name
14583 DayGridFillRenderer
.prototype.attachSegEls = function (type
, segs
) {
14588 for (i
= 0; i
< segs
.length
; i
++) {
14590 skeletonEl
= this.renderFillRow(type
, seg
);
14591 this.component
.rowEls
.eq(seg
.row
).append(skeletonEl
);
14592 nodes
.push(skeletonEl
[0]);
14596 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
14597 DayGridFillRenderer
.prototype.renderFillRow = function (type
, seg
) {
14598 var colCnt
= this.component
.colCnt
;
14599 var startCol
= seg
.leftCol
;
14600 var endCol
= seg
.rightCol
+ 1;
14604 if (type
=== 'businessHours') {
14605 className
= 'bgevent';
14608 className
= type
.toLowerCase();
14610 skeletonEl
= $('<div class="fc-' + className
+ '-skeleton">' +
14611 '<table><tr/></table>' +
14613 trEl
= skeletonEl
.find('tr');
14614 if (startCol
> 0) {
14615 trEl
.append('<td colspan="' + startCol
+ '"/>');
14617 trEl
.append(seg
.el
.attr('colspan', endCol
- startCol
));
14618 if (endCol
< colCnt
) {
14619 trEl
.append('<td colspan="' + (colCnt
- endCol
) + '"/>');
14621 this.component
.bookendCells(trEl
);
14624 return DayGridFillRenderer
;
14625 }(FillRenderer_1
.default));
14626 exports
.default = DayGridFillRenderer
;
14631 /***/ (function(module
, exports
, __webpack_require__
) {
14633 Object
.defineProperty(exports
, "__esModule", { value
: true });
14634 var tslib_1
= __webpack_require__(2);
14635 var BasicViewDateProfileGenerator_1
= __webpack_require__(228);
14636 var UnzonedRange_1
= __webpack_require__(5);
14637 var MonthViewDateProfileGenerator
= /** @class */ (function (_super
) {
14638 tslib_1
.__extends(MonthViewDateProfileGenerator
, _super
);
14639 function MonthViewDateProfileGenerator() {
14640 return _super
!== null && _super
.apply(this, arguments
) || this;
14642 // Computes the date range that will be rendered.
14643 MonthViewDateProfileGenerator
.prototype.buildRenderRange = function (currentUnzonedRange
, currentRangeUnit
, isRangeAllDay
) {
14644 var renderUnzonedRange
= _super
.prototype.buildRenderRange
.call(this, currentUnzonedRange
, currentRangeUnit
, isRangeAllDay
);
14645 var start
= this.msToUtcMoment(renderUnzonedRange
.startMs
, isRangeAllDay
);
14646 var end
= this.msToUtcMoment(renderUnzonedRange
.endMs
, isRangeAllDay
);
14649 if (this.opt('fixedWeekCount')) {
14650 rowCnt
= Math
.ceil(// could be partial weeks due to hiddenDays
14651 end
.diff(start
, 'weeks', true) // dontRound=true
14653 end
.add(6 - rowCnt
, 'weeks');
14655 return new UnzonedRange_1
.default(start
, end
);
14657 return MonthViewDateProfileGenerator
;
14658 }(BasicViewDateProfileGenerator_1
.default));
14659 exports
.default = MonthViewDateProfileGenerator
;
14664 /***/ (function(module
, exports
, __webpack_require__
) {
14666 Object
.defineProperty(exports
, "__esModule", { value
: true });
14667 var tslib_1
= __webpack_require__(2);
14668 var util_1
= __webpack_require__(4);
14669 var EventRenderer_1
= __webpack_require__(42);
14670 var ListEventRenderer
= /** @class */ (function (_super
) {
14671 tslib_1
.__extends(ListEventRenderer
, _super
);
14672 function ListEventRenderer() {
14673 return _super
!== null && _super
.apply(this, arguments
) || this;
14675 ListEventRenderer
.prototype.renderFgSegs = function (segs
) {
14676 if (!segs
.length
) {
14677 this.component
.renderEmptyMessage();
14680 this.component
.renderSegList(segs
);
14683 // generates the HTML for a single event row
14684 ListEventRenderer
.prototype.fgSegHtml = function (seg
) {
14685 var view
= this.view
;
14686 var calendar
= view
.calendar
;
14687 var theme
= calendar
.theme
;
14688 var eventFootprint
= seg
.footprint
;
14689 var eventDef
= eventFootprint
.eventDef
;
14690 var componentFootprint
= eventFootprint
.componentFootprint
;
14691 var url
= eventDef
.url
;
14692 var classes
= ['fc-list-item'].concat(this.getClasses(eventDef
));
14693 var bgColor
= this.getBgColor(eventDef
);
14695 if (componentFootprint
.isAllDay
) {
14696 timeHtml
= view
.getAllDayHtml();
14698 else if (view
.isMultiDayRange(componentFootprint
.unzonedRange
)) {
14699 if (seg
.isStart
|| seg
.isEnd
) {
14700 timeHtml
= util_1
.htmlEscape(this._getTimeText(calendar
.msToMoment(seg
.startMs
), calendar
.msToMoment(seg
.endMs
), componentFootprint
.isAllDay
));
14703 timeHtml
= view
.getAllDayHtml();
14707 // Display the normal time text for the *event's* times
14708 timeHtml
= util_1
.htmlEscape(this.getTimeText(eventFootprint
));
14711 classes
.push('fc-has-url');
14713 return '<tr class="' + classes
.join(' ') + '">' +
14714 (this.displayEventTime
?
14715 '<td class="fc-list-item-time ' + theme
.getClass('widgetContent') + '">' +
14719 '<td class="fc-list-item-marker ' + theme
.getClass('widgetContent') + '">' +
14720 '<span class="fc-event-dot"' +
14722 ' style="background-color:' + bgColor
+ '"' :
14726 '<td class="fc-list-item-title ' + theme
.getClass('widgetContent') + '">' +
14727 '<a' + (url
? ' href="' + util_1
.htmlEscape(url
) + '"' : '') + '>' +
14728 util_1
.htmlEscape(eventDef
.title
|| '') +
14734 ListEventRenderer
.prototype.computeEventTimeFormat = function () {
14735 return this.opt('mediumTimeFormat');
14737 return ListEventRenderer
;
14738 }(EventRenderer_1
.default));
14739 exports
.default = ListEventRenderer
;
14744 /***/ (function(module
, exports
, __webpack_require__
) {
14746 Object
.defineProperty(exports
, "__esModule", { value
: true });
14747 var tslib_1
= __webpack_require__(2);
14748 var $ = __webpack_require__(3);
14749 var EventPointing_1
= __webpack_require__(59);
14750 var ListEventPointing
= /** @class */ (function (_super
) {
14751 tslib_1
.__extends(ListEventPointing
, _super
);
14752 function ListEventPointing() {
14753 return _super
!== null && _super
.apply(this, arguments
) || this;
14755 // for events with a url, the whole <tr> should be clickable,
14756 // but it's impossible to wrap with an <a> tag. simulate this.
14757 ListEventPointing
.prototype.handleClick = function (seg
, ev
) {
14759 _super
.prototype.handleClick
.call(this, seg
, ev
); // might prevent the default action
14760 // not clicking on or within an <a> with an href
14761 if (!$(ev
.target
).closest('a[href]').length
) {
14762 url
= seg
.footprint
.eventDef
.url
;
14763 if (url
&& !ev
.isDefaultPrevented()) {
14764 window
.location
.href
= url
; // simulate link click
14768 return ListEventPointing
;
14769 }(EventPointing_1
.default));
14770 exports
.default = ListEventPointing
;
14775 /***/ (function(module
, exports
, __webpack_require__
) {
14777 Object
.defineProperty(exports
, "__esModule", { value
: true });
14778 var EventSourceParser_1
= __webpack_require__(38);
14779 var ArrayEventSource_1
= __webpack_require__(52);
14780 var FuncEventSource_1
= __webpack_require__(215);
14781 var JsonFeedEventSource_1
= __webpack_require__(216);
14782 EventSourceParser_1
.default.registerClass(ArrayEventSource_1
.default);
14783 EventSourceParser_1
.default.registerClass(FuncEventSource_1
.default);
14784 EventSourceParser_1
.default.registerClass(JsonFeedEventSource_1
.default);
14789 /***/ (function(module
, exports
, __webpack_require__
) {
14791 Object
.defineProperty(exports
, "__esModule", { value
: true });
14792 var ThemeRegistry_1
= __webpack_require__(51);
14793 var StandardTheme_1
= __webpack_require__(213);
14794 var JqueryUiTheme_1
= __webpack_require__(214);
14795 var Bootstrap3Theme_1
= __webpack_require__(258);
14796 var Bootstrap4Theme_1
= __webpack_require__(259);
14797 ThemeRegistry_1
.defineThemeSystem('standard', StandardTheme_1
.default);
14798 ThemeRegistry_1
.defineThemeSystem('jquery-ui', JqueryUiTheme_1
.default);
14799 ThemeRegistry_1
.defineThemeSystem('bootstrap3', Bootstrap3Theme_1
.default);
14800 ThemeRegistry_1
.defineThemeSystem('bootstrap4', Bootstrap4Theme_1
.default);
14805 /***/ (function(module
, exports
, __webpack_require__
) {
14807 Object
.defineProperty(exports
, "__esModule", { value
: true });
14808 var tslib_1
= __webpack_require__(2);
14809 var Theme_1
= __webpack_require__(19);
14810 var Bootstrap3Theme
= /** @class */ (function (_super
) {
14811 tslib_1
.__extends(Bootstrap3Theme
, _super
);
14812 function Bootstrap3Theme() {
14813 return _super
!== null && _super
.apply(this, arguments
) || this;
14815 return Bootstrap3Theme
;
14816 }(Theme_1
.default));
14817 exports
.default = Bootstrap3Theme
;
14818 Bootstrap3Theme
.prototype.classes
= {
14819 widget
: 'fc-bootstrap3',
14820 tableGrid
: 'table-bordered',
14821 tableList
: 'table',
14822 tableListHeading
: 'active',
14823 buttonGroup
: 'btn-group',
14824 button
: 'btn btn-default',
14825 stateActive
: 'active',
14826 stateDisabled
: 'disabled',
14827 today
: 'alert alert-info',
14828 popover
: 'panel panel-default',
14829 popoverHeader
: 'panel-heading',
14830 popoverContent
: 'panel-body',
14832 // for left/right border color when border is inset from edges (all-day in agenda view)
14833 // avoid `panel` class b/c don't want margins/radius. only border color.
14834 headerRow
: 'panel-default',
14835 dayRow
: 'panel-default',
14837 listView
: 'panel panel-default'
14839 Bootstrap3Theme
.prototype.baseIconClass
= 'glyphicon';
14840 Bootstrap3Theme
.prototype.iconClasses
= {
14841 close
: 'glyphicon-remove',
14842 prev
: 'glyphicon-chevron-left',
14843 next
: 'glyphicon-chevron-right',
14844 prevYear
: 'glyphicon-backward',
14845 nextYear
: 'glyphicon-forward'
14847 Bootstrap3Theme
.prototype.iconOverrideOption
= 'bootstrapGlyphicons';
14848 Bootstrap3Theme
.prototype.iconOverrideCustomButtonOption
= 'bootstrapGlyphicon';
14849 Bootstrap3Theme
.prototype.iconOverridePrefix
= 'glyphicon-';
14854 /***/ (function(module
, exports
, __webpack_require__
) {
14856 Object
.defineProperty(exports
, "__esModule", { value
: true });
14857 var tslib_1
= __webpack_require__(2);
14858 var Theme_1
= __webpack_require__(19);
14859 var Bootstrap4Theme
= /** @class */ (function (_super
) {
14860 tslib_1
.__extends(Bootstrap4Theme
, _super
);
14861 function Bootstrap4Theme() {
14862 return _super
!== null && _super
.apply(this, arguments
) || this;
14864 return Bootstrap4Theme
;
14865 }(Theme_1
.default));
14866 exports
.default = Bootstrap4Theme
;
14867 Bootstrap4Theme
.prototype.classes
= {
14868 widget
: 'fc-bootstrap4',
14869 tableGrid
: 'table-bordered',
14870 tableList
: 'table',
14871 tableListHeading
: 'table-active',
14872 buttonGroup
: 'btn-group',
14873 button
: 'btn btn-primary',
14874 stateActive
: 'active',
14875 stateDisabled
: 'disabled',
14876 today
: 'alert alert-info',
14877 popover
: 'card card-primary',
14878 popoverHeader
: 'card-header',
14879 popoverContent
: 'card-body',
14881 // for left/right border color when border is inset from edges (all-day in agenda view)
14882 // avoid `table` class b/c don't want margins/padding/structure. only border color.
14883 headerRow
: 'table-bordered',
14884 dayRow
: 'table-bordered',
14886 listView
: 'card card-primary'
14888 Bootstrap4Theme
.prototype.baseIconClass
= 'fa';
14889 Bootstrap4Theme
.prototype.iconClasses
= {
14891 prev
: 'fa-chevron-left',
14892 next
: 'fa-chevron-right',
14893 prevYear
: 'fa-angle-double-left',
14894 nextYear
: 'fa-angle-double-right'
14896 Bootstrap4Theme
.prototype.iconOverrideOption
= 'bootstrapFontAwesome';
14897 Bootstrap4Theme
.prototype.iconOverrideCustomButtonOption
= 'bootstrapFontAwesome';
14898 Bootstrap4Theme
.prototype.iconOverridePrefix
= 'fa-';
14903 /***/ (function(module
, exports
, __webpack_require__
) {
14905 Object
.defineProperty(exports
, "__esModule", { value
: true });
14906 var ViewRegistry_1
= __webpack_require__(22);
14907 var BasicView_1
= __webpack_require__(62);
14908 var MonthView_1
= __webpack_require__(229);
14909 ViewRegistry_1
.defineView('basic', {
14910 'class': BasicView_1
.default
14912 ViewRegistry_1
.defineView('basicDay', {
14914 duration
: { days
: 1 }
14916 ViewRegistry_1
.defineView('basicWeek', {
14918 duration
: { weeks
: 1 }
14920 ViewRegistry_1
.defineView('month', {
14921 'class': MonthView_1
.default,
14922 duration
: { months
: 1 },
14924 fixedWeekCount
: true
14931 /***/ (function(module
, exports
, __webpack_require__
) {
14933 Object
.defineProperty(exports
, "__esModule", { value
: true });
14934 var ViewRegistry_1
= __webpack_require__(22);
14935 var AgendaView_1
= __webpack_require__(226);
14936 ViewRegistry_1
.defineView('agenda', {
14937 'class': AgendaView_1
.default,
14940 slotDuration
: '00:30:00',
14941 slotEventOverlap
: true // a bad name. confused with overlap/constraint system
14944 ViewRegistry_1
.defineView('agendaDay', {
14946 duration
: { days
: 1 }
14948 ViewRegistry_1
.defineView('agendaWeek', {
14950 duration
: { weeks
: 1 }
14956 /***/ (function(module
, exports
, __webpack_require__
) {
14958 Object
.defineProperty(exports
, "__esModule", { value
: true });
14959 var ViewRegistry_1
= __webpack_require__(22);
14960 var ListView_1
= __webpack_require__(230);
14961 ViewRegistry_1
.defineView('list', {
14962 'class': ListView_1
.default,
14963 buttonTextKey
: 'list',
14965 buttonText
: 'list',
14966 listDayFormat
: 'LL',
14967 noEventsMessage
: 'No events to display'
14970 ViewRegistry_1
.defineView('listDay', {
14972 duration
: { days
: 1 },
14974 listDayFormat
: 'dddd' // day-of-week is all we need. full date is probably in header
14977 ViewRegistry_1
.defineView('listWeek', {
14979 duration
: { weeks
: 1 },
14981 listDayFormat
: 'dddd',
14982 listDayAltFormat
: 'LL'
14985 ViewRegistry_1
.defineView('listMonth', {
14987 duration
: { month
: 1 },
14989 listDayAltFormat
: 'dddd' // day-of-week is nice-to-have
14992 ViewRegistry_1
.defineView('listYear', {
14994 duration
: { year
: 1 },
14996 listDayAltFormat
: 'dddd' // day-of-week is nice-to-have
15003 /***/ (function(module
, exports
) {
15005 Object
.defineProperty(exports
, "__esModule", { value
: true });