e24e7290cb987317a9b259fe6a09f7a75ef4228c
[lhc/web/www.git] / www / plugins-dist / organiseur / lib / fullcalendar / fullcalendar.js
1 /*!
2 * FullCalendar v3.10.2
3 * Docs & License: https://fullcalendar.io/
4 * (c) 2019 Adam Shaw
5 */
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"));
13 else
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 = {};
19 /******/
20 /******/ // The require function
21 /******/ function __webpack_require__(moduleId) {
22 /******/
23 /******/ // Check if module is in cache
24 /******/ if(installedModules[moduleId]) {
25 /******/ return installedModules[moduleId].exports;
26 /******/ }
27 /******/ // Create a new module (and put it into the cache)
28 /******/ var module = installedModules[moduleId] = {
29 /******/ i: moduleId,
30 /******/ l: false,
31 /******/ exports: {}
32 /******/ };
33 /******/
34 /******/ // Execute the module function
35 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
36 /******/
37 /******/ // Flag the module as loaded
38 /******/ module.l = true;
39 /******/
40 /******/ // Return the exports of the module
41 /******/ return module.exports;
42 /******/ }
43 /******/
44 /******/
45 /******/ // expose the modules object (__webpack_modules__)
46 /******/ __webpack_require__.m = modules;
47 /******/
48 /******/ // expose the module cache
49 /******/ __webpack_require__.c = installedModules;
50 /******/
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,
57 /******/ get: getter
58 /******/ });
59 /******/ }
60 /******/ };
61 /******/
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;
69 /******/ };
70 /******/
71 /******/ // Object.prototype.hasOwnProperty.call
72 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
73 /******/
74 /******/ // __webpack_public_path__
75 /******/ __webpack_require__.p = "";
76 /******/
77 /******/ // Load entry module and return exports
78 /******/ return __webpack_require__(__webpack_require__.s = 256);
79 /******/ })
80 /************************************************************************/
81 /******/ ([
82 /* 0 */
83 /***/ (function(module, exports) {
84
85 module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
86
87 /***/ }),
88 /* 1 */,
89 /* 2 */
90 /***/ (function(module, exports) {
91
92 /*
93 derived from:
94 https://github.com/Microsoft/tslib/blob/v1.6.0/tslib.js
95
96 only include the helpers we need, to keep down filesize
97 */
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))
102 d[p] = b[p]; };
103 exports.__extends = function (d, b) {
104 extendStatics(d, b);
105 function __() { this.constructor = d; }
106 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
107 };
108
109
110 /***/ }),
111 /* 3 */
112 /***/ (function(module, exports) {
113
114 module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
115
116 /***/ }),
117 /* 4 */
118 /***/ (function(module, exports, __webpack_require__) {
119
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) {
129 rowEls.css({
130 'border-left-width': 1,
131 'margin-left': scrollbarWidths.left - 1
132 });
133 }
134 if (scrollbarWidths.right) {
135 rowEls.css({
136 'border-right-width': 1,
137 'margin-right': scrollbarWidths.right - 1
138 });
139 }
140 }
141 exports.compensateScroll = compensateScroll;
142 // Undoes compensateScroll and restores all borders/margins
143 function uncompensateScroll(rowEls) {
144 rowEls.css({
145 'margin-left': '',
146 'margin-right': '',
147 'border-left-width': '',
148 'border-right-width': ''
149 });
150 }
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');
155 }
156 exports.disableCursor = disableCursor;
157 // Returns the mouse cursor to its original look
158 function enableCursor() {
159 $('body').removeClass('fc-not-allowed');
160 }
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
174 var usedHeight = 0;
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) {
182 flexEls.push(el);
183 flexOffsets.push(naturalOffset);
184 flexHeights.push($(el).height());
185 }
186 else {
187 // this element stretches past recommended height (non-expandable). mark the space as occupied.
188 usedHeight += naturalOffset;
189 }
190 });
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*
196 }
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) { // we check this again because redistribution might have changed things
204 $(el).height(newHeight);
205 }
206 });
207 }
208 exports.distributeHeight = distributeHeight;
209 // Undoes distrubuteHeight, restoring all els to their natural height
210 function undistributeHeight(els) {
211 els.height('');
212 }
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;
223 }
224 });
225 maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
226 els.width(maxInnerWidth);
227 return maxInnerWidth;
228 }
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);
234 var diff;
235 // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
236 both.css({
237 position: 'relative',
238 left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
239 });
240 diff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions
241 both.css({ position: '', left: '' }); // undo hack
242 return diff;
243 }
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'));
253 }).eq(0);
254 return position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent;
255 }
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);
264 return {
265 left: left,
266 right: left + el.outerWidth(),
267 top: top,
268 bottom: top + el.outerHeight()
269 };
270 }
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);
282 return {
283 left: left,
284 right: left + el[0].clientWidth,
285 top: top,
286 bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars
287 };
288 }
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);
299 return {
300 left: left,
301 right: left + el.width(),
302 top: top,
303 bottom: top + el.height()
304 };
305 }
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;
313 var widths;
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') { // is the scrollbar on the left side?
318 widths.left = leftRightWidth;
319 }
320 else {
321 widths.right = leftRightWidth;
322 }
323 return widths;
324 }
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);
331 return width;
332 }
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();
338 }
339 return _isLeftRtlScrollbars;
340 }
341 function computeIsLeftRtlScrollbars() {
342 var el = $('<div><div></div></div>')
343 .css({
344 position: 'absolute',
345 top: -1000,
346 left: 0,
347 border: 0,
348 padding: 0,
349 overflow: 'scroll',
350 direction: 'rtl'
351 })
352 .appendTo('body');
353 var innerEl = el.children();
354 var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar?
355 el.remove();
356 return res;
357 }
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;
362 }
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;
368 }
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;
376 }
377 return ev.pageX;
378 }
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;
386 }
387 return ev.pageY;
388 }
389 exports.getEvY = getEvY;
390 function getEvIsTouch(ev) {
391 return /^touch/.test(ev.type);
392 }
393 exports.getEvIsTouch = getEvIsTouch;
394 function preventSelection(el) {
395 el.addClass('fc-unselectable')
396 .on('selectstart', preventDefault);
397 }
398 exports.preventSelection = preventSelection;
399 function allowSelection(el) {
400 el.removeClass('fc-unselectable')
401 .off('selectstart', preventDefault);
402 }
403 exports.allowSelection = allowSelection;
404 // Stops a mouse/touch event from doing it's native browser action
405 function preventDefault(ev) {
406 ev.preventDefault();
407 }
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) {
413 var res = {
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)
418 };
419 if (res.left < res.right && res.top < res.bottom) {
420 return res;
421 }
422 return false;
423 }
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) {
427 return {
428 left: Math.min(Math.max(point.left, rect.left), rect.right),
429 top: Math.min(Math.max(point.top, rect.top), rect.bottom)
430 };
431 }
432 exports.constrainPoint = constrainPoint;
433 // Returns a point that is the center of the given rectangle
434 function getRectCenter(rect) {
435 return {
436 left: (rect.left + rect.right) / 2,
437 top: (rect.top + rect.bottom) / 2
438 };
439 }
440 exports.getRectCenter = getRectCenter;
441 // Subtracts point2's coordinates from point1's coordinates, returning a delta
442 function diffPoints(point1, point2) {
443 return {
444 left: point1.left - point2.left,
445 top: point1.top - point2.top
446 };
447 }
448 exports.diffPoints = diffPoints;
449 /* Object Ordering by Field
450 ----------------------------------------------------------------------------------------------------------------------*/
451 function parseFieldSpecs(input) {
452 var specs = [];
453 var tokens = [];
454 var i;
455 var token;
456 if (typeof input === 'string') {
457 tokens = input.split(/\s*,\s*/);
458 }
459 else if (typeof input === 'function') {
460 tokens = [input];
461 }
462 else if ($.isArray(input)) {
463 tokens = input;
464 }
465 for (i = 0; i < tokens.length; i++) {
466 token = tokens[i];
467 if (typeof token === 'string') {
468 specs.push(token.charAt(0) === '-' ?
469 { field: token.substring(1), order: -1 } :
470 { field: token, order: 1 });
471 }
472 else if (typeof token === 'function') {
473 specs.push({ func: token });
474 }
475 }
476 return specs;
477 }
478 exports.parseFieldSpecs = parseFieldSpecs;
479 function compareByFieldSpecs(obj1, obj2, fieldSpecs, obj1fallback, obj2fallback) {
480 var i;
481 var cmp;
482 for (i = 0; i < fieldSpecs.length; i++) {
483 cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i], obj1fallback, obj2fallback);
484 if (cmp) {
485 return cmp;
486 }
487 }
488 return 0;
489 }
490 exports.compareByFieldSpecs = compareByFieldSpecs;
491 function compareByFieldSpec(obj1, obj2, fieldSpec, obj1fallback, obj2fallback) {
492 if (fieldSpec.func) {
493 return fieldSpec.func(obj1, obj2);
494 }
495 var val1 = obj1[fieldSpec.field];
496 var val2 = obj2[fieldSpec.field];
497 if (val1 == null && obj1fallback) {
498 val1 = obj1fallback[fieldSpec.field];
499 }
500 if (val2 == null && obj2fallback) {
501 val2 = obj2fallback[fieldSpec.field];
502 }
503 return flexibleCompare(val1, val2) * (fieldSpec.order || 1);
504 }
505 exports.compareByFieldSpec = compareByFieldSpec;
506 function flexibleCompare(a, b) {
507 if (!a && !b) {
508 return 0;
509 }
510 if (b == null) {
511 return -1;
512 }
513 if (a == null) {
514 return 1;
515 }
516 if ($.type(a) === 'string' || $.type(b) === 'string') {
517 return String(a).localeCompare(String(b));
518 }
519 return a - b;
520 }
521 exports.flexibleCompare = flexibleCompare;
522 /* Date Utilities
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
532 });
533 }
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')
539 });
540 }
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
545 unit);
546 }
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) {
552 var i;
553 var unit;
554 var val;
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)) {
559 break;
560 }
561 }
562 return unit; // will be "milliseconds" if nothing else matches
563 }
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) {
570 unit = 'day';
571 }
572 return unit;
573 }
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) {
580 if (end != null) { // given start, end
581 return end.diff(start, unit, true);
582 }
583 else if (moment.isDuration(start)) { // given duration
584 return start.as(unit);
585 }
586 else { // given { start, end } range object
587 return start.end.diff(start.start, unit, true);
588 }
589 }
590 // Intelligently divides a range (specified by a start/end params) by a duration
591 function divideRangeByDuration(start, end, dur) {
592 var months;
593 if (durationHasTime(dur)) {
594 return (end - start) / dur;
595 }
596 months = dur.asMonths();
597 if (Math.abs(months) >= 1 && isInt(months)) {
598 return end.diff(start, 'months', true) / months;
599 }
600 return end.diff(start, 'days', true) / dur.asDays();
601 }
602 exports.divideRangeByDuration = divideRangeByDuration;
603 // Intelligently divides one duration by another
604 function divideDurationByDuration(dur1, dur2) {
605 var months1;
606 var months2;
607 if (durationHasTime(dur1) || durationHasTime(dur2)) {
608 return dur1 / dur2;
609 }
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;
615 }
616 return dur1.asDays() / dur2.asDays();
617 }
618 exports.divideDurationByDuration = divideDurationByDuration;
619 // Intelligently multiplies a duration by a number
620 function multiplyDuration(dur, n) {
621 var months;
622 if (durationHasTime(dur)) {
623 return moment.duration(dur * n);
624 }
625 months = dur.asMonths();
626 if (Math.abs(months) >= 1 && isInt(months)) {
627 return moment.duration({ months: months * n });
628 }
629 return moment.duration({ days: dur.asDays() * n });
630 }
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());
635 }
636 exports.durationHasTime = durationHasTime;
637 function isNativeDate(input) {
638 return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;
639 }
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);
645 }
646 exports.isTimeString = isTimeString;
647 /* Logging and Debug
648 ----------------------------------------------------------------------------------------------------------------------*/
649 function log() {
650 var args = [];
651 for (var _i = 0; _i < arguments.length; _i++) {
652 args[_i] = arguments[_i];
653 }
654 var console = window.console;
655 if (console && console.log) {
656 return console.log.apply(console, args);
657 }
658 }
659 exports.log = log;
660 function warn() {
661 var args = [];
662 for (var _i = 0; _i < arguments.length; _i++) {
663 args[_i] = arguments[_i];
664 }
665 var console = window.console;
666 if (console && console.warn) {
667 return console.warn.apply(console, args);
668 }
669 else {
670 return log.apply(null, args);
671 }
672 }
673 exports.warn = warn;
674 /* General Utilities
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) {
680 var dest = {};
681 var i;
682 var name;
683 var complexObjs;
684 var j;
685 var val;
686 var props;
687 if (complexProps) {
688 for (i = 0; i < complexProps.length; i++) {
689 name = complexProps[i];
690 complexObjs = [];
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);
696 }
697 else if (val !== undefined) {
698 dest[name] = val; // if there were no objects, this value will be used
699 break;
700 }
701 }
702 // if the trailing values were objects, use the merged value
703 if (complexObjs.length) {
704 dest[name] = mergeProps(complexObjs);
705 }
706 }
707 }
708 // copy values into the destination, going from last to first
709 for (i = propObjs.length - 1; i >= 0; i--) {
710 props = propObjs[i];
711 for (name in props) {
712 if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
713 dest[name] = props[name];
714 }
715 }
716 }
717 return dest;
718 }
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];
724 }
725 }
726 }
727 exports.copyOwnProps = copyOwnProps;
728 function hasOwnProp(obj, name) {
729 return hasOwnPropMethod.call(obj, name);
730 }
731 exports.hasOwnProp = hasOwnProp;
732 function applyAll(functions, thisObj, args) {
733 if ($.isFunction(functions)) {
734 functions = [functions];
735 }
736 if (functions) {
737 var i = void 0;
738 var ret = void 0;
739 for (i = 0; i < functions.length; i++) {
740 ret = functions[i].apply(thisObj, args) || ret;
741 }
742 return ret;
743 }
744 }
745 exports.applyAll = applyAll;
746 function removeMatching(array, testFunc) {
747 var removeCnt = 0;
748 var i = 0;
749 while (i < array.length) {
750 if (testFunc(array[i])) { // truthy value means *remove*
751 array.splice(i, 1);
752 removeCnt++;
753 }
754 else {
755 i++;
756 }
757 }
758 return removeCnt;
759 }
760 exports.removeMatching = removeMatching;
761 function removeExact(array, exactVal) {
762 var removeCnt = 0;
763 var i = 0;
764 while (i < array.length) {
765 if (array[i] === exactVal) {
766 array.splice(i, 1);
767 removeCnt++;
768 }
769 else {
770 i++;
771 }
772 }
773 return removeCnt;
774 }
775 exports.removeExact = removeExact;
776 function isArraysEqual(a0, a1) {
777 var len = a0.length;
778 var i;
779 if (len == null || len !== a1.length) { // not array? or not same length?
780 return false;
781 }
782 for (i = 0; i < len; i++) {
783 if (a0[i] !== a1[i]) {
784 return false;
785 }
786 }
787 return true;
788 }
789 exports.isArraysEqual = isArraysEqual;
790 function firstDefined() {
791 var args = [];
792 for (var _i = 0; _i < arguments.length; _i++) {
793 args[_i] = arguments[_i];
794 }
795 for (var i = 0; i < args.length; i++) {
796 if (args[i] !== undefined) {
797 return args[i];
798 }
799 }
800 }
801 exports.firstDefined = firstDefined;
802 function htmlEscape(s) {
803 return (s + '').replace(/&/g, '&amp;')
804 .replace(/</g, '&lt;')
805 .replace(/>/g, '&gt;')
806 .replace(/'/g, '&#039;')
807 .replace(/"/g, '&quot;')
808 .replace(/\n/g, '<br>');
809 }
810 exports.htmlEscape = htmlEscape;
811 function stripHtmlEntities(text) {
812 return text.replace(/&.*?;/g, '');
813 }
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) {
818 var statements = [];
819 $.each(cssProps, function (name, val) {
820 if (val != null) {
821 statements.push(name + ':' + val);
822 }
823 });
824 return statements.join(';');
825 }
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) {
830 var parts = [];
831 $.each(attrs, function (name, val) {
832 if (val != null) {
833 parts.push(name + '="' + htmlEscape(val) + '"');
834 }
835 });
836 return parts.join(' ');
837 }
838 exports.attrsToStr = attrsToStr;
839 function capitaliseFirstLetter(str) {
840 return str.charAt(0).toUpperCase() + str.slice(1);
841 }
842 exports.capitaliseFirstLetter = capitaliseFirstLetter;
843 function compareNumbers(a, b) {
844 return a - b;
845 }
846 exports.compareNumbers = compareNumbers;
847 function isInt(n) {
848 return n % 1 === 0;
849 }
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];
856 return function () {
857 return method.apply(obj, arguments);
858 };
859 }
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; }
868 var timeout;
869 var args;
870 var context;
871 var timestamp;
872 var result;
873 var later = function () {
874 var last = +new Date() - timestamp;
875 if (last < wait) {
876 timeout = setTimeout(later, wait - last);
877 }
878 else {
879 timeout = null;
880 if (!immediate) {
881 result = func.apply(context, args);
882 context = args = null;
883 }
884 }
885 };
886 return function () {
887 context = this;
888 args = arguments;
889 timestamp = +new Date();
890 var callNow = immediate && !timeout;
891 if (!timeout) {
892 timeout = setTimeout(later, wait);
893 }
894 if (callNow) {
895 result = func.apply(context, args);
896 context = args = null;
897 }
898 return result;
899 };
900 }
901 exports.debounce = debounce;
902
903
904 /***/ }),
905 /* 5 */
906 /***/ (function(module, exports, __webpack_require__) {
907
908 Object.defineProperty(exports, "__esModule", { value: true });
909 var moment = __webpack_require__(0);
910 var moment_ext_1 = __webpack_require__(11);
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.
915 this.isStart = true;
916 this.isEnd = true;
917 if (moment.isMoment(startInput)) {
918 startInput = startInput.clone().stripZone();
919 }
920 if (moment.isMoment(endInput)) {
921 endInput = endInput.clone().stripZone();
922 }
923 if (startInput) {
924 this.startMs = startInput.valueOf();
925 }
926 if (endInput) {
927 this.endMs = endInput.valueOf();
928 }
929 }
930 /*
931 SIDEEFFECT: will mutate eventRanges.
932 Will return a new array result.
933 Only works for non-open-ended ranges.
934 */
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
938 var i;
939 var dateRange;
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) { // compare millisecond time (skip any ambig logic)
946 invertedRanges.push(new UnzonedRange(startMs, dateRange.startMs));
947 }
948 if (dateRange.endMs > startMs) {
949 startMs = dateRange.endMs;
950 }
951 }
952 // add the span of time after the last event (if there is any)
953 if (startMs < constraintRange.endMs) { // compare millisecond time (skip any ambig logic)
954 invertedRanges.push(new UnzonedRange(startMs, constraintRange.endMs));
955 }
956 return invertedRanges;
957 };
958 UnzonedRange.prototype.intersect = function (otherRange) {
959 var startMs = this.startMs;
960 var endMs = this.endMs;
961 var newRange = null;
962 if (otherRange.startMs != null) {
963 if (startMs == null) {
964 startMs = otherRange.startMs;
965 }
966 else {
967 startMs = Math.max(startMs, otherRange.startMs);
968 }
969 }
970 if (otherRange.endMs != null) {
971 if (endMs == null) {
972 endMs = otherRange.endMs;
973 }
974 else {
975 endMs = Math.min(endMs, otherRange.endMs);
976 }
977 }
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;
982 }
983 return newRange;
984 };
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);
988 };
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));
992 };
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);
998 };
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) {
1006 ms = this.startMs;
1007 }
1008 if (this.endMs != null && ms >= this.endMs) {
1009 ms = this.endMs - 1;
1010 }
1011 return ms;
1012 };
1013 UnzonedRange.prototype.equals = function (otherRange) {
1014 return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs;
1015 };
1016 UnzonedRange.prototype.clone = function () {
1017 var range = new UnzonedRange(this.startMs, this.endMs);
1018 range.isStart = this.isStart;
1019 range.isEnd = this.isEnd;
1020 return range;
1021 };
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();
1028 }
1029 return null;
1030 };
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();
1037 }
1038 return null;
1039 };
1040 UnzonedRange.prototype.as = function (unit) {
1041 return moment.utc(this.endMs).diff(moment.utc(this.startMs), unit, true);
1042 };
1043 return UnzonedRange;
1044 }());
1045 exports.default = UnzonedRange;
1046 /*
1047 Only works for non-open-ended ranges.
1048 */
1049 function compareUnzonedRanges(range1, range2) {
1050 return range1.startMs - range2.startMs; // earlier ranges go first
1051 }
1052
1053
1054 /***/ }),
1055 /* 6 */
1056 /***/ (function(module, exports, __webpack_require__) {
1057
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__(52);
1062 var Class_1 = __webpack_require__(35);
1063 var EventDefParser_1 = __webpack_require__(36);
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++);
1073 return _this;
1074 }
1075 /*
1076 rawInput can be any data type!
1077 */
1078 EventSource.parse = function (rawInput, calendar) {
1079 var source = new this(calendar);
1080 if (typeof rawInput === 'object') {
1081 if (source.applyProps(rawInput)) {
1082 return source;
1083 }
1084 }
1085 return false;
1086 };
1087 EventSource.normalizeId = function (id) {
1088 if (id) {
1089 return String(id);
1090 }
1091 return null;
1092 };
1093 EventSource.prototype.fetch = function (start, end, timezone) {
1094 // subclasses must implement. must return a promise.
1095 };
1096 EventSource.prototype.removeEventDefsById = function (eventDefId) {
1097 // optional for subclasses to implement
1098 };
1099 EventSource.prototype.removeAllEventDefs = function () {
1100 // optional for subclasses to implement
1101 };
1102 /*
1103 For compairing/matching
1104 */
1105 EventSource.prototype.getPrimitive = function (otherSource) {
1106 // subclasses must implement
1107 };
1108 EventSource.prototype.parseEventDefs = function (rawEventDefs) {
1109 var i;
1110 var eventDef;
1111 var eventDefs = [];
1112 for (i = 0; i < rawEventDefs.length; i++) {
1113 eventDef = this.parseEventDef(rawEventDefs[i]);
1114 if (eventDef) {
1115 eventDefs.push(eventDef);
1116 }
1117 }
1118 return eventDefs;
1119 };
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);
1125 }
1126 if (sourceTransform) {
1127 rawInput = sourceTransform(rawInput, this.calendar);
1128 }
1129 return EventDefParser_1.default.parse(rawInput, this);
1130 };
1131 EventSource.prototype.applyManualStandardProps = function (rawProps) {
1132 if (rawProps.id != null) {
1133 this.id = EventSource.normalizeId(rawProps.id);
1134 }
1135 // TODO: converge with EventDef
1136 if ($.isArray(rawProps.className)) {
1137 this.className = rawProps.className;
1138 }
1139 else if (typeof rawProps.className === 'string') {
1140 this.className = rawProps.className.split(/\s+/);
1141 }
1142 return true;
1143 };
1144 EventSource.uuid = 0;
1145 EventSource.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps;
1146 EventSource.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps;
1147 return EventSource;
1148 }(Class_1.default));
1149 exports.default = EventSource;
1150 ParsableModelMixin_1.default.mixInto(EventSource);
1151 // Parsing
1152 // ---------------------------------------------------------------------------------------------------------------------
1153 EventSource.defineStandardProps({
1154 // manually process...
1155 id: false,
1156 className: false,
1157 // automatically transfer...
1158 color: true,
1159 backgroundColor: true,
1160 borderColor: true,
1161 textColor: true,
1162 editable: true,
1163 startEditable: true,
1164 durationEditable: true,
1165 rendering: true,
1166 overlap: true,
1167 constraint: true,
1168 allDayDefault: true,
1169 eventDataTransform: true
1170 });
1171
1172
1173 /***/ }),
1174 /* 7 */
1175 /***/ (function(module, exports, __webpack_require__) {
1176
1177 /*
1178 Utility methods for easily listening to events on another object,
1179 and more importantly, easily unlistening from them.
1180
1181 USAGE:
1182 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin'
1183 in class:
1184 listenTo: ListenerInterface['listenTo']
1185 stopListeningTo: ListenerInterface['stopListeningTo']
1186 after class:
1187 ListenerMixin.mixInto(TheClass)
1188 */
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__(15);
1193 var guid = 0;
1194 var ListenerMixin = /** @class */ (function (_super) {
1195 tslib_1.__extends(ListenerMixin, _super);
1196 function ListenerMixin() {
1197 return _super !== null && _super.apply(this, arguments) || this;
1198 }
1199 /*
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.
1202 Can be called:
1203 .listenTo(other, eventName, callback)
1204 OR
1205 .listenTo(other, {
1206 eventName1: callback1,
1207 eventName2: callback2
1208 })
1209 */
1210 ListenerMixin.prototype.listenTo = function (other, arg, callback) {
1211 if (typeof arg === 'object') { // given dictionary of callbacks
1212 for (var eventName in arg) {
1213 if (arg.hasOwnProperty(eventName)) {
1214 this.listenTo(other, eventName, arg[eventName]);
1215 }
1216 }
1217 }
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
1223 );
1224 }
1225 };
1226 /*
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`.
1229 */
1230 ListenerMixin.prototype.stopListeningTo = function (other, eventName) {
1231 other.off((eventName || '') + '.' + this.getListenerNamespace());
1232 };
1233 /*
1234 Returns a string, unique to this object, to be used for event namespacing
1235 */
1236 ListenerMixin.prototype.getListenerNamespace = function () {
1237 if (this.listenerId == null) {
1238 this.listenerId = guid++;
1239 }
1240 return '_listener' + this.listenerId;
1241 };
1242 return ListenerMixin;
1243 }(Mixin_1.default));
1244 exports.default = ListenerMixin;
1245
1246
1247 /***/ }),
1248 /* 8 */,
1249 /* 9 */
1250 /***/ (function(module, exports, __webpack_require__) {
1251
1252 Object.defineProperty(exports, "__esModule", { value: true });
1253 var tslib_1 = __webpack_require__(2);
1254 var EventDef_1 = __webpack_require__(37);
1255 var EventInstance_1 = __webpack_require__(53);
1256 var EventDateProfile_1 = __webpack_require__(16);
1257 var SingleEventDef = /** @class */ (function (_super) {
1258 tslib_1.__extends(SingleEventDef, _super);
1259 function SingleEventDef() {
1260 return _super !== null && _super.apply(this, arguments) || this;
1261 }
1262 /*
1263 Will receive start/end params, but will be ignored.
1264 */
1265 SingleEventDef.prototype.buildInstances = function () {
1266 return [this.buildInstance()];
1267 };
1268 SingleEventDef.prototype.buildInstance = function () {
1269 return new EventInstance_1.default(this, // definition
1270 this.dateProfile);
1271 };
1272 SingleEventDef.prototype.isAllDay = function () {
1273 return this.dateProfile.isAllDay();
1274 };
1275 SingleEventDef.prototype.clone = function () {
1276 var def = _super.prototype.clone.call(this);
1277 def.dateProfile = this.dateProfile;
1278 return def;
1279 };
1280 SingleEventDef.prototype.rezone = function () {
1281 var calendar = this.source.calendar;
1282 var dateProfile = this.dateProfile;
1283 this.dateProfile = new EventDateProfile_1.default(calendar.moment(dateProfile.start), dateProfile.end ? calendar.moment(dateProfile.end) : null, calendar);
1284 };
1285 /*
1286 NOTE: if super-method fails, should still attempt to apply
1287 */
1288 SingleEventDef.prototype.applyManualStandardProps = function (rawProps) {
1289 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
1290 var dateProfile = EventDateProfile_1.default.parse(rawProps, this.source); // returns null on failure
1291 if (dateProfile) {
1292 this.dateProfile = dateProfile;
1293 // make sure `date` shows up in the legacy event objects as-is
1294 if (rawProps.date != null) {
1295 this.miscProps.date = rawProps.date;
1296 }
1297 return superSuccess;
1298 }
1299 else {
1300 return false;
1301 }
1302 };
1303 return SingleEventDef;
1304 }(EventDef_1.default));
1305 exports.default = SingleEventDef;
1306 // Parsing
1307 // ---------------------------------------------------------------------------------------------------------------------
1308 SingleEventDef.defineStandardProps({
1309 start: false,
1310 date: false,
1311 end: false,
1312 allDay: false
1313 });
1314
1315
1316 /***/ }),
1317 /* 10 */,
1318 /* 11 */
1319 /***/ (function(module, exports, __webpack_require__) {
1320
1321 Object.defineProperty(exports, "__esModule", { value: true });
1322 var moment = __webpack_require__(0);
1323 var $ = __webpack_require__(3);
1324 var util_1 = __webpack_require__(4);
1325 var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
1326 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+)?)?)?)?)?$/;
1327 var newMomentProto = moment.fn; // where we will attach our new methods
1328 exports.newMomentProto = newMomentProto;
1329 var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods
1330 exports.oldMomentProto = oldMomentProto;
1331 // tell momentjs to transfer these properties upon clone
1332 var momentProperties = moment.momentProperties;
1333 momentProperties.push('_fullCalendar');
1334 momentProperties.push('_ambigTime');
1335 momentProperties.push('_ambigZone');
1336 /*
1337 Call this if you want Moment's original format method to be used
1338 */
1339 function oldMomentFormat(mom, formatStr) {
1340 return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js
1341 }
1342 exports.oldMomentFormat = oldMomentFormat;
1343 // Creating
1344 // -------------------------------------------------------------------------------------------------
1345 // Creates a new moment, similar to the vanilla moment(...) constructor, but with
1346 // extra features (ambiguous time, enhanced formatting). When given an existing moment,
1347 // it will function as a clone (and retain the zone of the moment). Anything else will
1348 // result in a moment in the local zone.
1349 var momentExt = function () {
1350 return makeMoment(arguments);
1351 };
1352 exports.default = momentExt;
1353 // Sames as momentExt, but forces the resulting moment to be in the UTC timezone.
1354 momentExt.utc = function () {
1355 var mom = makeMoment(arguments, true);
1356 // Force it into UTC because makeMoment doesn't guarantee it
1357 // (if given a pre-existing moment for example)
1358 if (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone
1359 mom.utc();
1360 }
1361 return mom;
1362 };
1363 // Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved.
1364 // ISO8601 strings with no timezone offset will become ambiguously zoned.
1365 momentExt.parseZone = function () {
1366 return makeMoment(arguments, true, true);
1367 };
1368 // Builds an enhanced moment from args. When given an existing moment, it clones. When given a
1369 // native Date, or called with no arguments (the current time), the resulting moment will be local.
1370 // Anything else needs to be "parsed" (a string or an array), and will be affected by:
1371 // parseAsUTC - if there is no zone information, should we parse the input in UTC?
1372 // parseZone - if there is zone information, should we force the zone of the moment?
1373 function makeMoment(args, parseAsUTC, parseZone) {
1374 if (parseAsUTC === void 0) { parseAsUTC = false; }
1375 if (parseZone === void 0) { parseZone = false; }
1376 var input = args[0];
1377 var isSingleString = args.length === 1 && typeof input === 'string';
1378 var isAmbigTime;
1379 var isAmbigZone;
1380 var ambigMatch;
1381 var mom;
1382 if (moment.isMoment(input) || util_1.isNativeDate(input) || input === undefined) {
1383 mom = moment.apply(null, args);
1384 }
1385 else { // "parsing" is required
1386 isAmbigTime = false;
1387 isAmbigZone = false;
1388 if (isSingleString) {
1389 if (ambigDateOfMonthRegex.test(input)) {
1390 // accept strings like '2014-05', but convert to the first of the month
1391 input += '-01';
1392 args = [input]; // for when we pass it on to moment's constructor
1393 isAmbigTime = true;
1394 isAmbigZone = true;
1395 }
1396 else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {
1397 isAmbigTime = !ambigMatch[5]; // no time part?
1398 isAmbigZone = true;
1399 }
1400 }
1401 else if ($.isArray(input)) {
1402 // arrays have no timezone information, so assume ambiguous zone
1403 isAmbigZone = true;
1404 }
1405 // otherwise, probably a string with a format
1406 if (parseAsUTC || isAmbigTime) {
1407 mom = moment.utc.apply(moment, args);
1408 }
1409 else {
1410 mom = moment.apply(null, args);
1411 }
1412 if (isAmbigTime) {
1413 mom._ambigTime = true;
1414 mom._ambigZone = true; // ambiguous time always means ambiguous zone
1415 }
1416 else if (parseZone) { // let's record the inputted zone somehow
1417 if (isAmbigZone) {
1418 mom._ambigZone = true;
1419 }
1420 else if (isSingleString) {
1421 mom.utcOffset(input); // if not a valid zone, will assign UTC
1422 }
1423 }
1424 }
1425 mom._fullCalendar = true; // flag for extended functionality
1426 return mom;
1427 }
1428 // Week Number
1429 // -------------------------------------------------------------------------------------------------
1430 // Returns the week number, considering the locale's custom week number calcuation
1431 // `weeks` is an alias for `week`
1432 newMomentProto.week = newMomentProto.weeks = function (input) {
1433 var weekCalc = this._locale._fullCalendar_weekCalc;
1434 if (input == null && typeof weekCalc === 'function') { // custom function only works for getter
1435 return weekCalc(this);
1436 }
1437 else if (weekCalc === 'ISO') {
1438 return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter
1439 }
1440 return oldMomentProto.week.apply(this, arguments); // local getter/setter
1441 };
1442 // Time-of-day
1443 // -------------------------------------------------------------------------------------------------
1444 // GETTER
1445 // Returns a Duration with the hours/minutes/seconds/ms values of the moment.
1446 // If the moment has an ambiguous time, a duration of 00:00 will be returned.
1447 //
1448 // SETTER
1449 // You can supply a Duration, a Moment, or a Duration-like argument.
1450 // When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.
1451 newMomentProto.time = function (time) {
1452 // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.
1453 // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.
1454 if (!this._fullCalendar) {
1455 return oldMomentProto.time.apply(this, arguments);
1456 }
1457 if (time == null) { // getter
1458 return moment.duration({
1459 hours: this.hours(),
1460 minutes: this.minutes(),
1461 seconds: this.seconds(),
1462 milliseconds: this.milliseconds()
1463 });
1464 }
1465 else { // setter
1466 this._ambigTime = false; // mark that the moment now has a time
1467 if (!moment.isDuration(time) && !moment.isMoment(time)) {
1468 time = moment.duration(time);
1469 }
1470 // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).
1471 // Only for Duration times, not Moment times.
1472 var dayHours = 0;
1473 if (moment.isDuration(time)) {
1474 dayHours = Math.floor(time.asDays()) * 24;
1475 }
1476 // We need to set the individual fields.
1477 // Can't use startOf('day') then add duration. In case of DST at start of day.
1478 return this.hours(dayHours + time.hours())
1479 .minutes(time.minutes())
1480 .seconds(time.seconds())
1481 .milliseconds(time.milliseconds());
1482 }
1483 };
1484 // Converts the moment to UTC, stripping out its time-of-day and timezone offset,
1485 // but preserving its YMD. A moment with a stripped time will display no time
1486 // nor timezone offset when .format() is called.
1487 newMomentProto.stripTime = function () {
1488 if (!this._ambigTime) {
1489 this.utc(true); // keepLocalTime=true (for keeping *date* value)
1490 // set time to zero
1491 this.set({
1492 hours: 0,
1493 minutes: 0,
1494 seconds: 0,
1495 ms: 0
1496 });
1497 // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1498 // which clears all ambig flags.
1499 this._ambigTime = true;
1500 this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset
1501 }
1502 return this; // for chaining
1503 };
1504 // Returns if the moment has a non-ambiguous time (boolean)
1505 newMomentProto.hasTime = function () {
1506 return !this._ambigTime;
1507 };
1508 // Timezone
1509 // -------------------------------------------------------------------------------------------------
1510 // Converts the moment to UTC, stripping out its timezone offset, but preserving its
1511 // YMD and time-of-day. A moment with a stripped timezone offset will display no
1512 // timezone offset when .format() is called.
1513 newMomentProto.stripZone = function () {
1514 var wasAmbigTime;
1515 if (!this._ambigZone) {
1516 wasAmbigTime = this._ambigTime;
1517 this.utc(true); // keepLocalTime=true (for keeping date and time values)
1518 // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore
1519 this._ambigTime = wasAmbigTime || false;
1520 // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1521 // which clears the ambig flags.
1522 this._ambigZone = true;
1523 }
1524 return this; // for chaining
1525 };
1526 // Returns of the moment has a non-ambiguous timezone offset (boolean)
1527 newMomentProto.hasZone = function () {
1528 return !this._ambigZone;
1529 };
1530 // implicitly marks a zone
1531 newMomentProto.local = function (keepLocalTime) {
1532 // for when converting from ambiguously-zoned to local,
1533 // keep the time values when converting from UTC -> local
1534 oldMomentProto.local.call(this, this._ambigZone || keepLocalTime);
1535 // ensure non-ambiguous
1536 // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals
1537 this._ambigTime = false;
1538 this._ambigZone = false;
1539 return this; // for chaining
1540 };
1541 // implicitly marks a zone
1542 newMomentProto.utc = function (keepLocalTime) {
1543 oldMomentProto.utc.call(this, keepLocalTime);
1544 // ensure non-ambiguous
1545 // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals
1546 this._ambigTime = false;
1547 this._ambigZone = false;
1548 return this;
1549 };
1550 // implicitly marks a zone (will probably get called upon .utc() and .local())
1551 newMomentProto.utcOffset = function (tzo) {
1552 if (tzo != null) { // setter
1553 // these assignments needs to happen before the original zone method is called.
1554 // I forget why, something to do with a browser crash.
1555 this._ambigTime = false;
1556 this._ambigZone = false;
1557 }
1558 return oldMomentProto.utcOffset.apply(this, arguments);
1559 };
1560
1561
1562 /***/ }),
1563 /* 12 */
1564 /***/ (function(module, exports) {
1565
1566 Object.defineProperty(exports, "__esModule", { value: true });
1567 /*
1568 Meant to be immutable
1569 */
1570 var ComponentFootprint = /** @class */ (function () {
1571 function ComponentFootprint(unzonedRange, isAllDay) {
1572 this.isAllDay = false; // component can choose to ignore this
1573 this.unzonedRange = unzonedRange;
1574 this.isAllDay = isAllDay;
1575 }
1576 /*
1577 Only works for non-open-ended ranges.
1578 */
1579 ComponentFootprint.prototype.toLegacy = function (calendar) {
1580 return {
1581 start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay),
1582 end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay)
1583 };
1584 };
1585 return ComponentFootprint;
1586 }());
1587 exports.default = ComponentFootprint;
1588
1589
1590 /***/ }),
1591 /* 13 */
1592 /***/ (function(module, exports, __webpack_require__) {
1593
1594 /*
1595 USAGE:
1596 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
1597 in class:
1598 on: EmitterInterface['on']
1599 one: EmitterInterface['one']
1600 off: EmitterInterface['off']
1601 trigger: EmitterInterface['trigger']
1602 triggerWith: EmitterInterface['triggerWith']
1603 hasHandlers: EmitterInterface['hasHandlers']
1604 after class:
1605 EmitterMixin.mixInto(TheClass)
1606 */
1607 Object.defineProperty(exports, "__esModule", { value: true });
1608 var tslib_1 = __webpack_require__(2);
1609 var $ = __webpack_require__(3);
1610 var Mixin_1 = __webpack_require__(15);
1611 var EmitterMixin = /** @class */ (function (_super) {
1612 tslib_1.__extends(EmitterMixin, _super);
1613 function EmitterMixin() {
1614 return _super !== null && _super.apply(this, arguments) || this;
1615 }
1616 // jQuery-ification via $(this) allows a non-DOM object to have
1617 // the same event handling capabilities (including namespaces).
1618 EmitterMixin.prototype.on = function (types, handler) {
1619 $(this).on(types, this._prepareIntercept(handler));
1620 return this; // for chaining
1621 };
1622 EmitterMixin.prototype.one = function (types, handler) {
1623 $(this).one(types, this._prepareIntercept(handler));
1624 return this; // for chaining
1625 };
1626 EmitterMixin.prototype._prepareIntercept = function (handler) {
1627 // handlers are always called with an "event" object as their first param.
1628 // sneak the `this` context and arguments into the extra parameter object
1629 // and forward them on to the original handler.
1630 var intercept = function (ev, extra) {
1631 return handler.apply(extra.context || this, extra.args || []);
1632 };
1633 // mimick jQuery's internal "proxy" system (risky, I know)
1634 // causing all functions with the same .guid to appear to be the same.
1635 // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448
1636 // this is needed for calling .off with the original non-intercept handler.
1637 if (!handler.guid) {
1638 handler.guid = $.guid++;
1639 }
1640 intercept.guid = handler.guid;
1641 return intercept;
1642 };
1643 EmitterMixin.prototype.off = function (types, handler) {
1644 $(this).off(types, handler);
1645 return this; // for chaining
1646 };
1647 EmitterMixin.prototype.trigger = function (types) {
1648 var args = [];
1649 for (var _i = 1; _i < arguments.length; _i++) {
1650 args[_i - 1] = arguments[_i];
1651 }
1652 // pass in "extra" info to the intercept
1653 $(this).triggerHandler(types, { args: args });
1654 return this; // for chaining
1655 };
1656 EmitterMixin.prototype.triggerWith = function (types, context, args) {
1657 // `triggerHandler` is less reliant on the DOM compared to `trigger`.
1658 // pass in "extra" info to the intercept.
1659 $(this).triggerHandler(types, { context: context, args: args });
1660 return this; // for chaining
1661 };
1662 EmitterMixin.prototype.hasHandlers = function (type) {
1663 var hash = $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/
1664 return hash && hash[type] && hash[type].length > 0;
1665 };
1666 return EmitterMixin;
1667 }(Mixin_1.default));
1668 exports.default = EmitterMixin;
1669
1670
1671 /***/ }),
1672 /* 14 */
1673 /***/ (function(module, exports) {
1674
1675 Object.defineProperty(exports, "__esModule", { value: true });
1676 var Interaction = /** @class */ (function () {
1677 function Interaction(component) {
1678 this.view = component._getView();
1679 this.component = component;
1680 }
1681 Interaction.prototype.opt = function (name) {
1682 return this.view.opt(name);
1683 };
1684 Interaction.prototype.end = function () {
1685 // subclasses can implement
1686 };
1687 return Interaction;
1688 }());
1689 exports.default = Interaction;
1690
1691
1692 /***/ }),
1693 /* 15 */
1694 /***/ (function(module, exports) {
1695
1696 Object.defineProperty(exports, "__esModule", { value: true });
1697 var Mixin = /** @class */ (function () {
1698 function Mixin() {
1699 }
1700 Mixin.mixInto = function (destClass) {
1701 var _this = this;
1702 Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
1703 if (!destClass.prototype[name]) { // if destination class doesn't already define it
1704 destClass.prototype[name] = _this.prototype[name];
1705 }
1706 });
1707 };
1708 /*
1709 will override existing methods
1710 TODO: remove! not used anymore
1711 */
1712 Mixin.mixOver = function (destClass) {
1713 var _this = this;
1714 Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
1715 destClass.prototype[name] = _this.prototype[name];
1716 });
1717 };
1718 return Mixin;
1719 }());
1720 exports.default = Mixin;
1721
1722
1723 /***/ }),
1724 /* 16 */
1725 /***/ (function(module, exports, __webpack_require__) {
1726
1727 Object.defineProperty(exports, "__esModule", { value: true });
1728 var UnzonedRange_1 = __webpack_require__(5);
1729 /*
1730 Meant to be immutable
1731 */
1732 var EventDateProfile = /** @class */ (function () {
1733 function EventDateProfile(start, end, calendar) {
1734 this.start = start;
1735 this.end = end || null;
1736 this.unzonedRange = this.buildUnzonedRange(calendar);
1737 }
1738 /*
1739 Needs an EventSource object
1740 */
1741 EventDateProfile.parse = function (rawProps, source) {
1742 var startInput = rawProps.start || rawProps.date;
1743 var endInput = rawProps.end;
1744 if (!startInput) {
1745 return false;
1746 }
1747 var calendar = source.calendar;
1748 var start = calendar.moment(startInput);
1749 var end = endInput ? calendar.moment(endInput) : null;
1750 var forcedAllDay = rawProps.allDay;
1751 var forceEventDuration = calendar.opt('forceEventDuration');
1752 if (!start.isValid()) {
1753 return false;
1754 }
1755 if (forcedAllDay == null) {
1756 forcedAllDay = source.allDayDefault;
1757 if (forcedAllDay == null) {
1758 forcedAllDay = calendar.opt('allDayDefault');
1759 }
1760 }
1761 if (forcedAllDay === true) {
1762 start.stripTime();
1763 if (end) {
1764 end.stripTime();
1765 }
1766 }
1767 else if (forcedAllDay === false) {
1768 if (!start.hasTime()) {
1769 start.time(0);
1770 }
1771 if (end && !end.hasTime()) {
1772 end.time(0);
1773 }
1774 }
1775 if (end && (!end.isValid() || !end.isAfter(start))) {
1776 end = null;
1777 }
1778 if (!end && forceEventDuration) {
1779 end = calendar.getDefaultEventEnd(!start.hasTime(), start);
1780 }
1781 return new EventDateProfile(start, end, calendar);
1782 };
1783 EventDateProfile.isStandardProp = function (propName) {
1784 return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay';
1785 };
1786 EventDateProfile.prototype.isAllDay = function () {
1787 return !(this.start.hasTime() || (this.end && this.end.hasTime()));
1788 };
1789 /*
1790 Needs a Calendar object
1791 */
1792 EventDateProfile.prototype.buildUnzonedRange = function (calendar) {
1793 var startMs = this.start.clone().stripZone().valueOf();
1794 var endMs = this.getEnd(calendar).stripZone().valueOf();
1795 return new UnzonedRange_1.default(startMs, endMs);
1796 };
1797 /*
1798 Needs a Calendar object
1799 */
1800 EventDateProfile.prototype.getEnd = function (calendar) {
1801 return this.end ?
1802 this.end.clone() :
1803 // derive the end from the start and allDay. compute allDay if necessary
1804 calendar.getDefaultEventEnd(this.isAllDay(), this.start);
1805 };
1806 return EventDateProfile;
1807 }());
1808 exports.default = EventDateProfile;
1809
1810
1811 /***/ }),
1812 /* 17 */
1813 /***/ (function(module, exports, __webpack_require__) {
1814
1815 Object.defineProperty(exports, "__esModule", { value: true });
1816 var tslib_1 = __webpack_require__(2);
1817 var util_1 = __webpack_require__(4);
1818 var DragListener_1 = __webpack_require__(59);
1819 /* Tracks mouse movements over a component and raises events about which hit the mouse is over.
1820 ------------------------------------------------------------------------------------------------------------------------
1821 options:
1822 - subjectEl
1823 - subjectCenter
1824 */
1825 var HitDragListener = /** @class */ (function (_super) {
1826 tslib_1.__extends(HitDragListener, _super);
1827 function HitDragListener(component, options) {
1828 var _this = _super.call(this, options) || this;
1829 _this.component = component;
1830 return _this;
1831 }
1832 // Called when drag listening starts (but a real drag has not necessarily began).
1833 // ev might be undefined if dragging was started manually.
1834 HitDragListener.prototype.handleInteractionStart = function (ev) {
1835 var subjectEl = this.subjectEl;
1836 var subjectRect;
1837 var origPoint;
1838 var point;
1839 this.component.hitsNeeded();
1840 this.computeScrollBounds(); // for autoscroll
1841 if (ev) {
1842 origPoint = { left: util_1.getEvX(ev), top: util_1.getEvY(ev) };
1843 point = origPoint;
1844 // constrain the point to bounds of the element being dragged
1845 if (subjectEl) {
1846 subjectRect = util_1.getOuterRect(subjectEl); // used for centering as well
1847 point = util_1.constrainPoint(point, subjectRect);
1848 }
1849 this.origHit = this.queryHit(point.left, point.top);
1850 // treat the center of the subject as the collision point?
1851 if (subjectEl && this.options.subjectCenter) {
1852 // only consider the area the subject overlaps the hit. best for large subjects.
1853 // TODO: skip this if hit didn't supply left/right/top/bottom
1854 if (this.origHit) {
1855 subjectRect = util_1.intersectRects(this.origHit, subjectRect) ||
1856 subjectRect; // in case there is no intersection
1857 }
1858 point = util_1.getRectCenter(subjectRect);
1859 }
1860 this.coordAdjust = util_1.diffPoints(point, origPoint); // point - origPoint
1861 }
1862 else {
1863 this.origHit = null;
1864 this.coordAdjust = null;
1865 }
1866 // call the super-method. do it after origHit has been computed
1867 _super.prototype.handleInteractionStart.call(this, ev);
1868 };
1869 // Called when the actual drag has started
1870 HitDragListener.prototype.handleDragStart = function (ev) {
1871 var hit;
1872 _super.prototype.handleDragStart.call(this, ev);
1873 // might be different from this.origHit if the min-distance is large
1874 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev));
1875 // report the initial hit the mouse is over
1876 // especially important if no min-distance and drag starts immediately
1877 if (hit) {
1878 this.handleHitOver(hit);
1879 }
1880 };
1881 // Called when the drag moves
1882 HitDragListener.prototype.handleDrag = function (dx, dy, ev) {
1883 var hit;
1884 _super.prototype.handleDrag.call(this, dx, dy, ev);
1885 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev));
1886 if (!isHitsEqual(hit, this.hit)) { // a different hit than before?
1887 if (this.hit) {
1888 this.handleHitOut();
1889 }
1890 if (hit) {
1891 this.handleHitOver(hit);
1892 }
1893 }
1894 };
1895 // Called when dragging has been stopped
1896 HitDragListener.prototype.handleDragEnd = function (ev) {
1897 this.handleHitDone();
1898 _super.prototype.handleDragEnd.call(this, ev);
1899 };
1900 // Called when a the mouse has just moved over a new hit
1901 HitDragListener.prototype.handleHitOver = function (hit) {
1902 var isOrig = isHitsEqual(hit, this.origHit);
1903 this.hit = hit;
1904 this.trigger('hitOver', this.hit, isOrig, this.origHit);
1905 };
1906 // Called when the mouse has just moved out of a hit
1907 HitDragListener.prototype.handleHitOut = function () {
1908 if (this.hit) {
1909 this.trigger('hitOut', this.hit);
1910 this.handleHitDone();
1911 this.hit = null;
1912 }
1913 };
1914 // Called after a hitOut. Also called before a dragStop
1915 HitDragListener.prototype.handleHitDone = function () {
1916 if (this.hit) {
1917 this.trigger('hitDone', this.hit);
1918 }
1919 };
1920 // Called when the interaction ends, whether there was a real drag or not
1921 HitDragListener.prototype.handleInteractionEnd = function (ev, isCancelled) {
1922 _super.prototype.handleInteractionEnd.call(this, ev, isCancelled);
1923 this.origHit = null;
1924 this.hit = null;
1925 this.component.hitsNotNeeded();
1926 };
1927 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
1928 HitDragListener.prototype.handleScrollEnd = function () {
1929 _super.prototype.handleScrollEnd.call(this);
1930 // hits' absolute positions will be in new places after a user's scroll.
1931 // HACK for recomputing.
1932 if (this.isDragging) {
1933 this.component.releaseHits();
1934 this.component.prepareHits();
1935 }
1936 };
1937 // Gets the hit underneath the coordinates for the given mouse event
1938 HitDragListener.prototype.queryHit = function (left, top) {
1939 if (this.coordAdjust) {
1940 left += this.coordAdjust.left;
1941 top += this.coordAdjust.top;
1942 }
1943 return this.component.queryHit(left, top);
1944 };
1945 return HitDragListener;
1946 }(DragListener_1.default));
1947 exports.default = HitDragListener;
1948 // Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.
1949 // Two null values will be considered equal, as two "out of the component" states are the same.
1950 function isHitsEqual(hit0, hit1) {
1951 if (!hit0 && !hit1) {
1952 return true;
1953 }
1954 if (hit0 && hit1) {
1955 return hit0.component === hit1.component &&
1956 isHitPropsWithin(hit0, hit1) &&
1957 isHitPropsWithin(hit1, hit0); // ensures all props are identical
1958 }
1959 return false;
1960 }
1961 // Returns true if all of subHit's non-standard properties are within superHit
1962 function isHitPropsWithin(subHit, superHit) {
1963 for (var propName in subHit) {
1964 if (!/^(component|left|right|top|bottom)$/.test(propName)) {
1965 if (subHit[propName] !== superHit[propName]) {
1966 return false;
1967 }
1968 }
1969 }
1970 return true;
1971 }
1972
1973
1974 /***/ }),
1975 /* 18 */
1976 /***/ (function(module, exports, __webpack_require__) {
1977
1978 Object.defineProperty(exports, "__esModule", { value: true });
1979 exports.version = '3.10.2';
1980 // When introducing internal API incompatibilities (where fullcalendar plugins would break),
1981 // the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0)
1982 // and the below integer should be incremented.
1983 exports.internalApiVersion = 12;
1984 var util_1 = __webpack_require__(4);
1985 exports.applyAll = util_1.applyAll;
1986 exports.debounce = util_1.debounce;
1987 exports.isInt = util_1.isInt;
1988 exports.htmlEscape = util_1.htmlEscape;
1989 exports.cssToStr = util_1.cssToStr;
1990 exports.proxy = util_1.proxy;
1991 exports.capitaliseFirstLetter = util_1.capitaliseFirstLetter;
1992 exports.getOuterRect = util_1.getOuterRect;
1993 exports.getClientRect = util_1.getClientRect;
1994 exports.getContentRect = util_1.getContentRect;
1995 exports.getScrollbarWidths = util_1.getScrollbarWidths;
1996 exports.preventDefault = util_1.preventDefault;
1997 exports.parseFieldSpecs = util_1.parseFieldSpecs;
1998 exports.compareByFieldSpecs = util_1.compareByFieldSpecs;
1999 exports.compareByFieldSpec = util_1.compareByFieldSpec;
2000 exports.flexibleCompare = util_1.flexibleCompare;
2001 exports.computeGreatestUnit = util_1.computeGreatestUnit;
2002 exports.divideRangeByDuration = util_1.divideRangeByDuration;
2003 exports.divideDurationByDuration = util_1.divideDurationByDuration;
2004 exports.multiplyDuration = util_1.multiplyDuration;
2005 exports.durationHasTime = util_1.durationHasTime;
2006 exports.log = util_1.log;
2007 exports.warn = util_1.warn;
2008 exports.removeExact = util_1.removeExact;
2009 exports.intersectRects = util_1.intersectRects;
2010 exports.allowSelection = util_1.allowSelection;
2011 exports.attrsToStr = util_1.attrsToStr;
2012 exports.compareNumbers = util_1.compareNumbers;
2013 exports.compensateScroll = util_1.compensateScroll;
2014 exports.computeDurationGreatestUnit = util_1.computeDurationGreatestUnit;
2015 exports.constrainPoint = util_1.constrainPoint;
2016 exports.copyOwnProps = util_1.copyOwnProps;
2017 exports.diffByUnit = util_1.diffByUnit;
2018 exports.diffDay = util_1.diffDay;
2019 exports.diffDayTime = util_1.diffDayTime;
2020 exports.diffPoints = util_1.diffPoints;
2021 exports.disableCursor = util_1.disableCursor;
2022 exports.distributeHeight = util_1.distributeHeight;
2023 exports.enableCursor = util_1.enableCursor;
2024 exports.firstDefined = util_1.firstDefined;
2025 exports.getEvIsTouch = util_1.getEvIsTouch;
2026 exports.getEvX = util_1.getEvX;
2027 exports.getEvY = util_1.getEvY;
2028 exports.getRectCenter = util_1.getRectCenter;
2029 exports.getScrollParent = util_1.getScrollParent;
2030 exports.hasOwnProp = util_1.hasOwnProp;
2031 exports.isArraysEqual = util_1.isArraysEqual;
2032 exports.isNativeDate = util_1.isNativeDate;
2033 exports.isPrimaryMouseButton = util_1.isPrimaryMouseButton;
2034 exports.isTimeString = util_1.isTimeString;
2035 exports.matchCellWidths = util_1.matchCellWidths;
2036 exports.mergeProps = util_1.mergeProps;
2037 exports.preventSelection = util_1.preventSelection;
2038 exports.removeMatching = util_1.removeMatching;
2039 exports.stripHtmlEntities = util_1.stripHtmlEntities;
2040 exports.subtractInnerElHeight = util_1.subtractInnerElHeight;
2041 exports.uncompensateScroll = util_1.uncompensateScroll;
2042 exports.undistributeHeight = util_1.undistributeHeight;
2043 exports.dayIDs = util_1.dayIDs;
2044 exports.unitsDesc = util_1.unitsDesc;
2045 var date_formatting_1 = __webpack_require__(49);
2046 exports.formatDate = date_formatting_1.formatDate;
2047 exports.formatRange = date_formatting_1.formatRange;
2048 exports.queryMostGranularFormatUnit = date_formatting_1.queryMostGranularFormatUnit;
2049 var locale_1 = __webpack_require__(32);
2050 exports.datepickerLocale = locale_1.datepickerLocale;
2051 exports.locale = locale_1.locale;
2052 exports.getMomentLocaleData = locale_1.getMomentLocaleData;
2053 exports.populateInstanceComputableOptions = locale_1.populateInstanceComputableOptions;
2054 var util_2 = __webpack_require__(19);
2055 exports.eventDefsToEventInstances = util_2.eventDefsToEventInstances;
2056 exports.eventFootprintToComponentFootprint = util_2.eventFootprintToComponentFootprint;
2057 exports.eventInstanceToEventRange = util_2.eventInstanceToEventRange;
2058 exports.eventInstanceToUnzonedRange = util_2.eventInstanceToUnzonedRange;
2059 exports.eventRangeToEventFootprint = util_2.eventRangeToEventFootprint;
2060 var moment_ext_1 = __webpack_require__(11);
2061 exports.moment = moment_ext_1.default;
2062 var EmitterMixin_1 = __webpack_require__(13);
2063 exports.EmitterMixin = EmitterMixin_1.default;
2064 var ListenerMixin_1 = __webpack_require__(7);
2065 exports.ListenerMixin = ListenerMixin_1.default;
2066 var Model_1 = __webpack_require__(51);
2067 exports.Model = Model_1.default;
2068 var Constraints_1 = __webpack_require__(217);
2069 exports.Constraints = Constraints_1.default;
2070 var DateProfileGenerator_1 = __webpack_require__(55);
2071 exports.DateProfileGenerator = DateProfileGenerator_1.default;
2072 var UnzonedRange_1 = __webpack_require__(5);
2073 exports.UnzonedRange = UnzonedRange_1.default;
2074 var ComponentFootprint_1 = __webpack_require__(12);
2075 exports.ComponentFootprint = ComponentFootprint_1.default;
2076 var BusinessHourGenerator_1 = __webpack_require__(218);
2077 exports.BusinessHourGenerator = BusinessHourGenerator_1.default;
2078 var EventPeriod_1 = __webpack_require__(219);
2079 exports.EventPeriod = EventPeriod_1.default;
2080 var EventManager_1 = __webpack_require__(220);
2081 exports.EventManager = EventManager_1.default;
2082 var EventDef_1 = __webpack_require__(37);
2083 exports.EventDef = EventDef_1.default;
2084 var EventDefMutation_1 = __webpack_require__(39);
2085 exports.EventDefMutation = EventDefMutation_1.default;
2086 var EventDefParser_1 = __webpack_require__(36);
2087 exports.EventDefParser = EventDefParser_1.default;
2088 var EventInstance_1 = __webpack_require__(53);
2089 exports.EventInstance = EventInstance_1.default;
2090 var EventRange_1 = __webpack_require__(50);
2091 exports.EventRange = EventRange_1.default;
2092 var RecurringEventDef_1 = __webpack_require__(54);
2093 exports.RecurringEventDef = RecurringEventDef_1.default;
2094 var SingleEventDef_1 = __webpack_require__(9);
2095 exports.SingleEventDef = SingleEventDef_1.default;
2096 var EventDefDateMutation_1 = __webpack_require__(40);
2097 exports.EventDefDateMutation = EventDefDateMutation_1.default;
2098 var EventDateProfile_1 = __webpack_require__(16);
2099 exports.EventDateProfile = EventDateProfile_1.default;
2100 var EventSourceParser_1 = __webpack_require__(38);
2101 exports.EventSourceParser = EventSourceParser_1.default;
2102 var EventSource_1 = __webpack_require__(6);
2103 exports.EventSource = EventSource_1.default;
2104 var ThemeRegistry_1 = __webpack_require__(57);
2105 exports.defineThemeSystem = ThemeRegistry_1.defineThemeSystem;
2106 exports.getThemeSystemClass = ThemeRegistry_1.getThemeSystemClass;
2107 var EventInstanceGroup_1 = __webpack_require__(20);
2108 exports.EventInstanceGroup = EventInstanceGroup_1.default;
2109 var ArrayEventSource_1 = __webpack_require__(56);
2110 exports.ArrayEventSource = ArrayEventSource_1.default;
2111 var FuncEventSource_1 = __webpack_require__(223);
2112 exports.FuncEventSource = FuncEventSource_1.default;
2113 var JsonFeedEventSource_1 = __webpack_require__(224);
2114 exports.JsonFeedEventSource = JsonFeedEventSource_1.default;
2115 var EventFootprint_1 = __webpack_require__(34);
2116 exports.EventFootprint = EventFootprint_1.default;
2117 var Class_1 = __webpack_require__(35);
2118 exports.Class = Class_1.default;
2119 var Mixin_1 = __webpack_require__(15);
2120 exports.Mixin = Mixin_1.default;
2121 var CoordCache_1 = __webpack_require__(58);
2122 exports.CoordCache = CoordCache_1.default;
2123 var Iterator_1 = __webpack_require__(225);
2124 exports.Iterator = Iterator_1.default;
2125 var DragListener_1 = __webpack_require__(59);
2126 exports.DragListener = DragListener_1.default;
2127 var HitDragListener_1 = __webpack_require__(17);
2128 exports.HitDragListener = HitDragListener_1.default;
2129 var MouseFollower_1 = __webpack_require__(226);
2130 exports.MouseFollower = MouseFollower_1.default;
2131 var ParsableModelMixin_1 = __webpack_require__(52);
2132 exports.ParsableModelMixin = ParsableModelMixin_1.default;
2133 var Popover_1 = __webpack_require__(227);
2134 exports.Popover = Popover_1.default;
2135 var Promise_1 = __webpack_require__(21);
2136 exports.Promise = Promise_1.default;
2137 var TaskQueue_1 = __webpack_require__(228);
2138 exports.TaskQueue = TaskQueue_1.default;
2139 var RenderQueue_1 = __webpack_require__(229);
2140 exports.RenderQueue = RenderQueue_1.default;
2141 var Scroller_1 = __webpack_require__(41);
2142 exports.Scroller = Scroller_1.default;
2143 var Theme_1 = __webpack_require__(22);
2144 exports.Theme = Theme_1.default;
2145 var Component_1 = __webpack_require__(230);
2146 exports.Component = Component_1.default;
2147 var DateComponent_1 = __webpack_require__(231);
2148 exports.DateComponent = DateComponent_1.default;
2149 var InteractiveDateComponent_1 = __webpack_require__(42);
2150 exports.InteractiveDateComponent = InteractiveDateComponent_1.default;
2151 var Calendar_1 = __webpack_require__(232);
2152 exports.Calendar = Calendar_1.default;
2153 var View_1 = __webpack_require__(43);
2154 exports.View = View_1.default;
2155 var ViewRegistry_1 = __webpack_require__(24);
2156 exports.defineView = ViewRegistry_1.defineView;
2157 exports.getViewConfig = ViewRegistry_1.getViewConfig;
2158 var DayTableMixin_1 = __webpack_require__(60);
2159 exports.DayTableMixin = DayTableMixin_1.default;
2160 var BusinessHourRenderer_1 = __webpack_require__(61);
2161 exports.BusinessHourRenderer = BusinessHourRenderer_1.default;
2162 var EventRenderer_1 = __webpack_require__(44);
2163 exports.EventRenderer = EventRenderer_1.default;
2164 var FillRenderer_1 = __webpack_require__(62);
2165 exports.FillRenderer = FillRenderer_1.default;
2166 var HelperRenderer_1 = __webpack_require__(63);
2167 exports.HelperRenderer = HelperRenderer_1.default;
2168 var ExternalDropping_1 = __webpack_require__(233);
2169 exports.ExternalDropping = ExternalDropping_1.default;
2170 var EventResizing_1 = __webpack_require__(234);
2171 exports.EventResizing = EventResizing_1.default;
2172 var EventPointing_1 = __webpack_require__(64);
2173 exports.EventPointing = EventPointing_1.default;
2174 var EventDragging_1 = __webpack_require__(235);
2175 exports.EventDragging = EventDragging_1.default;
2176 var DateSelecting_1 = __webpack_require__(236);
2177 exports.DateSelecting = DateSelecting_1.default;
2178 var DateClicking_1 = __webpack_require__(237);
2179 exports.DateClicking = DateClicking_1.default;
2180 var Interaction_1 = __webpack_require__(14);
2181 exports.Interaction = Interaction_1.default;
2182 var StandardInteractionsMixin_1 = __webpack_require__(65);
2183 exports.StandardInteractionsMixin = StandardInteractionsMixin_1.default;
2184 var AgendaView_1 = __webpack_require__(238);
2185 exports.AgendaView = AgendaView_1.default;
2186 var TimeGrid_1 = __webpack_require__(239);
2187 exports.TimeGrid = TimeGrid_1.default;
2188 var TimeGridEventRenderer_1 = __webpack_require__(240);
2189 exports.TimeGridEventRenderer = TimeGridEventRenderer_1.default;
2190 var TimeGridFillRenderer_1 = __webpack_require__(242);
2191 exports.TimeGridFillRenderer = TimeGridFillRenderer_1.default;
2192 var TimeGridHelperRenderer_1 = __webpack_require__(241);
2193 exports.TimeGridHelperRenderer = TimeGridHelperRenderer_1.default;
2194 var DayGrid_1 = __webpack_require__(66);
2195 exports.DayGrid = DayGrid_1.default;
2196 var DayGridEventRenderer_1 = __webpack_require__(243);
2197 exports.DayGridEventRenderer = DayGridEventRenderer_1.default;
2198 var DayGridFillRenderer_1 = __webpack_require__(245);
2199 exports.DayGridFillRenderer = DayGridFillRenderer_1.default;
2200 var DayGridHelperRenderer_1 = __webpack_require__(244);
2201 exports.DayGridHelperRenderer = DayGridHelperRenderer_1.default;
2202 var BasicView_1 = __webpack_require__(67);
2203 exports.BasicView = BasicView_1.default;
2204 var BasicViewDateProfileGenerator_1 = __webpack_require__(68);
2205 exports.BasicViewDateProfileGenerator = BasicViewDateProfileGenerator_1.default;
2206 var MonthView_1 = __webpack_require__(246);
2207 exports.MonthView = MonthView_1.default;
2208 var MonthViewDateProfileGenerator_1 = __webpack_require__(247);
2209 exports.MonthViewDateProfileGenerator = MonthViewDateProfileGenerator_1.default;
2210 var ListView_1 = __webpack_require__(248);
2211 exports.ListView = ListView_1.default;
2212 var ListEventPointing_1 = __webpack_require__(250);
2213 exports.ListEventPointing = ListEventPointing_1.default;
2214 var ListEventRenderer_1 = __webpack_require__(249);
2215 exports.ListEventRenderer = ListEventRenderer_1.default;
2216
2217
2218 /***/ }),
2219 /* 19 */
2220 /***/ (function(module, exports, __webpack_require__) {
2221
2222 Object.defineProperty(exports, "__esModule", { value: true });
2223 var EventRange_1 = __webpack_require__(50);
2224 var EventFootprint_1 = __webpack_require__(34);
2225 var ComponentFootprint_1 = __webpack_require__(12);
2226 function eventDefsToEventInstances(eventDefs, unzonedRange) {
2227 var eventInstances = [];
2228 var i;
2229 for (i = 0; i < eventDefs.length; i++) {
2230 eventInstances.push.apply(eventInstances, // append
2231 eventDefs[i].buildInstances(unzonedRange));
2232 }
2233 return eventInstances;
2234 }
2235 exports.eventDefsToEventInstances = eventDefsToEventInstances;
2236 function eventInstanceToEventRange(eventInstance) {
2237 return new EventRange_1.default(eventInstance.dateProfile.unzonedRange, eventInstance.def, eventInstance);
2238 }
2239 exports.eventInstanceToEventRange = eventInstanceToEventRange;
2240 function eventRangeToEventFootprint(eventRange) {
2241 return new EventFootprint_1.default(new ComponentFootprint_1.default(eventRange.unzonedRange, eventRange.eventDef.isAllDay()), eventRange.eventDef, eventRange.eventInstance // might not exist
2242 );
2243 }
2244 exports.eventRangeToEventFootprint = eventRangeToEventFootprint;
2245 function eventInstanceToUnzonedRange(eventInstance) {
2246 return eventInstance.dateProfile.unzonedRange;
2247 }
2248 exports.eventInstanceToUnzonedRange = eventInstanceToUnzonedRange;
2249 function eventFootprintToComponentFootprint(eventFootprint) {
2250 return eventFootprint.componentFootprint;
2251 }
2252 exports.eventFootprintToComponentFootprint = eventFootprintToComponentFootprint;
2253
2254
2255 /***/ }),
2256 /* 20 */
2257 /***/ (function(module, exports, __webpack_require__) {
2258
2259 Object.defineProperty(exports, "__esModule", { value: true });
2260 var UnzonedRange_1 = __webpack_require__(5);
2261 var util_1 = __webpack_require__(19);
2262 var EventRange_1 = __webpack_require__(50);
2263 /*
2264 It's expected that there will be at least one EventInstance,
2265 OR that an explicitEventDef is assigned.
2266 */
2267 var EventInstanceGroup = /** @class */ (function () {
2268 function EventInstanceGroup(eventInstances) {
2269 this.eventInstances = eventInstances || [];
2270 }
2271 EventInstanceGroup.prototype.getAllEventRanges = function (constraintRange) {
2272 if (constraintRange) {
2273 return this.sliceNormalRenderRanges(constraintRange);
2274 }
2275 else {
2276 return this.eventInstances.map(util_1.eventInstanceToEventRange);
2277 }
2278 };
2279 EventInstanceGroup.prototype.sliceRenderRanges = function (constraintRange) {
2280 if (this.isInverse()) {
2281 return this.sliceInverseRenderRanges(constraintRange);
2282 }
2283 else {
2284 return this.sliceNormalRenderRanges(constraintRange);
2285 }
2286 };
2287 EventInstanceGroup.prototype.sliceNormalRenderRanges = function (constraintRange) {
2288 var eventInstances = this.eventInstances;
2289 var i;
2290 var eventInstance;
2291 var slicedRange;
2292 var slicedEventRanges = [];
2293 for (i = 0; i < eventInstances.length; i++) {
2294 eventInstance = eventInstances[i];
2295 slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange);
2296 if (slicedRange) {
2297 slicedEventRanges.push(new EventRange_1.default(slicedRange, eventInstance.def, eventInstance));
2298 }
2299 }
2300 return slicedEventRanges;
2301 };
2302 EventInstanceGroup.prototype.sliceInverseRenderRanges = function (constraintRange) {
2303 var unzonedRanges = this.eventInstances.map(util_1.eventInstanceToUnzonedRange);
2304 var ownerDef = this.getEventDef();
2305 unzonedRanges = UnzonedRange_1.default.invertRanges(unzonedRanges, constraintRange);
2306 return unzonedRanges.map(function (unzonedRange) {
2307 return new EventRange_1.default(unzonedRange, ownerDef); // don't give an EventInstance
2308 });
2309 };
2310 EventInstanceGroup.prototype.isInverse = function () {
2311 return this.getEventDef().hasInverseRendering();
2312 };
2313 EventInstanceGroup.prototype.getEventDef = function () {
2314 return this.explicitEventDef || this.eventInstances[0].def;
2315 };
2316 return EventInstanceGroup;
2317 }());
2318 exports.default = EventInstanceGroup;
2319
2320
2321 /***/ }),
2322 /* 21 */
2323 /***/ (function(module, exports, __webpack_require__) {
2324
2325 Object.defineProperty(exports, "__esModule", { value: true });
2326 var $ = __webpack_require__(3);
2327 var PromiseStub = {
2328 construct: function (executor) {
2329 var deferred = $.Deferred();
2330 var promise = deferred.promise();
2331 if (typeof executor === 'function') {
2332 executor(function (val) {
2333 deferred.resolve(val);
2334 attachImmediatelyResolvingThen(promise, val);
2335 }, function () {
2336 deferred.reject();
2337 attachImmediatelyRejectingThen(promise);
2338 });
2339 }
2340 return promise;
2341 },
2342 resolve: function (val) {
2343 var deferred = $.Deferred().resolve(val);
2344 var promise = deferred.promise();
2345 attachImmediatelyResolvingThen(promise, val);
2346 return promise;
2347 },
2348 reject: function () {
2349 var deferred = $.Deferred().reject();
2350 var promise = deferred.promise();
2351 attachImmediatelyRejectingThen(promise);
2352 return promise;
2353 }
2354 };
2355 exports.default = PromiseStub;
2356 function attachImmediatelyResolvingThen(promise, val) {
2357 promise.then = function (onResolve) {
2358 if (typeof onResolve === 'function') {
2359 return PromiseStub.resolve(onResolve(val));
2360 }
2361 return promise;
2362 };
2363 }
2364 function attachImmediatelyRejectingThen(promise) {
2365 promise.then = function (onResolve, onReject) {
2366 if (typeof onReject === 'function') {
2367 onReject();
2368 }
2369 return promise;
2370 };
2371 }
2372
2373
2374 /***/ }),
2375 /* 22 */
2376 /***/ (function(module, exports, __webpack_require__) {
2377
2378 Object.defineProperty(exports, "__esModule", { value: true });
2379 var $ = __webpack_require__(3);
2380 var Theme = /** @class */ (function () {
2381 function Theme(optionsManager) {
2382 this.optionsManager = optionsManager;
2383 this.processIconOverride();
2384 }
2385 Theme.prototype.processIconOverride = function () {
2386 if (this.iconOverrideOption) {
2387 this.setIconOverride(this.optionsManager.get(this.iconOverrideOption));
2388 }
2389 };
2390 Theme.prototype.setIconOverride = function (iconOverrideHash) {
2391 var iconClassesCopy;
2392 var buttonName;
2393 if ($.isPlainObject(iconOverrideHash)) {
2394 iconClassesCopy = $.extend({}, this.iconClasses);
2395 for (buttonName in iconOverrideHash) {
2396 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
2397 }
2398 this.iconClasses = iconClassesCopy;
2399 }
2400 else if (iconOverrideHash === false) {
2401 this.iconClasses = {};
2402 }
2403 };
2404 Theme.prototype.applyIconOverridePrefix = function (className) {
2405 var prefix = this.iconOverridePrefix;
2406 if (prefix && className.indexOf(prefix) !== 0) { // if not already present
2407 className = prefix + className;
2408 }
2409 return className;
2410 };
2411 Theme.prototype.getClass = function (key) {
2412 return this.classes[key] || '';
2413 };
2414 Theme.prototype.getIconClass = function (buttonName) {
2415 var className = this.iconClasses[buttonName];
2416 if (className) {
2417 return this.baseIconClass + ' ' + className;
2418 }
2419 return '';
2420 };
2421 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
2422 var className;
2423 if (this.iconOverrideCustomButtonOption) {
2424 className = customButtonProps[this.iconOverrideCustomButtonOption];
2425 if (className) {
2426 return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
2427 }
2428 }
2429 return '';
2430 };
2431 return Theme;
2432 }());
2433 exports.default = Theme;
2434 Theme.prototype.classes = {};
2435 Theme.prototype.iconClasses = {};
2436 Theme.prototype.baseIconClass = '';
2437 Theme.prototype.iconOverridePrefix = '';
2438
2439
2440 /***/ }),
2441 /* 23 */
2442 /***/ (function(module, exports, __webpack_require__) {
2443
2444 Object.defineProperty(exports, "__esModule", { value: true });
2445 var $ = __webpack_require__(3);
2446 var exportHooks = __webpack_require__(18);
2447 var EmitterMixin_1 = __webpack_require__(13);
2448 var ListenerMixin_1 = __webpack_require__(7);
2449 exportHooks.touchMouseIgnoreWait = 500;
2450 var globalEmitter = null;
2451 var neededCount = 0;
2452 /*
2453 Listens to document and window-level user-interaction events, like touch events and mouse events,
2454 and fires these events as-is to whoever is observing a GlobalEmitter.
2455 Best when used as a singleton via GlobalEmitter.get()
2456
2457 Normalizes mouse/touch events. For examples:
2458 - ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click
2459 - compensates for various buggy scenarios where a touchend does not fire
2460 */
2461 var GlobalEmitter = /** @class */ (function () {
2462 function GlobalEmitter() {
2463 this.isTouching = false;
2464 this.mouseIgnoreDepth = 0;
2465 }
2466 // gets the singleton
2467 GlobalEmitter.get = function () {
2468 if (!globalEmitter) {
2469 globalEmitter = new GlobalEmitter();
2470 globalEmitter.bind();
2471 }
2472 return globalEmitter;
2473 };
2474 // called when an object knows it will need a GlobalEmitter in the near future.
2475 GlobalEmitter.needed = function () {
2476 GlobalEmitter.get(); // ensures globalEmitter
2477 neededCount++;
2478 };
2479 // called when the object that originally called needed() doesn't need a GlobalEmitter anymore.
2480 GlobalEmitter.unneeded = function () {
2481 neededCount--;
2482 if (!neededCount) { // nobody else needs it
2483 globalEmitter.unbind();
2484 globalEmitter = null;
2485 }
2486 };
2487 GlobalEmitter.prototype.bind = function () {
2488 var _this = this;
2489 this.listenTo($(document), {
2490 touchstart: this.handleTouchStart,
2491 touchcancel: this.handleTouchCancel,
2492 touchend: this.handleTouchEnd,
2493 mousedown: this.handleMouseDown,
2494 mousemove: this.handleMouseMove,
2495 mouseup: this.handleMouseUp,
2496 click: this.handleClick,
2497 selectstart: this.handleSelectStart,
2498 contextmenu: this.handleContextMenu
2499 });
2500 // because we need to call preventDefault
2501 // because https://www.chromestatus.com/features/5093566007214080
2502 // TODO: investigate performance because this is a global handler
2503 window.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev) {
2504 _this.handleTouchMove($.Event(ev));
2505 }, { passive: false } // allows preventDefault()
2506 );
2507 // attach a handler to get called when ANY scroll action happens on the page.
2508 // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
2509 // http://stackoverflow.com/a/32954565/96342
2510 window.addEventListener('scroll', this.handleScrollProxy = function (ev) {
2511 _this.handleScroll($.Event(ev));
2512 }, true // useCapture
2513 );
2514 };
2515 GlobalEmitter.prototype.unbind = function () {
2516 this.stopListeningTo($(document));
2517 window.removeEventListener('touchmove', this.handleTouchMoveProxy, { passive: false } // use same options as addEventListener
2518 );
2519 window.removeEventListener('scroll', this.handleScrollProxy, true // useCapture
2520 );
2521 };
2522 // Touch Handlers
2523 // -----------------------------------------------------------------------------------------------------------------
2524 GlobalEmitter.prototype.handleTouchStart = function (ev) {
2525 // if a previous touch interaction never ended with a touchend, then implicitly end it,
2526 // but since a new touch interaction is about to begin, don't start the mouse ignore period.
2527 this.stopTouch(ev, true); // skipMouseIgnore=true
2528 this.isTouching = true;
2529 this.trigger('touchstart', ev);
2530 };
2531 GlobalEmitter.prototype.handleTouchMove = function (ev) {
2532 if (this.isTouching) {
2533 this.trigger('touchmove', ev);
2534 }
2535 };
2536 GlobalEmitter.prototype.handleTouchCancel = function (ev) {
2537 if (this.isTouching) {
2538 this.trigger('touchcancel', ev);
2539 // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both.
2540 // If touchend fires later, it won't have any effect b/c isTouching will be false.
2541 this.stopTouch(ev);
2542 }
2543 };
2544 GlobalEmitter.prototype.handleTouchEnd = function (ev) {
2545 this.stopTouch(ev);
2546 };
2547 // Mouse Handlers
2548 // -----------------------------------------------------------------------------------------------------------------
2549 GlobalEmitter.prototype.handleMouseDown = function (ev) {
2550 if (!this.shouldIgnoreMouse()) {
2551 this.trigger('mousedown', ev);
2552 }
2553 };
2554 GlobalEmitter.prototype.handleMouseMove = function (ev) {
2555 if (!this.shouldIgnoreMouse()) {
2556 this.trigger('mousemove', ev);
2557 }
2558 };
2559 GlobalEmitter.prototype.handleMouseUp = function (ev) {
2560 if (!this.shouldIgnoreMouse()) {
2561 this.trigger('mouseup', ev);
2562 }
2563 };
2564 GlobalEmitter.prototype.handleClick = function (ev) {
2565 if (!this.shouldIgnoreMouse()) {
2566 this.trigger('click', ev);
2567 }
2568 };
2569 // Misc Handlers
2570 // -----------------------------------------------------------------------------------------------------------------
2571 GlobalEmitter.prototype.handleSelectStart = function (ev) {
2572 this.trigger('selectstart', ev);
2573 };
2574 GlobalEmitter.prototype.handleContextMenu = function (ev) {
2575 this.trigger('contextmenu', ev);
2576 };
2577 GlobalEmitter.prototype.handleScroll = function (ev) {
2578 this.trigger('scroll', ev);
2579 };
2580 // Utils
2581 // -----------------------------------------------------------------------------------------------------------------
2582 GlobalEmitter.prototype.stopTouch = function (ev, skipMouseIgnore) {
2583 if (skipMouseIgnore === void 0) { skipMouseIgnore = false; }
2584 if (this.isTouching) {
2585 this.isTouching = false;
2586 this.trigger('touchend', ev);
2587 if (!skipMouseIgnore) {
2588 this.startTouchMouseIgnore();
2589 }
2590 }
2591 };
2592 GlobalEmitter.prototype.startTouchMouseIgnore = function () {
2593 var _this = this;
2594 var wait = exportHooks.touchMouseIgnoreWait;
2595 if (wait) {
2596 this.mouseIgnoreDepth++;
2597 setTimeout(function () {
2598 _this.mouseIgnoreDepth--;
2599 }, wait);
2600 }
2601 };
2602 GlobalEmitter.prototype.shouldIgnoreMouse = function () {
2603 return this.isTouching || Boolean(this.mouseIgnoreDepth);
2604 };
2605 return GlobalEmitter;
2606 }());
2607 exports.default = GlobalEmitter;
2608 ListenerMixin_1.default.mixInto(GlobalEmitter);
2609 EmitterMixin_1.default.mixInto(GlobalEmitter);
2610
2611
2612 /***/ }),
2613 /* 24 */
2614 /***/ (function(module, exports, __webpack_require__) {
2615
2616 Object.defineProperty(exports, "__esModule", { value: true });
2617 var exportHooks = __webpack_require__(18);
2618 exports.viewHash = {};
2619 exportHooks.views = exports.viewHash;
2620 function defineView(viewName, viewConfig) {
2621 exports.viewHash[viewName] = viewConfig;
2622 }
2623 exports.defineView = defineView;
2624 function getViewConfig(viewName) {
2625 return exports.viewHash[viewName];
2626 }
2627 exports.getViewConfig = getViewConfig;
2628
2629
2630 /***/ }),
2631 /* 25 */,
2632 /* 26 */,
2633 /* 27 */,
2634 /* 28 */,
2635 /* 29 */,
2636 /* 30 */,
2637 /* 31 */,
2638 /* 32 */
2639 /***/ (function(module, exports, __webpack_require__) {
2640
2641 Object.defineProperty(exports, "__esModule", { value: true });
2642 var $ = __webpack_require__(3);
2643 var moment = __webpack_require__(0);
2644 var exportHooks = __webpack_require__(18);
2645 var options_1 = __webpack_require__(33);
2646 var util_1 = __webpack_require__(4);
2647 exports.localeOptionHash = {};
2648 exportHooks.locales = exports.localeOptionHash;
2649 // NOTE: can't guarantee any of these computations will run because not every locale has datepicker
2650 // configs, so make sure there are English fallbacks for these in the defaults file.
2651 var dpComputableOptions = {
2652 buttonText: function (dpOptions) {
2653 return {
2654 // the translations sometimes wrongly contain HTML entities
2655 prev: util_1.stripHtmlEntities(dpOptions.prevText),
2656 next: util_1.stripHtmlEntities(dpOptions.nextText),
2657 today: util_1.stripHtmlEntities(dpOptions.currentText)
2658 };
2659 },
2660 // Produces format strings like "MMMM YYYY" -> "September 2014"
2661 monthYearFormat: function (dpOptions) {
2662 return dpOptions.showMonthAfterYear ?
2663 'YYYY[' + dpOptions.yearSuffix + '] MMMM' :
2664 'MMMM YYYY[' + dpOptions.yearSuffix + ']';
2665 }
2666 };
2667 var momComputableOptions = {
2668 // Produces format strings like "ddd M/D" -> "Fri 9/15"
2669 dayOfMonthFormat: function (momOptions, fcOptions) {
2670 var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY"
2671 // strip the year off the edge, as well as other misc non-whitespace chars
2672 format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '');
2673 if (fcOptions.isRTL) {
2674 format += ' ddd'; // for RTL, add day-of-week to end
2675 }
2676 else {
2677 format = 'ddd ' + format; // for LTR, add day-of-week to beginning
2678 }
2679 return format;
2680 },
2681 // Produces format strings like "h:mma" -> "6:00pm"
2682 mediumTimeFormat: function (momOptions) {
2683 return momOptions.longDateFormat('LT')
2684 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2685 },
2686 // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
2687 smallTimeFormat: function (momOptions) {
2688 return momOptions.longDateFormat('LT')
2689 .replace(':mm', '(:mm)')
2690 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2691 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2692 },
2693 // Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
2694 extraSmallTimeFormat: function (momOptions) {
2695 return momOptions.longDateFormat('LT')
2696 .replace(':mm', '(:mm)')
2697 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2698 .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
2699 },
2700 // Produces format strings like "ha" / "H" -> "6pm" / "18"
2701 hourFormat: function (momOptions) {
2702 return momOptions.longDateFormat('LT')
2703 .replace(':mm', '')
2704 .replace(/(\Wmm)$/, '') // like above, but for foreign locales
2705 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2706 },
2707 // Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
2708 noMeridiemTimeFormat: function (momOptions) {
2709 return momOptions.longDateFormat('LT')
2710 .replace(/\s*a$/i, ''); // remove trailing AM/PM
2711 }
2712 };
2713 // options that should be computed off live calendar options (considers override options)
2714 // TODO: best place for this? related to locale?
2715 // TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it
2716 var instanceComputableOptions = {
2717 // Produces format strings for results like "Mo 16"
2718 smallDayDateFormat: function (options) {
2719 return options.isRTL ?
2720 'D dd' :
2721 'dd D';
2722 },
2723 // Produces format strings for results like "Wk 5"
2724 weekFormat: function (options) {
2725 return options.isRTL ?
2726 'w[ ' + options.weekNumberTitle + ']' :
2727 '[' + options.weekNumberTitle + ' ]w';
2728 },
2729 // Produces format strings for results like "Wk5"
2730 smallWeekFormat: function (options) {
2731 return options.isRTL ?
2732 'w[' + options.weekNumberTitle + ']' :
2733 '[' + options.weekNumberTitle + ']w';
2734 }
2735 };
2736 // TODO: make these computable properties in optionsManager
2737 function populateInstanceComputableOptions(options) {
2738 $.each(instanceComputableOptions, function (name, func) {
2739 if (options[name] == null) {
2740 options[name] = func(options);
2741 }
2742 });
2743 }
2744 exports.populateInstanceComputableOptions = populateInstanceComputableOptions;
2745 // Initialize jQuery UI datepicker translations while using some of the translations
2746 // Will set this as the default locales for datepicker.
2747 function datepickerLocale(localeCode, dpLocaleCode, dpOptions) {
2748 // get the FullCalendar internal option hash for this locale. create if necessary
2749 var fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {});
2750 // transfer some simple options from datepicker to fc
2751 fcOptions.isRTL = dpOptions.isRTL;
2752 fcOptions.weekNumberTitle = dpOptions.weekHeader;
2753 // compute some more complex options from datepicker
2754 $.each(dpComputableOptions, function (name, func) {
2755 fcOptions[name] = func(dpOptions);
2756 });
2757 var jqDatePicker = $.datepicker;
2758 // is jQuery UI Datepicker is on the page?
2759 if (jqDatePicker) {
2760 // Register the locale data.
2761 // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker
2762 // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt".
2763 // Make an alias so the locale can be referenced either way.
2764 jqDatePicker.regional[dpLocaleCode] =
2765 jqDatePicker.regional[localeCode] = // alias
2766 dpOptions;
2767 // Alias 'en' to the default locale data. Do this every time.
2768 jqDatePicker.regional.en = jqDatePicker.regional[''];
2769 // Set as Datepicker's global defaults.
2770 jqDatePicker.setDefaults(dpOptions);
2771 }
2772 }
2773 exports.datepickerLocale = datepickerLocale;
2774 // Sets FullCalendar-specific translations. Will set the locales as the global default.
2775 function locale(localeCode, newFcOptions) {
2776 var fcOptions;
2777 var momOptions;
2778 // get the FullCalendar internal option hash for this locale. create if necessary
2779 fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {});
2780 // provided new options for this locales? merge them in
2781 if (newFcOptions) {
2782 fcOptions = exports.localeOptionHash[localeCode] = options_1.mergeOptions([fcOptions, newFcOptions]);
2783 }
2784 // compute locale options that weren't defined.
2785 // always do this. newFcOptions can be undefined when initializing from i18n file,
2786 // so no way to tell if this is an initialization or a default-setting.
2787 momOptions = getMomentLocaleData(localeCode); // will fall back to en
2788 $.each(momComputableOptions, function (name, func) {
2789 if (fcOptions[name] == null) {
2790 fcOptions[name] = (func)(momOptions, fcOptions);
2791 }
2792 });
2793 // set it as the default locale for FullCalendar
2794 options_1.globalDefaults.locale = localeCode;
2795 }
2796 exports.locale = locale;
2797 // Returns moment's internal locale data. If doesn't exist, returns English.
2798 function getMomentLocaleData(localeCode) {
2799 return moment.localeData(localeCode) || moment.localeData('en');
2800 }
2801 exports.getMomentLocaleData = getMomentLocaleData;
2802 // Initialize English by forcing computation of moment-derived options.
2803 // Also, sets it as the default.
2804 locale('en', options_1.englishDefaults);
2805
2806
2807 /***/ }),
2808 /* 33 */
2809 /***/ (function(module, exports, __webpack_require__) {
2810
2811 Object.defineProperty(exports, "__esModule", { value: true });
2812 var util_1 = __webpack_require__(4);
2813 exports.globalDefaults = {
2814 titleRangeSeparator: ' \u2013 ',
2815 monthYearFormat: 'MMMM YYYY',
2816 defaultTimedEventDuration: '02:00:00',
2817 defaultAllDayEventDuration: { days: 1 },
2818 forceEventDuration: false,
2819 nextDayThreshold: '09:00:00',
2820 // display
2821 columnHeader: true,
2822 defaultView: 'month',
2823 aspectRatio: 1.35,
2824 header: {
2825 left: 'title',
2826 center: '',
2827 right: 'today prev,next'
2828 },
2829 weekends: true,
2830 weekNumbers: false,
2831 weekNumberTitle: 'W',
2832 weekNumberCalculation: 'local',
2833 // editable: false,
2834 // nowIndicator: false,
2835 scrollTime: '06:00:00',
2836 minTime: '00:00:00',
2837 maxTime: '24:00:00',
2838 showNonCurrentDates: true,
2839 // event ajax
2840 lazyFetching: true,
2841 startParam: 'start',
2842 endParam: 'end',
2843 timezoneParam: 'timezone',
2844 timezone: false,
2845 // allDayDefault: undefined,
2846 // locale
2847 locale: null,
2848 isRTL: false,
2849 buttonText: {
2850 prev: 'prev',
2851 next: 'next',
2852 prevYear: 'prev year',
2853 nextYear: 'next year',
2854 year: 'year',
2855 today: 'today',
2856 month: 'month',
2857 week: 'week',
2858 day: 'day'
2859 },
2860 // buttonIcons: null,
2861 allDayText: 'all-day',
2862 // allows setting a min-height to the event segment to prevent short events overlapping each other
2863 agendaEventMinHeight: 0,
2864 // jquery-ui theming
2865 theme: false,
2866 // themeButtonIcons: null,
2867 // eventResizableFromStart: false,
2868 dragOpacity: .75,
2869 dragRevertDuration: 500,
2870 dragScroll: true,
2871 // selectable: false,
2872 unselectAuto: true,
2873 // selectMinDistance: 0,
2874 dropAccept: '*',
2875 eventOrder: 'title',
2876 // eventRenderWait: null,
2877 eventLimit: false,
2878 eventLimitText: 'more',
2879 eventLimitClick: 'popover',
2880 dayPopoverFormat: 'LL',
2881 handleWindowResize: true,
2882 windowResizeDelay: 100,
2883 longPressDelay: 1000
2884 };
2885 exports.englishDefaults = {
2886 dayPopoverFormat: 'dddd, MMMM D'
2887 };
2888 exports.rtlDefaults = {
2889 header: {
2890 left: 'next,prev today',
2891 center: '',
2892 right: 'title'
2893 },
2894 buttonIcons: {
2895 prev: 'right-single-arrow',
2896 next: 'left-single-arrow',
2897 prevYear: 'right-double-arrow',
2898 nextYear: 'left-double-arrow'
2899 },
2900 themeButtonIcons: {
2901 prev: 'circle-triangle-e',
2902 next: 'circle-triangle-w',
2903 nextYear: 'seek-prev',
2904 prevYear: 'seek-next'
2905 }
2906 };
2907 var complexOptions = [
2908 'header',
2909 'footer',
2910 'buttonText',
2911 'buttonIcons',
2912 'themeButtonIcons'
2913 ];
2914 // Merges an array of option objects into a single object
2915 function mergeOptions(optionObjs) {
2916 return util_1.mergeProps(optionObjs, complexOptions);
2917 }
2918 exports.mergeOptions = mergeOptions;
2919
2920
2921 /***/ }),
2922 /* 34 */
2923 /***/ (function(module, exports) {
2924
2925 Object.defineProperty(exports, "__esModule", { value: true });
2926 var EventFootprint = /** @class */ (function () {
2927 function EventFootprint(componentFootprint, eventDef, eventInstance) {
2928 this.componentFootprint = componentFootprint;
2929 this.eventDef = eventDef;
2930 if (eventInstance) {
2931 this.eventInstance = eventInstance;
2932 }
2933 }
2934 EventFootprint.prototype.getEventLegacy = function () {
2935 return (this.eventInstance || this.eventDef).toLegacy();
2936 };
2937 return EventFootprint;
2938 }());
2939 exports.default = EventFootprint;
2940
2941
2942 /***/ }),
2943 /* 35 */
2944 /***/ (function(module, exports, __webpack_require__) {
2945
2946 Object.defineProperty(exports, "__esModule", { value: true });
2947 var tslib_1 = __webpack_require__(2);
2948 var util_1 = __webpack_require__(4);
2949 // Class that all other classes will inherit from
2950 var Class = /** @class */ (function () {
2951 function Class() {
2952 }
2953 // Called on a class to create a subclass.
2954 // LIMITATION: cannot provide a constructor!
2955 Class.extend = function (members) {
2956 var SubClass = /** @class */ (function (_super) {
2957 tslib_1.__extends(SubClass, _super);
2958 function SubClass() {
2959 return _super !== null && _super.apply(this, arguments) || this;
2960 }
2961 return SubClass;
2962 }(this));
2963 util_1.copyOwnProps(members, SubClass.prototype);
2964 return SubClass;
2965 };
2966 // Adds new member variables/methods to the class's prototype.
2967 // Can be called with another class, or a plain object hash containing new members.
2968 Class.mixin = function (members) {
2969 util_1.copyOwnProps(members, this.prototype);
2970 };
2971 return Class;
2972 }());
2973 exports.default = Class;
2974
2975
2976 /***/ }),
2977 /* 36 */
2978 /***/ (function(module, exports, __webpack_require__) {
2979
2980 Object.defineProperty(exports, "__esModule", { value: true });
2981 var moment = __webpack_require__(0);
2982 var util_1 = __webpack_require__(4);
2983 var SingleEventDef_1 = __webpack_require__(9);
2984 var RecurringEventDef_1 = __webpack_require__(54);
2985 exports.default = {
2986 parse: function (eventInput, source) {
2987 if (util_1.isTimeString(eventInput.start) || moment.isDuration(eventInput.start) ||
2988 util_1.isTimeString(eventInput.end) || moment.isDuration(eventInput.end)) {
2989 return RecurringEventDef_1.default.parse(eventInput, source);
2990 }
2991 else {
2992 return SingleEventDef_1.default.parse(eventInput, source);
2993 }
2994 }
2995 };
2996
2997
2998 /***/ }),
2999 /* 37 */
3000 /***/ (function(module, exports, __webpack_require__) {
3001
3002 Object.defineProperty(exports, "__esModule", { value: true });
3003 var $ = __webpack_require__(3);
3004 var ParsableModelMixin_1 = __webpack_require__(52);
3005 var EventDef = /** @class */ (function () {
3006 function EventDef(source) {
3007 this.source = source;
3008 this.className = [];
3009 this.miscProps = {};
3010 }
3011 EventDef.parse = function (rawInput, source) {
3012 var def = new this(source);
3013 if (def.applyProps(rawInput)) {
3014 return def;
3015 }
3016 return false;
3017 };
3018 EventDef.normalizeId = function (id) {
3019 return String(id);
3020 };
3021 EventDef.generateId = function () {
3022 return '_fc' + (EventDef.uuid++);
3023 };
3024 EventDef.prototype.clone = function () {
3025 var copy = new this.constructor(this.source);
3026 copy.id = this.id;
3027 copy.rawId = this.rawId;
3028 copy.uid = this.uid; // not really unique anymore :(
3029 EventDef.copyVerbatimStandardProps(this, copy);
3030 copy.className = this.className.slice(); // copy
3031 copy.miscProps = $.extend({}, this.miscProps);
3032 return copy;
3033 };
3034 EventDef.prototype.hasInverseRendering = function () {
3035 return this.getRendering() === 'inverse-background';
3036 };
3037 EventDef.prototype.hasBgRendering = function () {
3038 var rendering = this.getRendering();
3039 return rendering === 'inverse-background' || rendering === 'background';
3040 };
3041 EventDef.prototype.getRendering = function () {
3042 if (this.rendering != null) {
3043 return this.rendering;
3044 }
3045 return this.source.rendering;
3046 };
3047 EventDef.prototype.getConstraint = function () {
3048 if (this.constraint != null) {
3049 return this.constraint;
3050 }
3051 if (this.source.constraint != null) {
3052 return this.source.constraint;
3053 }
3054 return this.source.calendar.opt('eventConstraint'); // what about View option?
3055 };
3056 EventDef.prototype.getOverlap = function () {
3057 if (this.overlap != null) {
3058 return this.overlap;
3059 }
3060 if (this.source.overlap != null) {
3061 return this.source.overlap;
3062 }
3063 return this.source.calendar.opt('eventOverlap'); // what about View option?
3064 };
3065 EventDef.prototype.isStartExplicitlyEditable = function () {
3066 if (this.startEditable != null) {
3067 return this.startEditable;
3068 }
3069 return this.source.startEditable;
3070 };
3071 EventDef.prototype.isDurationExplicitlyEditable = function () {
3072 if (this.durationEditable != null) {
3073 return this.durationEditable;
3074 }
3075 return this.source.durationEditable;
3076 };
3077 EventDef.prototype.isExplicitlyEditable = function () {
3078 if (this.editable != null) {
3079 return this.editable;
3080 }
3081 return this.source.editable;
3082 };
3083 EventDef.prototype.toLegacy = function () {
3084 var obj = $.extend({}, this.miscProps);
3085 obj._id = this.uid;
3086 obj.source = this.source;
3087 obj.className = this.className.slice(); // copy
3088 obj.allDay = this.isAllDay();
3089 if (this.rawId != null) {
3090 obj.id = this.rawId;
3091 }
3092 EventDef.copyVerbatimStandardProps(this, obj);
3093 return obj;
3094 };
3095 EventDef.prototype.applyManualStandardProps = function (rawProps) {
3096 if (rawProps.id != null) {
3097 this.id = EventDef.normalizeId((this.rawId = rawProps.id));
3098 }
3099 else {
3100 this.id = EventDef.generateId();
3101 }
3102 if (rawProps._id != null) { // accept this prop, even tho somewhat internal
3103 this.uid = String(rawProps._id);
3104 }
3105 else {
3106 this.uid = EventDef.generateId();
3107 }
3108 // TODO: converge with EventSource
3109 if ($.isArray(rawProps.className)) {
3110 this.className = rawProps.className;
3111 }
3112 if (typeof rawProps.className === 'string') {
3113 this.className = rawProps.className.split(/\s+/);
3114 }
3115 return true;
3116 };
3117 EventDef.prototype.applyMiscProps = function (rawProps) {
3118 $.extend(this.miscProps, rawProps);
3119 };
3120 EventDef.uuid = 0;
3121 EventDef.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps;
3122 EventDef.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps;
3123 return EventDef;
3124 }());
3125 exports.default = EventDef;
3126 ParsableModelMixin_1.default.mixInto(EventDef);
3127 EventDef.defineStandardProps({
3128 // not automatically assigned (`false`)
3129 _id: false,
3130 id: false,
3131 className: false,
3132 source: false,
3133 // automatically assigned (`true`)
3134 title: true,
3135 url: true,
3136 rendering: true,
3137 constraint: true,
3138 overlap: true,
3139 editable: true,
3140 startEditable: true,
3141 durationEditable: true,
3142 color: true,
3143 backgroundColor: true,
3144 borderColor: true,
3145 textColor: true
3146 });
3147
3148
3149 /***/ }),
3150 /* 38 */
3151 /***/ (function(module, exports) {
3152
3153 Object.defineProperty(exports, "__esModule", { value: true });
3154 exports.default = {
3155 sourceClasses: [],
3156 registerClass: function (EventSourceClass) {
3157 this.sourceClasses.unshift(EventSourceClass); // give highest priority
3158 },
3159 parse: function (rawInput, calendar) {
3160 var sourceClasses = this.sourceClasses;
3161 var i;
3162 var eventSource;
3163 for (i = 0; i < sourceClasses.length; i++) {
3164 eventSource = sourceClasses[i].parse(rawInput, calendar);
3165 if (eventSource) {
3166 return eventSource;
3167 }
3168 }
3169 }
3170 };
3171
3172
3173 /***/ }),
3174 /* 39 */
3175 /***/ (function(module, exports, __webpack_require__) {
3176
3177 Object.defineProperty(exports, "__esModule", { value: true });
3178 var util_1 = __webpack_require__(4);
3179 var EventDateProfile_1 = __webpack_require__(16);
3180 var EventDef_1 = __webpack_require__(37);
3181 var EventDefDateMutation_1 = __webpack_require__(40);
3182 var SingleEventDef_1 = __webpack_require__(9);
3183 var EventDefMutation = /** @class */ (function () {
3184 function EventDefMutation() {
3185 }
3186 EventDefMutation.createFromRawProps = function (eventInstance, rawProps, largeUnit) {
3187 var eventDef = eventInstance.def;
3188 var dateProps = {};
3189 var standardProps = {};
3190 var miscProps = {};
3191 var verbatimStandardProps = {};
3192 var eventDefId = null;
3193 var className = null;
3194 var propName;
3195 var dateProfile;
3196 var dateMutation;
3197 var defMutation;
3198 for (propName in rawProps) {
3199 if (EventDateProfile_1.default.isStandardProp(propName)) {
3200 dateProps[propName] = rawProps[propName];
3201 }
3202 else if (eventDef.isStandardProp(propName)) {
3203 standardProps[propName] = rawProps[propName];
3204 }
3205 else if (eventDef.miscProps[propName] !== rawProps[propName]) { // only if changed
3206 miscProps[propName] = rawProps[propName];
3207 }
3208 }
3209 dateProfile = EventDateProfile_1.default.parse(dateProps, eventDef.source);
3210 if (dateProfile) { // no failure?
3211 dateMutation = EventDefDateMutation_1.default.createFromDiff(eventInstance.dateProfile, dateProfile, largeUnit);
3212 }
3213 if (standardProps.id !== eventDef.id) {
3214 eventDefId = standardProps.id; // only apply if there's a change
3215 }
3216 if (!util_1.isArraysEqual(standardProps.className, eventDef.className)) {
3217 className = standardProps.className; // only apply if there's a change
3218 }
3219 EventDef_1.default.copyVerbatimStandardProps(standardProps, // src
3220 verbatimStandardProps // dest
3221 );
3222 defMutation = new EventDefMutation();
3223 defMutation.eventDefId = eventDefId;
3224 defMutation.className = className;
3225 defMutation.verbatimStandardProps = verbatimStandardProps;
3226 defMutation.miscProps = miscProps;
3227 if (dateMutation) {
3228 defMutation.dateMutation = dateMutation;
3229 }
3230 return defMutation;
3231 };
3232 /*
3233 eventDef assumed to be a SingleEventDef.
3234 returns an undo function.
3235 */
3236 EventDefMutation.prototype.mutateSingle = function (eventDef) {
3237 var origDateProfile;
3238 if (this.dateMutation) {
3239 origDateProfile = eventDef.dateProfile;
3240 eventDef.dateProfile = this.dateMutation.buildNewDateProfile(origDateProfile, eventDef.source.calendar);
3241 }
3242 // can't undo
3243 // TODO: more DRY with EventDef::applyManualStandardProps
3244 if (this.eventDefId != null) {
3245 eventDef.id = EventDef_1.default.normalizeId((eventDef.rawId = this.eventDefId));
3246 }
3247 // can't undo
3248 // TODO: more DRY with EventDef::applyManualStandardProps
3249 if (this.className) {
3250 eventDef.className = this.className;
3251 }
3252 // can't undo
3253 if (this.verbatimStandardProps) {
3254 SingleEventDef_1.default.copyVerbatimStandardProps(this.verbatimStandardProps, // src
3255 eventDef // dest
3256 );
3257 }
3258 // can't undo
3259 if (this.miscProps) {
3260 eventDef.applyMiscProps(this.miscProps);
3261 }
3262 if (origDateProfile) {
3263 return function () {
3264 eventDef.dateProfile = origDateProfile;
3265 };
3266 }
3267 else {
3268 return function () { };
3269 }
3270 };
3271 EventDefMutation.prototype.setDateMutation = function (dateMutation) {
3272 if (dateMutation && !dateMutation.isEmpty()) {
3273 this.dateMutation = dateMutation;
3274 }
3275 else {
3276 this.dateMutation = null;
3277 }
3278 };
3279 EventDefMutation.prototype.isEmpty = function () {
3280 return !this.dateMutation;
3281 };
3282 return EventDefMutation;
3283 }());
3284 exports.default = EventDefMutation;
3285
3286
3287 /***/ }),
3288 /* 40 */
3289 /***/ (function(module, exports, __webpack_require__) {
3290
3291 Object.defineProperty(exports, "__esModule", { value: true });
3292 var util_1 = __webpack_require__(4);
3293 var EventDateProfile_1 = __webpack_require__(16);
3294 var EventDefDateMutation = /** @class */ (function () {
3295 function EventDefDateMutation() {
3296 this.clearEnd = false;
3297 this.forceTimed = false;
3298 this.forceAllDay = false;
3299 }
3300 EventDefDateMutation.createFromDiff = function (dateProfile0, dateProfile1, largeUnit) {
3301 var clearEnd = dateProfile0.end && !dateProfile1.end;
3302 var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay();
3303 var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay();
3304 var dateDelta;
3305 var endDiff;
3306 var endDelta;
3307 var mutation;
3308 // subtracts the dates in the appropriate way, returning a duration
3309 function subtractDates(date1, date0) {
3310 if (largeUnit) {
3311 return util_1.diffByUnit(date1, date0, largeUnit); // poorly named
3312 }
3313 else if (dateProfile1.isAllDay()) {
3314 return util_1.diffDay(date1, date0); // poorly named
3315 }
3316 else {
3317 return util_1.diffDayTime(date1, date0); // poorly named
3318 }
3319 }
3320 dateDelta = subtractDates(dateProfile1.start, dateProfile0.start);
3321 if (dateProfile1.end) {
3322 // use unzonedRanges because dateProfile0.end might be null
3323 endDiff = subtractDates(dateProfile1.unzonedRange.getEnd(), dateProfile0.unzonedRange.getEnd());
3324 endDelta = endDiff.subtract(dateDelta);
3325 }
3326 mutation = new EventDefDateMutation();
3327 mutation.clearEnd = clearEnd;
3328 mutation.forceTimed = forceTimed;
3329 mutation.forceAllDay = forceAllDay;
3330 mutation.setDateDelta(dateDelta);
3331 mutation.setEndDelta(endDelta);
3332 return mutation;
3333 };
3334 /*
3335 returns an undo function.
3336 */
3337 EventDefDateMutation.prototype.buildNewDateProfile = function (eventDateProfile, calendar) {
3338 var start = eventDateProfile.start.clone();
3339 var end = null;
3340 var shouldRezone = false;
3341 if (eventDateProfile.end && !this.clearEnd) {
3342 end = eventDateProfile.end.clone();
3343 }
3344 else if (this.endDelta && !end) {
3345 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
3346 }
3347 if (this.forceTimed) {
3348 shouldRezone = true;
3349 if (!start.hasTime()) {
3350 start.time(0);
3351 }
3352 if (end && !end.hasTime()) {
3353 end.time(0);
3354 }
3355 }
3356 else if (this.forceAllDay) {
3357 if (start.hasTime()) {
3358 start.stripTime();
3359 }
3360 if (end && end.hasTime()) {
3361 end.stripTime();
3362 }
3363 }
3364 if (this.dateDelta) {
3365 shouldRezone = true;
3366 start.add(this.dateDelta);
3367 if (end) {
3368 end.add(this.dateDelta);
3369 }
3370 }
3371 // do this before adding startDelta to start, so we can work off of start
3372 if (this.endDelta) {
3373 shouldRezone = true;
3374 end.add(this.endDelta);
3375 }
3376 if (this.startDelta) {
3377 shouldRezone = true;
3378 start.add(this.startDelta);
3379 }
3380 if (shouldRezone) {
3381 start = calendar.applyTimezone(start);
3382 if (end) {
3383 end = calendar.applyTimezone(end);
3384 }
3385 }
3386 // TODO: okay to access calendar option?
3387 if (!end && calendar.opt('forceEventDuration')) {
3388 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
3389 }
3390 return new EventDateProfile_1.default(start, end, calendar);
3391 };
3392 EventDefDateMutation.prototype.setDateDelta = function (dateDelta) {
3393 if (dateDelta && dateDelta.valueOf()) {
3394 this.dateDelta = dateDelta;
3395 }
3396 else {
3397 this.dateDelta = null;
3398 }
3399 };
3400 EventDefDateMutation.prototype.setStartDelta = function (startDelta) {
3401 if (startDelta && startDelta.valueOf()) {
3402 this.startDelta = startDelta;
3403 }
3404 else {
3405 this.startDelta = null;
3406 }
3407 };
3408 EventDefDateMutation.prototype.setEndDelta = function (endDelta) {
3409 if (endDelta && endDelta.valueOf()) {
3410 this.endDelta = endDelta;
3411 }
3412 else {
3413 this.endDelta = null;
3414 }
3415 };
3416 EventDefDateMutation.prototype.isEmpty = function () {
3417 return !this.clearEnd && !this.forceTimed && !this.forceAllDay &&
3418 !this.dateDelta && !this.startDelta && !this.endDelta;
3419 };
3420 return EventDefDateMutation;
3421 }());
3422 exports.default = EventDefDateMutation;
3423
3424
3425 /***/ }),
3426 /* 41 */
3427 /***/ (function(module, exports, __webpack_require__) {
3428
3429 Object.defineProperty(exports, "__esModule", { value: true });
3430 var tslib_1 = __webpack_require__(2);
3431 var $ = __webpack_require__(3);
3432 var util_1 = __webpack_require__(4);
3433 var Class_1 = __webpack_require__(35);
3434 /*
3435 Embodies a div that has potential scrollbars
3436 */
3437 var Scroller = /** @class */ (function (_super) {
3438 tslib_1.__extends(Scroller, _super);
3439 function Scroller(options) {
3440 var _this = _super.call(this) || this;
3441 options = options || {};
3442 _this.overflowX = options.overflowX || options.overflow || 'auto';
3443 _this.overflowY = options.overflowY || options.overflow || 'auto';
3444 return _this;
3445 }
3446 Scroller.prototype.render = function () {
3447 this.el = this.renderEl();
3448 this.applyOverflow();
3449 };
3450 Scroller.prototype.renderEl = function () {
3451 return (this.scrollEl = $('<div class="fc-scroller"></div>'));
3452 };
3453 // sets to natural height, unlocks overflow
3454 Scroller.prototype.clear = function () {
3455 this.setHeight('auto');
3456 this.applyOverflow();
3457 };
3458 Scroller.prototype.destroy = function () {
3459 this.el.remove();
3460 };
3461 // Overflow
3462 // -----------------------------------------------------------------------------------------------------------------
3463 Scroller.prototype.applyOverflow = function () {
3464 this.scrollEl.css({
3465 'overflow-x': this.overflowX,
3466 'overflow-y': this.overflowY
3467 });
3468 };
3469 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3470 // Useful for preserving scrollbar widths regardless of future resizes.
3471 // Can pass in scrollbarWidths for optimization.
3472 Scroller.prototype.lockOverflow = function (scrollbarWidths) {
3473 var overflowX = this.overflowX;
3474 var overflowY = this.overflowY;
3475 scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3476 if (overflowX === 'auto') {
3477 overflowX = (scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars?
3478 // OR scrolling pane with massless scrollbars?
3479 this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth
3480 // subtract 1 because of IE off-by-one issue
3481 ) ? 'scroll' : 'hidden';
3482 }
3483 if (overflowY === 'auto') {
3484 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars?
3485 // OR scrolling pane with massless scrollbars?
3486 this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight
3487 // subtract 1 because of IE off-by-one issue
3488 ) ? 'scroll' : 'hidden';
3489 }
3490 this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY });
3491 };
3492 // Getters / Setters
3493 // -----------------------------------------------------------------------------------------------------------------
3494 Scroller.prototype.setHeight = function (height) {
3495 this.scrollEl.height(height);
3496 };
3497 Scroller.prototype.getScrollTop = function () {
3498 return this.scrollEl.scrollTop();
3499 };
3500 Scroller.prototype.setScrollTop = function (top) {
3501 this.scrollEl.scrollTop(top);
3502 };
3503 Scroller.prototype.getClientWidth = function () {
3504 return this.scrollEl[0].clientWidth;
3505 };
3506 Scroller.prototype.getClientHeight = function () {
3507 return this.scrollEl[0].clientHeight;
3508 };
3509 Scroller.prototype.getScrollbarWidths = function () {
3510 return util_1.getScrollbarWidths(this.scrollEl);
3511 };
3512 return Scroller;
3513 }(Class_1.default));
3514 exports.default = Scroller;
3515
3516
3517 /***/ }),
3518 /* 42 */
3519 /***/ (function(module, exports, __webpack_require__) {
3520
3521 Object.defineProperty(exports, "__esModule", { value: true });
3522 var tslib_1 = __webpack_require__(2);
3523 var $ = __webpack_require__(3);
3524 var util_1 = __webpack_require__(4);
3525 var DateComponent_1 = __webpack_require__(231);
3526 var GlobalEmitter_1 = __webpack_require__(23);
3527 var InteractiveDateComponent = /** @class */ (function (_super) {
3528 tslib_1.__extends(InteractiveDateComponent, _super);
3529 function InteractiveDateComponent(_view, _options) {
3530 var _this = _super.call(this, _view, _options) || this;
3531 // self-config, overridable by subclasses
3532 _this.segSelector = '.fc-event-container > *'; // what constitutes an event element?
3533 if (_this.dateSelectingClass) {
3534 _this.dateClicking = new _this.dateClickingClass(_this);
3535 }
3536 if (_this.dateSelectingClass) {
3537 _this.dateSelecting = new _this.dateSelectingClass(_this);
3538 }
3539 if (_this.eventPointingClass) {
3540 _this.eventPointing = new _this.eventPointingClass(_this);
3541 }
3542 if (_this.eventDraggingClass && _this.eventPointing) {
3543 _this.eventDragging = new _this.eventDraggingClass(_this, _this.eventPointing);
3544 }
3545 if (_this.eventResizingClass && _this.eventPointing) {
3546 _this.eventResizing = new _this.eventResizingClass(_this, _this.eventPointing);
3547 }
3548 if (_this.externalDroppingClass) {
3549 _this.externalDropping = new _this.externalDroppingClass(_this);
3550 }
3551 return _this;
3552 }
3553 // Sets the container element that the view should render inside of, does global DOM-related initializations,
3554 // and renders all the non-date-related content inside.
3555 InteractiveDateComponent.prototype.setElement = function (el) {
3556 _super.prototype.setElement.call(this, el);
3557 if (this.dateClicking) {
3558 this.dateClicking.bindToEl(el);
3559 }
3560 if (this.dateSelecting) {
3561 this.dateSelecting.bindToEl(el);
3562 }
3563 this.bindAllSegHandlersToEl(el);
3564 };
3565 InteractiveDateComponent.prototype.removeElement = function () {
3566 this.endInteractions();
3567 _super.prototype.removeElement.call(this);
3568 };
3569 InteractiveDateComponent.prototype.executeEventUnrender = function () {
3570 this.endInteractions();
3571 _super.prototype.executeEventUnrender.call(this);
3572 };
3573 InteractiveDateComponent.prototype.bindGlobalHandlers = function () {
3574 _super.prototype.bindGlobalHandlers.call(this);
3575 if (this.externalDropping) {
3576 this.externalDropping.bindToDocument();
3577 }
3578 };
3579 InteractiveDateComponent.prototype.unbindGlobalHandlers = function () {
3580 _super.prototype.unbindGlobalHandlers.call(this);
3581 if (this.externalDropping) {
3582 this.externalDropping.unbindFromDocument();
3583 }
3584 };
3585 InteractiveDateComponent.prototype.bindDateHandlerToEl = function (el, name, handler) {
3586 var _this = this;
3587 // attach a handler to the grid's root element.
3588 // jQuery will take care of unregistering them when removeElement gets called.
3589 this.el.on(name, function (ev) {
3590 if (!$(ev.target).is(_this.segSelector + ':not(.fc-helper),' + // directly on an event element
3591 _this.segSelector + ':not(.fc-helper) *,' + // within an event element
3592 '.fc-more,' + // a "more.." link
3593 'a[data-goto]' // a clickable nav link
3594 )) {
3595 return handler.call(_this, ev);
3596 }
3597 });
3598 };
3599 InteractiveDateComponent.prototype.bindAllSegHandlersToEl = function (el) {
3600 [
3601 this.eventPointing,
3602 this.eventDragging,
3603 this.eventResizing
3604 ].forEach(function (eventInteraction) {
3605 if (eventInteraction) {
3606 eventInteraction.bindToEl(el);
3607 }
3608 });
3609 };
3610 InteractiveDateComponent.prototype.bindSegHandlerToEl = function (el, name, handler) {
3611 var _this = this;
3612 el.on(name, this.segSelector, function (ev) {
3613 var segEl = $(ev.currentTarget);
3614 if (!segEl.is('.fc-helper')) {
3615 var seg = segEl.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload
3616 if (seg && !_this.shouldIgnoreEventPointing()) {
3617 return handler.call(_this, seg, ev); // context will be the Grid
3618 }
3619 }
3620 });
3621 };
3622 InteractiveDateComponent.prototype.shouldIgnoreMouse = function () {
3623 // HACK
3624 // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter.
3625 return GlobalEmitter_1.default.get().shouldIgnoreMouse();
3626 };
3627 InteractiveDateComponent.prototype.shouldIgnoreTouch = function () {
3628 var view = this._getView();
3629 // On iOS (and Android?) when a new selection is initiated overtop another selection,
3630 // the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
3631 // HACK: simply don't allow this to happen.
3632 // ALSO: prevent selection when an *event* is already raised.
3633 return view.isSelected || view.selectedEvent;
3634 };
3635 InteractiveDateComponent.prototype.shouldIgnoreEventPointing = function () {
3636 // only call the handlers if there is not a drag/resize in progress
3637 return (this.eventDragging && this.eventDragging.isDragging) ||
3638 (this.eventResizing && this.eventResizing.isResizing);
3639 };
3640 InteractiveDateComponent.prototype.canStartSelection = function (seg, ev) {
3641 return util_1.getEvIsTouch(ev) &&
3642 !this.canStartResize(seg, ev) &&
3643 (this.isEventDefDraggable(seg.footprint.eventDef) ||
3644 this.isEventDefResizable(seg.footprint.eventDef));
3645 };
3646 InteractiveDateComponent.prototype.canStartDrag = function (seg, ev) {
3647 return !this.canStartResize(seg, ev) &&
3648 this.isEventDefDraggable(seg.footprint.eventDef);
3649 };
3650 InteractiveDateComponent.prototype.canStartResize = function (seg, ev) {
3651 var view = this._getView();
3652 var eventDef = seg.footprint.eventDef;
3653 return (!util_1.getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) &&
3654 this.isEventDefResizable(eventDef) &&
3655 $(ev.target).is('.fc-resizer');
3656 };
3657 // Kills all in-progress dragging.
3658 // Useful for when public API methods that result in re-rendering are invoked during a drag.
3659 // Also useful for when touch devices misbehave and don't fire their touchend.
3660 InteractiveDateComponent.prototype.endInteractions = function () {
3661 [
3662 this.dateClicking,
3663 this.dateSelecting,
3664 this.eventPointing,
3665 this.eventDragging,
3666 this.eventResizing
3667 ].forEach(function (interaction) {
3668 if (interaction) {
3669 interaction.end();
3670 }
3671 });
3672 };
3673 // Event Drag-n-Drop
3674 // ---------------------------------------------------------------------------------------------------------------
3675 // Computes if the given event is allowed to be dragged by the user
3676 InteractiveDateComponent.prototype.isEventDefDraggable = function (eventDef) {
3677 return this.isEventDefStartEditable(eventDef);
3678 };
3679 InteractiveDateComponent.prototype.isEventDefStartEditable = function (eventDef) {
3680 var isEditable = eventDef.isStartExplicitlyEditable();
3681 if (isEditable == null) {
3682 isEditable = this.opt('eventStartEditable');
3683 if (isEditable == null) {
3684 isEditable = this.isEventDefGenerallyEditable(eventDef);
3685 }
3686 }
3687 return isEditable;
3688 };
3689 InteractiveDateComponent.prototype.isEventDefGenerallyEditable = function (eventDef) {
3690 var isEditable = eventDef.isExplicitlyEditable();
3691 if (isEditable == null) {
3692 isEditable = this.opt('editable');
3693 }
3694 return isEditable;
3695 };
3696 // Event Resizing
3697 // ---------------------------------------------------------------------------------------------------------------
3698 // Computes if the given event is allowed to be resized from its starting edge
3699 InteractiveDateComponent.prototype.isEventDefResizableFromStart = function (eventDef) {
3700 return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef);
3701 };
3702 // Computes if the given event is allowed to be resized from its ending edge
3703 InteractiveDateComponent.prototype.isEventDefResizableFromEnd = function (eventDef) {
3704 return this.isEventDefResizable(eventDef);
3705 };
3706 // Computes if the given event is allowed to be resized by the user at all
3707 InteractiveDateComponent.prototype.isEventDefResizable = function (eventDef) {
3708 var isResizable = eventDef.isDurationExplicitlyEditable();
3709 if (isResizable == null) {
3710 isResizable = this.opt('eventDurationEditable');
3711 if (isResizable == null) {
3712 isResizable = this.isEventDefGenerallyEditable(eventDef);
3713 }
3714 }
3715 return isResizable;
3716 };
3717 // Event Mutation / Constraints
3718 // ---------------------------------------------------------------------------------------------------------------
3719 // Diffs the two dates, returning a duration, based on granularity of the grid
3720 // TODO: port isTimeScale into this system?
3721 InteractiveDateComponent.prototype.diffDates = function (a, b) {
3722 if (this.largeUnit) {
3723 return util_1.diffByUnit(a, b, this.largeUnit);
3724 }
3725 else {
3726 return util_1.diffDayTime(a, b);
3727 }
3728 };
3729 // is it allowed, in relation to the view's validRange?
3730 // NOTE: very similar to isExternalInstanceGroupAllowed
3731 InteractiveDateComponent.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) {
3732 var view = this._getView();
3733 var dateProfile = this.dateProfile;
3734 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
3735 var i;
3736 for (i = 0; i < eventFootprints.length; i++) {
3737 // TODO: just use getAllEventRanges directly
3738 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
3739 return false;
3740 }
3741 }
3742 return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup);
3743 };
3744 // NOTE: very similar to isEventInstanceGroupAllowed
3745 // when it's a completely anonymous external drag, no event.
3746 InteractiveDateComponent.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup) {
3747 var view = this._getView();
3748 var dateProfile = this.dateProfile;
3749 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
3750 var i;
3751 for (i = 0; i < eventFootprints.length; i++) {
3752 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
3753 return false;
3754 }
3755 }
3756 for (i = 0; i < eventFootprints.length; i++) {
3757 // treat it as a selection
3758 // TODO: pass in eventInstanceGroup instead
3759 // because we don't want calendar's constraint system to depend on a component's
3760 // determination of footprints.
3761 if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) {
3762 return false;
3763 }
3764 }
3765 return true;
3766 };
3767 return InteractiveDateComponent;
3768 }(DateComponent_1.default));
3769 exports.default = InteractiveDateComponent;
3770
3771
3772 /***/ }),
3773 /* 43 */
3774 /***/ (function(module, exports, __webpack_require__) {
3775
3776 Object.defineProperty(exports, "__esModule", { value: true });
3777 var tslib_1 = __webpack_require__(2);
3778 var $ = __webpack_require__(3);
3779 var moment = __webpack_require__(0);
3780 var util_1 = __webpack_require__(4);
3781 var RenderQueue_1 = __webpack_require__(229);
3782 var DateProfileGenerator_1 = __webpack_require__(55);
3783 var InteractiveDateComponent_1 = __webpack_require__(42);
3784 var GlobalEmitter_1 = __webpack_require__(23);
3785 var UnzonedRange_1 = __webpack_require__(5);
3786 /* An abstract class from which other views inherit from
3787 ----------------------------------------------------------------------------------------------------------------------*/
3788 var View = /** @class */ (function (_super) {
3789 tslib_1.__extends(View, _super);
3790 function View(calendar, viewSpec) {
3791 var _this = _super.call(this, null, viewSpec.options) || this;
3792 _this.batchRenderDepth = 0;
3793 _this.isSelected = false; // boolean whether a range of time is user-selected or not
3794 _this.calendar = calendar;
3795 _this.viewSpec = viewSpec;
3796 // shortcuts
3797 _this.type = viewSpec.type;
3798 // .name is deprecated
3799 _this.name = _this.type;
3800 _this.initRenderQueue();
3801 _this.initHiddenDays();
3802 _this.dateProfileGenerator = new _this.dateProfileGeneratorClass(_this);
3803 _this.bindBaseRenderHandlers();
3804 _this.eventOrderSpecs = util_1.parseFieldSpecs(_this.opt('eventOrder'));
3805 // legacy
3806 if (_this['initialize']) {
3807 _this['initialize']();
3808 }
3809 return _this;
3810 }
3811 View.prototype._getView = function () {
3812 return this;
3813 };
3814 // Retrieves an option with the given name
3815 View.prototype.opt = function (name) {
3816 return this.options[name];
3817 };
3818 /* Render Queue
3819 ------------------------------------------------------------------------------------------------------------------*/
3820 View.prototype.initRenderQueue = function () {
3821 this.renderQueue = new RenderQueue_1.default({
3822 event: this.opt('eventRenderWait')
3823 });
3824 this.renderQueue.on('start', this.onRenderQueueStart.bind(this));
3825 this.renderQueue.on('stop', this.onRenderQueueStop.bind(this));
3826 this.on('before:change', this.startBatchRender);
3827 this.on('change', this.stopBatchRender);
3828 };
3829 View.prototype.onRenderQueueStart = function () {
3830 this.calendar.freezeContentHeight();
3831 this.addScroll(this.queryScroll());
3832 };
3833 View.prototype.onRenderQueueStop = function () {
3834 if (this.calendar.updateViewSize()) { // success?
3835 this.popScroll();
3836 }
3837 this.calendar.thawContentHeight();
3838 };
3839 View.prototype.startBatchRender = function () {
3840 if (!(this.batchRenderDepth++)) {
3841 this.renderQueue.pause();
3842 }
3843 };
3844 View.prototype.stopBatchRender = function () {
3845 if (!(--this.batchRenderDepth)) {
3846 this.renderQueue.resume();
3847 }
3848 };
3849 View.prototype.requestRender = function (func, namespace, actionType) {
3850 this.renderQueue.queue(func, namespace, actionType);
3851 };
3852 // given func will auto-bind to `this`
3853 View.prototype.whenSizeUpdated = function (func) {
3854 if (this.renderQueue.isRunning) {
3855 this.renderQueue.one('stop', func.bind(this));
3856 }
3857 else {
3858 func.call(this);
3859 }
3860 };
3861 /* Title and Date Formatting
3862 ------------------------------------------------------------------------------------------------------------------*/
3863 // Computes what the title at the top of the calendar should be for this view
3864 View.prototype.computeTitle = function (dateProfile) {
3865 var unzonedRange;
3866 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
3867 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
3868 unzonedRange = dateProfile.currentUnzonedRange;
3869 }
3870 else { // for day units or smaller, use the actual day range
3871 unzonedRange = dateProfile.activeUnzonedRange;
3872 }
3873 return this.formatRange({
3874 start: this.calendar.msToMoment(unzonedRange.startMs, dateProfile.isRangeAllDay),
3875 end: this.calendar.msToMoment(unzonedRange.endMs, dateProfile.isRangeAllDay)
3876 }, dateProfile.isRangeAllDay, this.opt('titleFormat') || this.computeTitleFormat(dateProfile), this.opt('titleRangeSeparator'));
3877 };
3878 // Generates the format string that should be used to generate the title for the current date range.
3879 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
3880 View.prototype.computeTitleFormat = function (dateProfile) {
3881 var currentRangeUnit = dateProfile.currentRangeUnit;
3882 if (currentRangeUnit === 'year') {
3883 return 'YYYY';
3884 }
3885 else if (currentRangeUnit === 'month') {
3886 return this.opt('monthYearFormat'); // like "September 2014"
3887 }
3888 else if (dateProfile.currentUnzonedRange.as('days') > 1) {
3889 return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014"
3890 }
3891 else {
3892 return 'LL'; // one day. longer, like "September 9 2014"
3893 }
3894 };
3895 // Date Setting/Unsetting
3896 // -----------------------------------------------------------------------------------------------------------------
3897 View.prototype.setDate = function (date) {
3898 var currentDateProfile = this.get('dateProfile');
3899 var newDateProfile = this.dateProfileGenerator.build(date, undefined, true); // forceToValid=true
3900 if (!currentDateProfile ||
3901 !currentDateProfile.activeUnzonedRange.equals(newDateProfile.activeUnzonedRange)) {
3902 this.set('dateProfile', newDateProfile);
3903 }
3904 };
3905 View.prototype.unsetDate = function () {
3906 this.unset('dateProfile');
3907 };
3908 // Event Data
3909 // -----------------------------------------------------------------------------------------------------------------
3910 View.prototype.fetchInitialEvents = function (dateProfile) {
3911 var calendar = this.calendar;
3912 var forceAllDay = dateProfile.isRangeAllDay && !this.usesMinMaxTime;
3913 return calendar.requestEvents(calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, forceAllDay), calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, forceAllDay));
3914 };
3915 View.prototype.bindEventChanges = function () {
3916 this.listenTo(this.calendar, 'eventsReset', this.resetEvents); // TODO: make this a real event
3917 };
3918 View.prototype.unbindEventChanges = function () {
3919 this.stopListeningTo(this.calendar, 'eventsReset');
3920 };
3921 View.prototype.setEvents = function (eventsPayload) {
3922 this.set('currentEvents', eventsPayload);
3923 this.set('hasEvents', true);
3924 };
3925 View.prototype.unsetEvents = function () {
3926 this.unset('currentEvents');
3927 this.unset('hasEvents');
3928 };
3929 View.prototype.resetEvents = function (eventsPayload) {
3930 this.startBatchRender();
3931 this.unsetEvents();
3932 this.setEvents(eventsPayload);
3933 this.stopBatchRender();
3934 };
3935 // Date High-level Rendering
3936 // -----------------------------------------------------------------------------------------------------------------
3937 View.prototype.requestDateRender = function (dateProfile) {
3938 var _this = this;
3939 this.requestRender(function () {
3940 _this.executeDateRender(dateProfile);
3941 }, 'date', 'init');
3942 };
3943 View.prototype.requestDateUnrender = function () {
3944 var _this = this;
3945 this.requestRender(function () {
3946 _this.executeDateUnrender();
3947 }, 'date', 'destroy');
3948 };
3949 // if dateProfile not specified, uses current
3950 View.prototype.executeDateRender = function (dateProfile) {
3951 _super.prototype.executeDateRender.call(this, dateProfile);
3952 if (this['render']) {
3953 this['render'](); // TODO: deprecate
3954 }
3955 this.trigger('datesRendered');
3956 this.addScroll({ isDateInit: true });
3957 this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon
3958 };
3959 View.prototype.executeDateUnrender = function () {
3960 this.unselect();
3961 this.stopNowIndicator();
3962 this.trigger('before:datesUnrendered');
3963 if (this['destroy']) {
3964 this['destroy'](); // TODO: deprecate
3965 }
3966 _super.prototype.executeDateUnrender.call(this);
3967 };
3968 // "Base" rendering
3969 // -----------------------------------------------------------------------------------------------------------------
3970 View.prototype.bindBaseRenderHandlers = function () {
3971 var _this = this;
3972 this.on('datesRendered', function () {
3973 _this.whenSizeUpdated(_this.triggerViewRender);
3974 });
3975 this.on('before:datesUnrendered', function () {
3976 _this.triggerViewDestroy();
3977 });
3978 };
3979 View.prototype.triggerViewRender = function () {
3980 this.publiclyTrigger('viewRender', {
3981 context: this,
3982 args: [this, this.el]
3983 });
3984 };
3985 View.prototype.triggerViewDestroy = function () {
3986 this.publiclyTrigger('viewDestroy', {
3987 context: this,
3988 args: [this, this.el]
3989 });
3990 };
3991 // Event High-level Rendering
3992 // -----------------------------------------------------------------------------------------------------------------
3993 View.prototype.requestEventsRender = function (eventsPayload) {
3994 var _this = this;
3995 this.requestRender(function () {
3996 _this.executeEventRender(eventsPayload);
3997 _this.whenSizeUpdated(_this.triggerAfterEventsRendered);
3998 }, 'event', 'init');
3999 };
4000 View.prototype.requestEventsUnrender = function () {
4001 var _this = this;
4002 this.requestRender(function () {
4003 _this.triggerBeforeEventsDestroyed();
4004 _this.executeEventUnrender();
4005 }, 'event', 'destroy');
4006 };
4007 // Business Hour High-level Rendering
4008 // -----------------------------------------------------------------------------------------------------------------
4009 View.prototype.requestBusinessHoursRender = function (businessHourGenerator) {
4010 var _this = this;
4011 this.requestRender(function () {
4012 _this.renderBusinessHours(businessHourGenerator);
4013 }, 'businessHours', 'init');
4014 };
4015 View.prototype.requestBusinessHoursUnrender = function () {
4016 var _this = this;
4017 this.requestRender(function () {
4018 _this.unrenderBusinessHours();
4019 }, 'businessHours', 'destroy');
4020 };
4021 // Misc view rendering utils
4022 // -----------------------------------------------------------------------------------------------------------------
4023 // Binds DOM handlers to elements that reside outside the view container, such as the document
4024 View.prototype.bindGlobalHandlers = function () {
4025 _super.prototype.bindGlobalHandlers.call(this);
4026 this.listenTo(GlobalEmitter_1.default.get(), {
4027 touchstart: this.processUnselect,
4028 mousedown: this.handleDocumentMousedown
4029 });
4030 };
4031 // Unbinds DOM handlers from elements that reside outside the view container
4032 View.prototype.unbindGlobalHandlers = function () {
4033 _super.prototype.unbindGlobalHandlers.call(this);
4034 this.stopListeningTo(GlobalEmitter_1.default.get());
4035 };
4036 /* Now Indicator
4037 ------------------------------------------------------------------------------------------------------------------*/
4038 // Immediately render the current time indicator and begins re-rendering it at an interval,
4039 // which is defined by this.getNowIndicatorUnit().
4040 // TODO: somehow do this for the current whole day's background too
4041 View.prototype.startNowIndicator = function () {
4042 var _this = this;
4043 var unit;
4044 var update;
4045 var delay; // ms wait value
4046 if (this.opt('nowIndicator')) {
4047 unit = this.getNowIndicatorUnit();
4048 if (unit) {
4049 update = util_1.proxy(this, 'updateNowIndicator'); // bind to `this`
4050 this.initialNowDate = this.calendar.getNow();
4051 this.initialNowQueriedMs = new Date().valueOf();
4052 // wait until the beginning of the next interval
4053 delay = this.initialNowDate.clone().startOf(unit).add(1, unit).valueOf() - this.initialNowDate.valueOf();
4054 this.nowIndicatorTimeoutID = setTimeout(function () {
4055 _this.nowIndicatorTimeoutID = null;
4056 update();
4057 delay = +moment.duration(1, unit);
4058 delay = Math.max(100, delay); // prevent too frequent
4059 _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
4060 }, delay);
4061 }
4062 // rendering will be initiated in updateSize
4063 }
4064 };
4065 // rerenders the now indicator, computing the new current time from the amount of time that has passed
4066 // since the initial getNow call.
4067 View.prototype.updateNowIndicator = function () {
4068 if (this.isDatesRendered &&
4069 this.initialNowDate // activated before?
4070 ) {
4071 this.unrenderNowIndicator(); // won't unrender if unnecessary
4072 this.renderNowIndicator(this.initialNowDate.clone().add(new Date().valueOf() - this.initialNowQueriedMs) // add ms
4073 );
4074 this.isNowIndicatorRendered = true;
4075 }
4076 };
4077 // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
4078 // Won't cause side effects if indicator isn't rendered.
4079 View.prototype.stopNowIndicator = function () {
4080 if (this.isNowIndicatorRendered) {
4081 if (this.nowIndicatorTimeoutID) {
4082 clearTimeout(this.nowIndicatorTimeoutID);
4083 this.nowIndicatorTimeoutID = null;
4084 }
4085 if (this.nowIndicatorIntervalID) {
4086 clearInterval(this.nowIndicatorIntervalID);
4087 this.nowIndicatorIntervalID = null;
4088 }
4089 this.unrenderNowIndicator();
4090 this.isNowIndicatorRendered = false;
4091 }
4092 };
4093 /* Dimensions
4094 ------------------------------------------------------------------------------------------------------------------*/
4095 View.prototype.updateSize = function (totalHeight, isAuto, isResize) {
4096 if (this['setHeight']) { // for legacy API
4097 this['setHeight'](totalHeight, isAuto);
4098 }
4099 else {
4100 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
4101 }
4102 this.updateNowIndicator();
4103 };
4104 /* Scroller
4105 ------------------------------------------------------------------------------------------------------------------*/
4106 View.prototype.addScroll = function (scroll) {
4107 var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
4108 $.extend(queuedScroll, scroll);
4109 };
4110 View.prototype.popScroll = function () {
4111 this.applyQueuedScroll();
4112 this.queuedScroll = null;
4113 };
4114 View.prototype.applyQueuedScroll = function () {
4115 if (this.queuedScroll) {
4116 this.applyScroll(this.queuedScroll);
4117 }
4118 };
4119 View.prototype.queryScroll = function () {
4120 var scroll = {};
4121 if (this.isDatesRendered) {
4122 $.extend(scroll, this.queryDateScroll());
4123 }
4124 return scroll;
4125 };
4126 View.prototype.applyScroll = function (scroll) {
4127 if (scroll.isDateInit && this.isDatesRendered) {
4128 $.extend(scroll, this.computeInitialDateScroll());
4129 }
4130 if (this.isDatesRendered) {
4131 this.applyDateScroll(scroll);
4132 }
4133 };
4134 View.prototype.computeInitialDateScroll = function () {
4135 return {}; // subclasses must implement
4136 };
4137 View.prototype.queryDateScroll = function () {
4138 return {}; // subclasses must implement
4139 };
4140 View.prototype.applyDateScroll = function (scroll) {
4141 // subclasses must implement
4142 };
4143 /* Event Drag-n-Drop
4144 ------------------------------------------------------------------------------------------------------------------*/
4145 View.prototype.reportEventDrop = function (eventInstance, eventMutation, el, ev) {
4146 var eventManager = this.calendar.eventManager;
4147 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation);
4148 var dateMutation = eventMutation.dateMutation;
4149 // update the EventInstance, for handlers
4150 if (dateMutation) {
4151 eventInstance.dateProfile = dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar);
4152 }
4153 this.triggerEventDrop(eventInstance,
4154 // a drop doesn't necessarily mean a date mutation (ex: resource change)
4155 (dateMutation && dateMutation.dateDelta) || moment.duration(), undoFunc, el, ev);
4156 };
4157 // Triggers event-drop handlers that have subscribed via the API
4158 View.prototype.triggerEventDrop = function (eventInstance, dateDelta, undoFunc, el, ev) {
4159 this.publiclyTrigger('eventDrop', {
4160 context: el[0],
4161 args: [
4162 eventInstance.toLegacy(),
4163 dateDelta,
4164 undoFunc,
4165 ev,
4166 {},
4167 this
4168 ]
4169 });
4170 };
4171 /* External Element Drag-n-Drop
4172 ------------------------------------------------------------------------------------------------------------------*/
4173 // Must be called when an external element, via jQuery UI, has been dropped onto the calendar.
4174 // `meta` is the parsed data that has been embedded into the dragging event.
4175 // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event.
4176 View.prototype.reportExternalDrop = function (singleEventDef, isEvent, isSticky, el, ev, ui) {
4177 if (isEvent) {
4178 this.calendar.eventManager.addEventDef(singleEventDef, isSticky);
4179 }
4180 this.triggerExternalDrop(singleEventDef, isEvent, el, ev, ui);
4181 };
4182 // Triggers external-drop handlers that have subscribed via the API
4183 View.prototype.triggerExternalDrop = function (singleEventDef, isEvent, el, ev, ui) {
4184 // trigger 'drop' regardless of whether element represents an event
4185 this.publiclyTrigger('drop', {
4186 context: el[0],
4187 args: [
4188 singleEventDef.dateProfile.start.clone(),
4189 ev,
4190 ui,
4191 this
4192 ]
4193 });
4194 if (isEvent) {
4195 // signal an external event landed
4196 this.publiclyTrigger('eventReceive', {
4197 context: this,
4198 args: [
4199 singleEventDef.buildInstance().toLegacy(),
4200 this
4201 ]
4202 });
4203 }
4204 };
4205 /* Event Resizing
4206 ------------------------------------------------------------------------------------------------------------------*/
4207 // Must be called when an event in the view has been resized to a new length
4208 View.prototype.reportEventResize = function (eventInstance, eventMutation, el, ev) {
4209 var eventManager = this.calendar.eventManager;
4210 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation);
4211 // update the EventInstance, for handlers
4212 eventInstance.dateProfile = eventMutation.dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar);
4213 var resizeDelta = eventMutation.dateMutation.endDelta || eventMutation.dateMutation.startDelta;
4214 this.triggerEventResize(eventInstance, resizeDelta, undoFunc, el, ev);
4215 };
4216 // Triggers event-resize handlers that have subscribed via the API
4217 View.prototype.triggerEventResize = function (eventInstance, resizeDelta, undoFunc, el, ev) {
4218 this.publiclyTrigger('eventResize', {
4219 context: el[0],
4220 args: [
4221 eventInstance.toLegacy(),
4222 resizeDelta,
4223 undoFunc,
4224 ev,
4225 {},
4226 this
4227 ]
4228 });
4229 };
4230 /* Selection (time range)
4231 ------------------------------------------------------------------------------------------------------------------*/
4232 // Selects a date span on the view. `start` and `end` are both Moments.
4233 // `ev` is the native mouse event that begin the interaction.
4234 View.prototype.select = function (footprint, ev) {
4235 this.unselect(ev);
4236 this.renderSelectionFootprint(footprint);
4237 this.reportSelection(footprint, ev);
4238 };
4239 View.prototype.renderSelectionFootprint = function (footprint) {
4240 if (this['renderSelection']) { // legacy method in custom view classes
4241 this['renderSelection'](footprint.toLegacy(this.calendar));
4242 }
4243 else {
4244 _super.prototype.renderSelectionFootprint.call(this, footprint);
4245 }
4246 };
4247 // Called when a new selection is made. Updates internal state and triggers handlers.
4248 View.prototype.reportSelection = function (footprint, ev) {
4249 this.isSelected = true;
4250 this.triggerSelect(footprint, ev);
4251 };
4252 // Triggers handlers to 'select'
4253 View.prototype.triggerSelect = function (footprint, ev) {
4254 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile?
4255 this.publiclyTrigger('select', {
4256 context: this,
4257 args: [
4258 dateProfile.start,
4259 dateProfile.end,
4260 ev,
4261 this
4262 ]
4263 });
4264 };
4265 // Undoes a selection. updates in the internal state and triggers handlers.
4266 // `ev` is the native mouse event that began the interaction.
4267 View.prototype.unselect = function (ev) {
4268 if (this.isSelected) {
4269 this.isSelected = false;
4270 if (this['destroySelection']) {
4271 this['destroySelection'](); // TODO: deprecate
4272 }
4273 this.unrenderSelection();
4274 this.publiclyTrigger('unselect', {
4275 context: this,
4276 args: [ev, this]
4277 });
4278 }
4279 };
4280 /* Event Selection
4281 ------------------------------------------------------------------------------------------------------------------*/
4282 View.prototype.selectEventInstance = function (eventInstance) {
4283 if (!this.selectedEventInstance ||
4284 this.selectedEventInstance !== eventInstance) {
4285 this.unselectEventInstance();
4286 this.getEventSegs().forEach(function (seg) {
4287 if (seg.footprint.eventInstance === eventInstance &&
4288 seg.el // necessary?
4289 ) {
4290 seg.el.addClass('fc-selected');
4291 }
4292 });
4293 this.selectedEventInstance = eventInstance;
4294 }
4295 };
4296 View.prototype.unselectEventInstance = function () {
4297 if (this.selectedEventInstance) {
4298 this.getEventSegs().forEach(function (seg) {
4299 if (seg.el) { // necessary?
4300 seg.el.removeClass('fc-selected');
4301 }
4302 });
4303 this.selectedEventInstance = null;
4304 }
4305 };
4306 View.prototype.isEventDefSelected = function (eventDef) {
4307 // event references might change on refetchEvents(), while selectedEventInstance doesn't,
4308 // so compare IDs
4309 return this.selectedEventInstance && this.selectedEventInstance.def.id === eventDef.id;
4310 };
4311 /* Mouse / Touch Unselecting (time range & event unselection)
4312 ------------------------------------------------------------------------------------------------------------------*/
4313 // TODO: move consistently to down/start or up/end?
4314 // TODO: don't kill previous selection if touch scrolling
4315 View.prototype.handleDocumentMousedown = function (ev) {
4316 if (util_1.isPrimaryMouseButton(ev)) {
4317 this.processUnselect(ev);
4318 }
4319 };
4320 View.prototype.processUnselect = function (ev) {
4321 this.processRangeUnselect(ev);
4322 this.processEventUnselect(ev);
4323 };
4324 View.prototype.processRangeUnselect = function (ev) {
4325 var ignore;
4326 // is there a time-range selection?
4327 if (this.isSelected && this.opt('unselectAuto')) {
4328 // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element
4329 ignore = this.opt('unselectCancel');
4330 if (!ignore || !$(ev.target).closest(ignore).length) {
4331 this.unselect(ev);
4332 }
4333 }
4334 };
4335 View.prototype.processEventUnselect = function (ev) {
4336 if (this.selectedEventInstance) {
4337 if (!$(ev.target).closest('.fc-selected').length) {
4338 this.unselectEventInstance();
4339 }
4340 }
4341 };
4342 /* Triggers
4343 ------------------------------------------------------------------------------------------------------------------*/
4344 View.prototype.triggerBaseRendered = function () {
4345 this.publiclyTrigger('viewRender', {
4346 context: this,
4347 args: [this, this.el]
4348 });
4349 };
4350 View.prototype.triggerBaseUnrendered = function () {
4351 this.publiclyTrigger('viewDestroy', {
4352 context: this,
4353 args: [this, this.el]
4354 });
4355 };
4356 // Triggers handlers to 'dayClick'
4357 // Span has start/end of the clicked area. Only the start is useful.
4358 View.prototype.triggerDayClick = function (footprint, dayEl, ev) {
4359 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile?
4360 this.publiclyTrigger('dayClick', {
4361 context: dayEl,
4362 args: [dateProfile.start, ev, this]
4363 });
4364 };
4365 /* Date Utils
4366 ------------------------------------------------------------------------------------------------------------------*/
4367 // For DateComponent::getDayClasses
4368 View.prototype.isDateInOtherMonth = function (date, dateProfile) {
4369 return false;
4370 };
4371 // Arguments after name will be forwarded to a hypothetical function value
4372 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
4373 // Always clone your objects if you fear mutation.
4374 View.prototype.getUnzonedRangeOption = function (name) {
4375 var val = this.opt(name);
4376 if (typeof val === 'function') {
4377 val = val.apply(null, Array.prototype.slice.call(arguments, 1));
4378 }
4379 if (val) {
4380 return this.calendar.parseUnzonedRange(val);
4381 }
4382 };
4383 /* Hidden Days
4384 ------------------------------------------------------------------------------------------------------------------*/
4385 // Initializes internal variables related to calculating hidden days-of-week
4386 View.prototype.initHiddenDays = function () {
4387 var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden
4388 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
4389 var dayCnt = 0;
4390 var i;
4391 if (this.opt('weekends') === false) {
4392 hiddenDays.push(0, 6); // 0=sunday, 6=saturday
4393 }
4394 for (i = 0; i < 7; i++) {
4395 if (!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)) {
4396 dayCnt++;
4397 }
4398 }
4399 if (!dayCnt) {
4400 throw new Error('invalid hiddenDays'); // all days were hidden? bad.
4401 }
4402 this.isHiddenDayHash = isHiddenDayHash;
4403 };
4404 // Remove days from the beginning and end of the range that are computed as hidden.
4405 // If the whole range is trimmed off, returns null
4406 View.prototype.trimHiddenDays = function (inputUnzonedRange) {
4407 var start = inputUnzonedRange.getStart();
4408 var end = inputUnzonedRange.getEnd();
4409 if (start) {
4410 start = this.skipHiddenDays(start);
4411 }
4412 if (end) {
4413 end = this.skipHiddenDays(end, -1, true);
4414 }
4415 if (start === null || end === null || start < end) {
4416 return new UnzonedRange_1.default(start, end);
4417 }
4418 return null;
4419 };
4420 // Is the current day hidden?
4421 // `day` is a day-of-week index (0-6), or a Moment
4422 View.prototype.isHiddenDay = function (day) {
4423 if (moment.isMoment(day)) {
4424 day = day.day();
4425 }
4426 return this.isHiddenDayHash[day];
4427 };
4428 // Incrementing the current day until it is no longer a hidden day, returning a copy.
4429 // DOES NOT CONSIDER validUnzonedRange!
4430 // If the initial value of `date` is not a hidden day, don't do anything.
4431 // Pass `isExclusive` as `true` if you are dealing with an end date.
4432 // `inc` defaults to `1` (increment one day forward each time)
4433 View.prototype.skipHiddenDays = function (date, inc, isExclusive) {
4434 if (inc === void 0) { inc = 1; }
4435 if (isExclusive === void 0) { isExclusive = false; }
4436 var out = date.clone();
4437 while (this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]) {
4438 out.add(inc, 'days');
4439 }
4440 return out;
4441 };
4442 return View;
4443 }(InteractiveDateComponent_1.default));
4444 exports.default = View;
4445 View.prototype.usesMinMaxTime = false;
4446 View.prototype.dateProfileGeneratorClass = DateProfileGenerator_1.default;
4447 View.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps) {
4448 this.requestDateRender(deps.dateProfile);
4449 }, function () {
4450 this.requestDateUnrender();
4451 });
4452 View.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps) {
4453 this.requestBusinessHoursRender(deps.businessHourGenerator);
4454 }, function () {
4455 this.requestBusinessHoursUnrender();
4456 });
4457 View.watch('initialEvents', ['dateProfile'], function (deps) {
4458 return this.fetchInitialEvents(deps.dateProfile);
4459 });
4460 View.watch('bindingEvents', ['initialEvents'], function (deps) {
4461 this.setEvents(deps.initialEvents);
4462 this.bindEventChanges();
4463 }, function () {
4464 this.unbindEventChanges();
4465 this.unsetEvents();
4466 });
4467 View.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () {
4468 this.requestEventsRender(this.get('currentEvents'));
4469 }, function () {
4470 this.requestEventsUnrender();
4471 });
4472 View.watch('title', ['dateProfile'], function (deps) {
4473 return (this.title = this.computeTitle(deps.dateProfile)); // assign to View for legacy reasons
4474 });
4475 View.watch('legacyDateProps', ['dateProfile'], function (deps) {
4476 var calendar = this.calendar;
4477 var dateProfile = deps.dateProfile;
4478 // DEPRECATED, but we need to keep it updated...
4479 this.start = calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, dateProfile.isRangeAllDay);
4480 this.end = calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, dateProfile.isRangeAllDay);
4481 this.intervalStart = calendar.msToMoment(dateProfile.currentUnzonedRange.startMs, dateProfile.isRangeAllDay);
4482 this.intervalEnd = calendar.msToMoment(dateProfile.currentUnzonedRange.endMs, dateProfile.isRangeAllDay);
4483 });
4484
4485
4486 /***/ }),
4487 /* 44 */
4488 /***/ (function(module, exports, __webpack_require__) {
4489
4490 Object.defineProperty(exports, "__esModule", { value: true });
4491 var $ = __webpack_require__(3);
4492 var util_1 = __webpack_require__(4);
4493 var EventRenderer = /** @class */ (function () {
4494 function EventRenderer(component, fillRenderer) {
4495 this.view = component._getView();
4496 this.component = component;
4497 this.fillRenderer = fillRenderer;
4498 }
4499 EventRenderer.prototype.opt = function (name) {
4500 return this.view.opt(name);
4501 };
4502 // Updates values that rely on options and also relate to range
4503 EventRenderer.prototype.rangeUpdated = function () {
4504 var displayEventTime;
4505 var displayEventEnd;
4506 this.eventTimeFormat =
4507 this.opt('eventTimeFormat') ||
4508 this.opt('timeFormat') || // deprecated
4509 this.computeEventTimeFormat();
4510 displayEventTime = this.opt('displayEventTime');
4511 if (displayEventTime == null) {
4512 displayEventTime = this.computeDisplayEventTime(); // might be based off of range
4513 }
4514 displayEventEnd = this.opt('displayEventEnd');
4515 if (displayEventEnd == null) {
4516 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
4517 }
4518 this.displayEventTime = displayEventTime;
4519 this.displayEventEnd = displayEventEnd;
4520 };
4521 EventRenderer.prototype.render = function (eventsPayload) {
4522 var dateProfile = this.component._getDateProfile();
4523 var eventDefId;
4524 var instanceGroup;
4525 var eventRanges;
4526 var bgRanges = [];
4527 var fgRanges = [];
4528 for (eventDefId in eventsPayload) {
4529 instanceGroup = eventsPayload[eventDefId];
4530 eventRanges = instanceGroup.sliceRenderRanges(dateProfile.activeUnzonedRange);
4531 if (instanceGroup.getEventDef().hasBgRendering()) {
4532 bgRanges.push.apply(bgRanges, eventRanges);
4533 }
4534 else {
4535 fgRanges.push.apply(fgRanges, eventRanges);
4536 }
4537 }
4538 this.renderBgRanges(bgRanges);
4539 this.renderFgRanges(fgRanges);
4540 };
4541 EventRenderer.prototype.unrender = function () {
4542 this.unrenderBgRanges();
4543 this.unrenderFgRanges();
4544 };
4545 EventRenderer.prototype.renderFgRanges = function (eventRanges) {
4546 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
4547 var segs = this.component.eventFootprintsToSegs(eventFootprints);
4548 // render an `.el` on each seg
4549 // returns a subset of the segs. segs that were actually rendered
4550 segs = this.renderFgSegEls(segs);
4551 if (this.renderFgSegs(segs) !== false) { // no failure?
4552 this.fgSegs = segs;
4553 }
4554 };
4555 EventRenderer.prototype.unrenderFgRanges = function () {
4556 this.unrenderFgSegs(this.fgSegs || []);
4557 this.fgSegs = null;
4558 };
4559 EventRenderer.prototype.renderBgRanges = function (eventRanges) {
4560 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
4561 var segs = this.component.eventFootprintsToSegs(eventFootprints);
4562 if (this.renderBgSegs(segs) !== false) { // no failure?
4563 this.bgSegs = segs;
4564 }
4565 };
4566 EventRenderer.prototype.unrenderBgRanges = function () {
4567 this.unrenderBgSegs();
4568 this.bgSegs = null;
4569 };
4570 EventRenderer.prototype.getSegs = function () {
4571 return (this.bgSegs || []).concat(this.fgSegs || []);
4572 };
4573 // Renders foreground event segments onto the grid
4574 EventRenderer.prototype.renderFgSegs = function (segs) {
4575 // subclasses must implement
4576 // segs already has rendered els, and has been filtered.
4577 return false; // signal failure if not implemented
4578 };
4579 // Unrenders all currently rendered foreground segments
4580 EventRenderer.prototype.unrenderFgSegs = function (segs) {
4581 // subclasses must implement
4582 };
4583 EventRenderer.prototype.renderBgSegs = function (segs) {
4584 var _this = this;
4585 if (this.fillRenderer) {
4586 this.fillRenderer.renderSegs('bgEvent', segs, {
4587 getClasses: function (seg) {
4588 return _this.getBgClasses(seg.footprint.eventDef);
4589 },
4590 getCss: function (seg) {
4591 return {
4592 'background-color': _this.getBgColor(seg.footprint.eventDef)
4593 };
4594 },
4595 filterEl: function (seg, el) {
4596 return _this.filterEventRenderEl(seg.footprint, el);
4597 }
4598 });
4599 }
4600 else {
4601 return false; // signal failure if no fillRenderer
4602 }
4603 };
4604 EventRenderer.prototype.unrenderBgSegs = function () {
4605 if (this.fillRenderer) {
4606 this.fillRenderer.unrender('bgEvent');
4607 }
4608 };
4609 // Renders and assigns an `el` property for each foreground event segment.
4610 // Only returns segments that successfully rendered.
4611 EventRenderer.prototype.renderFgSegEls = function (segs, disableResizing) {
4612 var _this = this;
4613 if (disableResizing === void 0) { disableResizing = false; }
4614 var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender');
4615 var html = '';
4616 var renderedSegs = [];
4617 var i;
4618 if (segs.length) { // don't build an empty html string
4619 // build a large concatenation of event segment HTML
4620 for (i = 0; i < segs.length; i++) {
4621 this.beforeFgSegHtml(segs[i]);
4622 html += this.fgSegHtml(segs[i], disableResizing);
4623 }
4624 // Grab individual elements from the combined HTML string. Use each as the default rendering.
4625 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
4626 $(html).each(function (i, node) {
4627 var seg = segs[i];
4628 var el = $(node);
4629 if (hasEventRenderHandlers) { // optimization
4630 el = _this.filterEventRenderEl(seg.footprint, el);
4631 }
4632 if (el) {
4633 el.data('fc-seg', seg); // used by handlers
4634 seg.el = el;
4635 renderedSegs.push(seg);
4636 }
4637 });
4638 }
4639 return renderedSegs;
4640 };
4641 EventRenderer.prototype.beforeFgSegHtml = function (seg) {
4642 };
4643 // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()
4644 EventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
4645 // subclasses should implement
4646 };
4647 // Generic utility for generating the HTML classNames for an event segment's element
4648 EventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable) {
4649 var classes = [
4650 'fc-event',
4651 seg.isStart ? 'fc-start' : 'fc-not-start',
4652 seg.isEnd ? 'fc-end' : 'fc-not-end'
4653 ].concat(this.getClasses(seg.footprint.eventDef));
4654 if (isDraggable) {
4655 classes.push('fc-draggable');
4656 }
4657 if (isResizable) {
4658 classes.push('fc-resizable');
4659 }
4660 // event is currently selected? attach a className.
4661 if (this.view.isEventDefSelected(seg.footprint.eventDef)) {
4662 classes.push('fc-selected');
4663 }
4664 return classes;
4665 };
4666 // Given an event and the default element used for rendering, returns the element that should actually be used.
4667 // Basically runs events and elements through the eventRender hook.
4668 EventRenderer.prototype.filterEventRenderEl = function (eventFootprint, el) {
4669 var legacy = eventFootprint.getEventLegacy();
4670 var custom = this.view.publiclyTrigger('eventRender', {
4671 context: legacy,
4672 args: [legacy, el, this.view]
4673 });
4674 if (custom === false) { // means don't render at all
4675 el = null;
4676 }
4677 else if (custom && custom !== true) {
4678 el = $(custom);
4679 }
4680 return el;
4681 };
4682 // Compute the text that should be displayed on an event's element.
4683 // `range` can be the Event object itself, or something range-like, with at least a `start`.
4684 // If event times are disabled, or the event has no time, will return a blank string.
4685 // If not specified, formatStr will default to the eventTimeFormat setting,
4686 // and displayEnd will default to the displayEventEnd setting.
4687 EventRenderer.prototype.getTimeText = function (eventFootprint, formatStr, displayEnd) {
4688 return this._getTimeText(eventFootprint.eventInstance.dateProfile.start, eventFootprint.eventInstance.dateProfile.end, eventFootprint.componentFootprint.isAllDay, formatStr, displayEnd);
4689 };
4690 EventRenderer.prototype._getTimeText = function (start, end, isAllDay, formatStr, displayEnd) {
4691 if (formatStr == null) {
4692 formatStr = this.eventTimeFormat;
4693 }
4694 if (displayEnd == null) {
4695 displayEnd = this.displayEventEnd;
4696 }
4697 if (this.displayEventTime && !isAllDay) {
4698 if (displayEnd && end) {
4699 return this.view.formatRange({ start: start, end: end }, false, // allDay
4700 formatStr);
4701 }
4702 else {
4703 return start.format(formatStr);
4704 }
4705 }
4706 return '';
4707 };
4708 EventRenderer.prototype.computeEventTimeFormat = function () {
4709 return this.opt('smallTimeFormat');
4710 };
4711 EventRenderer.prototype.computeDisplayEventTime = function () {
4712 return true;
4713 };
4714 EventRenderer.prototype.computeDisplayEventEnd = function () {
4715 return true;
4716 };
4717 EventRenderer.prototype.getBgClasses = function (eventDef) {
4718 var classNames = this.getClasses(eventDef);
4719 classNames.push('fc-bgevent');
4720 return classNames;
4721 };
4722 EventRenderer.prototype.getClasses = function (eventDef) {
4723 var objs = this.getStylingObjs(eventDef);
4724 var i;
4725 var classNames = [];
4726 for (i = 0; i < objs.length; i++) {
4727 classNames.push.apply(// append
4728 classNames, objs[i].eventClassName || objs[i].className || []);
4729 }
4730 return classNames;
4731 };
4732 // Utility for generating event skin-related CSS properties
4733 EventRenderer.prototype.getSkinCss = function (eventDef) {
4734 return {
4735 'background-color': this.getBgColor(eventDef),
4736 'border-color': this.getBorderColor(eventDef),
4737 color: this.getTextColor(eventDef)
4738 };
4739 };
4740 // Queries for caller-specified color, then falls back to default
4741 EventRenderer.prototype.getBgColor = function (eventDef) {
4742 var objs = this.getStylingObjs(eventDef);
4743 var i;
4744 var val;
4745 for (i = 0; i < objs.length && !val; i++) {
4746 val = objs[i].eventBackgroundColor || objs[i].eventColor ||
4747 objs[i].backgroundColor || objs[i].color;
4748 }
4749 if (!val) {
4750 val = this.opt('eventBackgroundColor') || this.opt('eventColor');
4751 }
4752 return val;
4753 };
4754 // Queries for caller-specified color, then falls back to default
4755 EventRenderer.prototype.getBorderColor = function (eventDef) {
4756 var objs = this.getStylingObjs(eventDef);
4757 var i;
4758 var val;
4759 for (i = 0; i < objs.length && !val; i++) {
4760 val = objs[i].eventBorderColor || objs[i].eventColor ||
4761 objs[i].borderColor || objs[i].color;
4762 }
4763 if (!val) {
4764 val = this.opt('eventBorderColor') || this.opt('eventColor');
4765 }
4766 return val;
4767 };
4768 // Queries for caller-specified color, then falls back to default
4769 EventRenderer.prototype.getTextColor = function (eventDef) {
4770 var objs = this.getStylingObjs(eventDef);
4771 var i;
4772 var val;
4773 for (i = 0; i < objs.length && !val; i++) {
4774 val = objs[i].eventTextColor ||
4775 objs[i].textColor;
4776 }
4777 if (!val) {
4778 val = this.opt('eventTextColor');
4779 }
4780 return val;
4781 };
4782 EventRenderer.prototype.getStylingObjs = function (eventDef) {
4783 var objs = this.getFallbackStylingObjs(eventDef);
4784 objs.unshift(eventDef);
4785 return objs;
4786 };
4787 EventRenderer.prototype.getFallbackStylingObjs = function (eventDef) {
4788 return [eventDef.source];
4789 };
4790 EventRenderer.prototype.sortEventSegs = function (segs) {
4791 segs.sort(util_1.proxy(this, 'compareEventSegs'));
4792 };
4793 // A cmp function for determining which segments should take visual priority
4794 EventRenderer.prototype.compareEventSegs = function (seg1, seg2) {
4795 var f1 = seg1.footprint;
4796 var f2 = seg2.footprint;
4797 var cf1 = f1.componentFootprint;
4798 var cf2 = f2.componentFootprint;
4799 var r1 = cf1.unzonedRange;
4800 var r2 = cf2.unzonedRange;
4801 return r1.startMs - r2.startMs || // earlier events go first
4802 (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first
4803 cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1)
4804 util_1.compareByFieldSpecs(f1.eventDef, f2.eventDef, this.view.eventOrderSpecs, f1.eventDef.miscProps, f2.eventDef.miscProps);
4805 };
4806 return EventRenderer;
4807 }());
4808 exports.default = EventRenderer;
4809
4810
4811 /***/ }),
4812 /* 45 */,
4813 /* 46 */,
4814 /* 47 */,
4815 /* 48 */,
4816 /* 49 */
4817 /***/ (function(module, exports, __webpack_require__) {
4818
4819 Object.defineProperty(exports, "__esModule", { value: true });
4820 var moment_ext_1 = __webpack_require__(11);
4821 // Plugin
4822 // -------------------------------------------------------------------------------------------------
4823 moment_ext_1.newMomentProto.format = function () {
4824 if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?
4825 return formatDate(this, arguments[0]); // our extended formatting
4826 }
4827 if (this._ambigTime) {
4828 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4829 }
4830 if (this._ambigZone) {
4831 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4832 }
4833 if (this._fullCalendar) { // enhanced non-ambig moment?
4834 // moment.format() doesn't ensure english, but we want to.
4835 return moment_ext_1.oldMomentFormat(englishMoment(this));
4836 }
4837 return moment_ext_1.oldMomentProto.format.apply(this, arguments);
4838 };
4839 moment_ext_1.newMomentProto.toISOString = function () {
4840 if (this._ambigTime) {
4841 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4842 }
4843 if (this._ambigZone) {
4844 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4845 }
4846 if (this._fullCalendar) { // enhanced non-ambig moment?
4847 // depending on browser, moment might not output english. ensure english.
4848 // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22
4849 return moment_ext_1.oldMomentProto.toISOString.apply(englishMoment(this), arguments);
4850 }
4851 return moment_ext_1.oldMomentProto.toISOString.apply(this, arguments);
4852 };
4853 function englishMoment(mom) {
4854 if (mom.locale() !== 'en') {
4855 return mom.clone().locale('en');
4856 }
4857 return mom;
4858 }
4859 // Config
4860 // ---------------------------------------------------------------------------------------------------------------------
4861 /*
4862 Inserted between chunks in the fake ("intermediate") formatting string.
4863 Important that it passes as whitespace (\s) because moment often identifies non-standalone months
4864 via a regexp with an \s.
4865 */
4866 var PART_SEPARATOR = '\u000b'; // vertical tab
4867 /*
4868 Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text,
4869 but rather, a "special" token that has custom rendering (see specialTokens map).
4870 */
4871 var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1
4872 /*
4873 Inserted at the beginning and end of a span of text that must have non-zero numeric characters.
4874 Handling of these markers is done in a post-processing step at the very end of text rendering.
4875 */
4876 var MAYBE_MARKER = '\u001e'; // information separator 2
4877 var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global
4878 /*
4879 Addition formatting tokens we want recognized
4880 */
4881 var specialTokens = {
4882 t: function (date) {
4883 return moment_ext_1.oldMomentFormat(date, 'a').charAt(0);
4884 },
4885 T: function (date) {
4886 return moment_ext_1.oldMomentFormat(date, 'A').charAt(0);
4887 }
4888 };
4889 /*
4890 The first characters of formatting tokens for units that are 1 day or larger.
4891 `value` is for ranking relative size (lower means bigger).
4892 `unit` is a normalized unit, used for comparing moments.
4893 */
4894 var largeTokenMap = {
4895 Y: { value: 1, unit: 'year' },
4896 M: { value: 2, unit: 'month' },
4897 W: { value: 3, unit: 'week' },
4898 w: { value: 3, unit: 'week' },
4899 D: { value: 4, unit: 'day' },
4900 d: { value: 4, unit: 'day' } // day of week
4901 };
4902 // Single Date Formatting
4903 // ---------------------------------------------------------------------------------------------------------------------
4904 /*
4905 Formats `date` with a Moment formatting string, but allow our non-zero areas and special token
4906 */
4907 function formatDate(date, formatStr) {
4908 return renderFakeFormatString(getParsedFormatString(formatStr).fakeFormatString, date);
4909 }
4910 exports.formatDate = formatDate;
4911 // Date Range Formatting
4912 // -------------------------------------------------------------------------------------------------
4913 // TODO: make it work with timezone offset
4914 /*
4915 Using a formatting string meant for a single date, generate a range string, like
4916 "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
4917 If the dates are the same as far as the format string is concerned, just return a single
4918 rendering of one date, without any separator.
4919 */
4920 function formatRange(date1, date2, formatStr, separator, isRTL) {
4921 var localeData;
4922 date1 = moment_ext_1.default.parseZone(date1);
4923 date2 = moment_ext_1.default.parseZone(date2);
4924 localeData = date1.localeData();
4925 // Expand localized format strings, like "LL" -> "MMMM D YYYY".
4926 // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
4927 // or non-zero areas in Moment's localized format strings.
4928 formatStr = localeData.longDateFormat(formatStr) || formatStr;
4929 return renderParsedFormat(getParsedFormatString(formatStr), date1, date2, separator || ' - ', isRTL);
4930 }
4931 exports.formatRange = formatRange;
4932 /*
4933 Renders a range with an already-parsed format string.
4934 */
4935 function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
4936 var sameUnits = parsedFormat.sameUnits;
4937 var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons
4938 var unzonedDate2 = date2.clone().stripZone(); // "
4939 var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1);
4940 var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2);
4941 var leftI;
4942 var leftStr = '';
4943 var rightI;
4944 var rightStr = '';
4945 var middleI;
4946 var middleStr1 = '';
4947 var middleStr2 = '';
4948 var middleStr = '';
4949 // Start at the leftmost side of the formatting string and continue until you hit a token
4950 // that is not the same between dates.
4951 for (leftI = 0; leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI])); leftI++) {
4952 leftStr += renderedParts1[leftI];
4953 }
4954 // Similarly, start at the rightmost side of the formatting string and move left
4955 for (rightI = sameUnits.length - 1; rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI])); rightI--) {
4956 // If current chunk is on the boundary of unique date-content, and is a special-case
4957 // date-formatting postfix character, then don't consume it. Consider it unique date-content.
4958 // TODO: make configurable
4959 if (rightI - 1 === leftI && renderedParts1[rightI] === '.') {
4960 break;
4961 }
4962 rightStr = renderedParts1[rightI] + rightStr;
4963 }
4964 // The area in the middle is different for both of the dates.
4965 // Collect them distinctly so we can jam them together later.
4966 for (middleI = leftI; middleI <= rightI; middleI++) {
4967 middleStr1 += renderedParts1[middleI];
4968 middleStr2 += renderedParts2[middleI];
4969 }
4970 if (middleStr1 || middleStr2) {
4971 if (isRTL) {
4972 middleStr = middleStr2 + separator + middleStr1;
4973 }
4974 else {
4975 middleStr = middleStr1 + separator + middleStr2;
4976 }
4977 }
4978 return processMaybeMarkers(leftStr + middleStr + rightStr);
4979 }
4980 // Format String Parsing
4981 // ---------------------------------------------------------------------------------------------------------------------
4982 var parsedFormatStrCache = {};
4983 /*
4984 Returns a parsed format string, leveraging a cache.
4985 */
4986 function getParsedFormatString(formatStr) {
4987 return parsedFormatStrCache[formatStr] ||
4988 (parsedFormatStrCache[formatStr] = parseFormatString(formatStr));
4989 }
4990 /*
4991 Parses a format string into the following:
4992 - fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed.
4993 - sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"),
4994 that indicates how similar a range's start & end must be in order to share the same formatted text.
4995 If not a token, then the value is null.
4996 Always a flat array (not nested liked "chunks").
4997 */
4998 function parseFormatString(formatStr) {
4999 var chunks = chunkFormatString(formatStr);
5000 return {
5001 fakeFormatString: buildFakeFormatString(chunks),
5002 sameUnits: buildSameUnits(chunks)
5003 };
5004 }
5005 /*
5006 Break the formatting string into an array of chunks.
5007 A 'maybe' chunk will have nested chunks.
5008 */
5009 function chunkFormatString(formatStr) {
5010 var chunks = [];
5011 var match;
5012 // TODO: more descrimination
5013 // \4 is a backreference to the first character of a multi-character set.
5014 var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;
5015 while ((match = chunker.exec(formatStr))) {
5016 if (match[1]) { // a literal string inside [ ... ]
5017 chunks.push.apply(chunks, // append
5018 splitStringLiteral(match[1]));
5019 }
5020 else if (match[2]) { // non-zero formatting inside ( ... )
5021 chunks.push({ maybe: chunkFormatString(match[2]) });
5022 }
5023 else if (match[3]) { // a formatting token
5024 chunks.push({ token: match[3] });
5025 }
5026 else if (match[5]) { // an unenclosed literal string
5027 chunks.push.apply(chunks, // append
5028 splitStringLiteral(match[5]));
5029 }
5030 }
5031 return chunks;
5032 }
5033 /*
5034 Potentially splits a literal-text string into multiple parts. For special cases.
5035 */
5036 function splitStringLiteral(s) {
5037 if (s === '. ') {
5038 return ['.', ' ']; // for locales with periods bound to the end of each year/month/date
5039 }
5040 else {
5041 return [s];
5042 }
5043 }
5044 /*
5045 Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control
5046 characters that will eventually be given to moment for formatting, and then post-processed.
5047 */
5048 function buildFakeFormatString(chunks) {
5049 var parts = [];
5050 var i;
5051 var chunk;
5052 for (i = 0; i < chunks.length; i++) {
5053 chunk = chunks[i];
5054 if (typeof chunk === 'string') {
5055 parts.push('[' + chunk + ']');
5056 }
5057 else if (chunk.token) {
5058 if (chunk.token in specialTokens) {
5059 parts.push(SPECIAL_TOKEN_MARKER + // useful during post-processing
5060 '[' + chunk.token + ']' // preserve as literal text
5061 );
5062 }
5063 else {
5064 parts.push(chunk.token); // unprotected text implies a format string
5065 }
5066 }
5067 else if (chunk.maybe) {
5068 parts.push(MAYBE_MARKER + // useful during post-processing
5069 buildFakeFormatString(chunk.maybe) +
5070 MAYBE_MARKER);
5071 }
5072 }
5073 return parts.join(PART_SEPARATOR);
5074 }
5075 /*
5076 Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate
5077 in which regard two dates must be similar in order to share range formatting text.
5078 The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat.
5079 */
5080 function buildSameUnits(chunks) {
5081 var units = [];
5082 var i;
5083 var chunk;
5084 var tokenInfo;
5085 for (i = 0; i < chunks.length; i++) {
5086 chunk = chunks[i];
5087 if (chunk.token) {
5088 tokenInfo = largeTokenMap[chunk.token.charAt(0)];
5089 units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second
5090 }
5091 else if (chunk.maybe) {
5092 units.push.apply(units, // append
5093 buildSameUnits(chunk.maybe));
5094 }
5095 else {
5096 units.push(null);
5097 }
5098 }
5099 return units;
5100 }
5101 // Rendering to text
5102 // ---------------------------------------------------------------------------------------------------------------------
5103 /*
5104 Formats a date with a fake format string, post-processes the control characters, then returns.
5105 */
5106 function renderFakeFormatString(fakeFormatString, date) {
5107 return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString, date).join(''));
5108 }
5109 /*
5110 Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers.
5111 */
5112 function renderFakeFormatStringParts(fakeFormatString, date) {
5113 var parts = [];
5114 var fakeRender = moment_ext_1.oldMomentFormat(date, fakeFormatString);
5115 var fakeParts = fakeRender.split(PART_SEPARATOR);
5116 var i;
5117 var fakePart;
5118 for (i = 0; i < fakeParts.length; i++) {
5119 fakePart = fakeParts[i];
5120 if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) {
5121 parts.push(
5122 // the literal string IS the token's name.
5123 // call special token's registered function.
5124 specialTokens[fakePart.substring(1)](date));
5125 }
5126 else {
5127 parts.push(fakePart);
5128 }
5129 }
5130 return parts;
5131 }
5132 /*
5133 Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string.
5134 */
5135 function processMaybeMarkers(s) {
5136 return s.replace(MAYBE_REGEXP, function (m0, m1) {
5137 if (m1.match(/[1-9]/)) { // any non-zero numeric characters?
5138 return m1;
5139 }
5140 else {
5141 return '';
5142 }
5143 });
5144 }
5145 // Misc Utils
5146 // -------------------------------------------------------------------------------------------------
5147 /*
5148 Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string.
5149 */
5150 function queryMostGranularFormatUnit(formatStr) {
5151 var chunks = chunkFormatString(formatStr);
5152 var i;
5153 var chunk;
5154 var candidate;
5155 var best;
5156 for (i = 0; i < chunks.length; i++) {
5157 chunk = chunks[i];
5158 if (chunk.token) {
5159 candidate = largeTokenMap[chunk.token.charAt(0)];
5160 if (candidate) {
5161 if (!best || candidate.value > best.value) {
5162 best = candidate;
5163 }
5164 }
5165 }
5166 }
5167 if (best) {
5168 return best.unit;
5169 }
5170 return null;
5171 }
5172 exports.queryMostGranularFormatUnit = queryMostGranularFormatUnit;
5173
5174
5175 /***/ }),
5176 /* 50 */
5177 /***/ (function(module, exports) {
5178
5179 Object.defineProperty(exports, "__esModule", { value: true });
5180 var EventRange = /** @class */ (function () {
5181 function EventRange(unzonedRange, eventDef, eventInstance) {
5182 this.unzonedRange = unzonedRange;
5183 this.eventDef = eventDef;
5184 if (eventInstance) {
5185 this.eventInstance = eventInstance;
5186 }
5187 }
5188 return EventRange;
5189 }());
5190 exports.default = EventRange;
5191
5192
5193 /***/ }),
5194 /* 51 */
5195 /***/ (function(module, exports, __webpack_require__) {
5196
5197 Object.defineProperty(exports, "__esModule", { value: true });
5198 var tslib_1 = __webpack_require__(2);
5199 var Class_1 = __webpack_require__(35);
5200 var EmitterMixin_1 = __webpack_require__(13);
5201 var ListenerMixin_1 = __webpack_require__(7);
5202 var Model = /** @class */ (function (_super) {
5203 tslib_1.__extends(Model, _super);
5204 function Model() {
5205 var _this = _super.call(this) || this;
5206 _this._watchers = {};
5207 _this._props = {};
5208 _this.applyGlobalWatchers();
5209 _this.constructed();
5210 return _this;
5211 }
5212 Model.watch = function (name) {
5213 var args = [];
5214 for (var _i = 1; _i < arguments.length; _i++) {
5215 args[_i - 1] = arguments[_i];
5216 }
5217 // subclasses should make a masked-copy of the superclass's map
5218 // TODO: write test
5219 if (!this.prototype.hasOwnProperty('_globalWatchArgs')) {
5220 this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs);
5221 }
5222 this.prototype._globalWatchArgs[name] = args;
5223 };
5224 Model.prototype.constructed = function () {
5225 // useful for monkeypatching. TODO: BaseClass?
5226 };
5227 Model.prototype.applyGlobalWatchers = function () {
5228 var map = this._globalWatchArgs;
5229 var name;
5230 for (name in map) {
5231 this.watch.apply(this, [name].concat(map[name]));
5232 }
5233 };
5234 Model.prototype.has = function (name) {
5235 return name in this._props;
5236 };
5237 Model.prototype.get = function (name) {
5238 if (name === undefined) {
5239 return this._props;
5240 }
5241 return this._props[name];
5242 };
5243 Model.prototype.set = function (name, val) {
5244 var newProps;
5245 if (typeof name === 'string') {
5246 newProps = {};
5247 newProps[name] = val === undefined ? null : val;
5248 }
5249 else {
5250 newProps = name;
5251 }
5252 this.setProps(newProps);
5253 };
5254 Model.prototype.reset = function (newProps) {
5255 var oldProps = this._props;
5256 var changeset = {}; // will have undefined's to signal unsets
5257 var name;
5258 for (name in oldProps) {
5259 changeset[name] = undefined;
5260 }
5261 for (name in newProps) {
5262 changeset[name] = newProps[name];
5263 }
5264 this.setProps(changeset);
5265 };
5266 Model.prototype.unset = function (name) {
5267 var newProps = {};
5268 var names;
5269 var i;
5270 if (typeof name === 'string') {
5271 names = [name];
5272 }
5273 else {
5274 names = name;
5275 }
5276 for (i = 0; i < names.length; i++) {
5277 newProps[names[i]] = undefined;
5278 }
5279 this.setProps(newProps);
5280 };
5281 Model.prototype.setProps = function (newProps) {
5282 var changedProps = {};
5283 var changedCnt = 0;
5284 var name;
5285 var val;
5286 for (name in newProps) {
5287 val = newProps[name];
5288 // a change in value?
5289 // if an object, don't check equality, because might have been mutated internally.
5290 // TODO: eventually enforce immutability.
5291 if (typeof val === 'object' ||
5292 val !== this._props[name]) {
5293 changedProps[name] = val;
5294 changedCnt++;
5295 }
5296 }
5297 if (changedCnt) {
5298 this.trigger('before:batchChange', changedProps);
5299 for (name in changedProps) {
5300 val = changedProps[name];
5301 this.trigger('before:change', name, val);
5302 this.trigger('before:change:' + name, val);
5303 }
5304 for (name in changedProps) {
5305 val = changedProps[name];
5306 if (val === undefined) {
5307 delete this._props[name];
5308 }
5309 else {
5310 this._props[name] = val;
5311 }
5312 this.trigger('change:' + name, val);
5313 this.trigger('change', name, val);
5314 }
5315 this.trigger('batchChange', changedProps);
5316 }
5317 };
5318 Model.prototype.watch = function (name, depList, startFunc, stopFunc) {
5319 var _this = this;
5320 this.unwatch(name);
5321 this._watchers[name] = this._watchDeps(depList, function (deps) {
5322 var res = startFunc.call(_this, deps);
5323 if (res && res.then) {
5324 _this.unset(name); // put in an unset state while resolving
5325 res.then(function (val) {
5326 _this.set(name, val);
5327 });
5328 }
5329 else {
5330 _this.set(name, res);
5331 }
5332 }, function (deps) {
5333 _this.unset(name);
5334 if (stopFunc) {
5335 stopFunc.call(_this, deps);
5336 }
5337 });
5338 };
5339 Model.prototype.unwatch = function (name) {
5340 var watcher = this._watchers[name];
5341 if (watcher) {
5342 delete this._watchers[name];
5343 watcher.teardown();
5344 }
5345 };
5346 Model.prototype._watchDeps = function (depList, startFunc, stopFunc) {
5347 var _this = this;
5348 var queuedChangeCnt = 0;
5349 var depCnt = depList.length;
5350 var satisfyCnt = 0;
5351 var values = {}; // what's passed as the `deps` arguments
5352 var bindTuples = []; // array of [ eventName, handlerFunc ] arrays
5353 var isCallingStop = false;
5354 var onBeforeDepChange = function (depName, val, isOptional) {
5355 queuedChangeCnt++;
5356 if (queuedChangeCnt === 1) { // first change to cause a "stop" ?
5357 if (satisfyCnt === depCnt) { // all deps previously satisfied?
5358 isCallingStop = true;
5359 stopFunc(values);
5360 isCallingStop = false;
5361 }
5362 }
5363 };
5364 var onDepChange = function (depName, val, isOptional) {
5365 if (val === undefined) { // unsetting a value?
5366 // required dependency that was previously set?
5367 if (!isOptional && values[depName] !== undefined) {
5368 satisfyCnt--;
5369 }
5370 delete values[depName];
5371 }
5372 else { // setting a value?
5373 // required dependency that was previously unset?
5374 if (!isOptional && values[depName] === undefined) {
5375 satisfyCnt++;
5376 }
5377 values[depName] = val;
5378 }
5379 queuedChangeCnt--;
5380 if (!queuedChangeCnt) { // last change to cause a "start"?
5381 // now finally satisfied or satisfied all along?
5382 if (satisfyCnt === depCnt) {
5383 // if the stopFunc initiated another value change, ignore it.
5384 // it will be processed by another change event anyway.
5385 if (!isCallingStop) {
5386 startFunc(values);
5387 }
5388 }
5389 }
5390 };
5391 // intercept for .on() that remembers handlers
5392 var bind = function (eventName, handler) {
5393 _this.on(eventName, handler);
5394 bindTuples.push([eventName, handler]);
5395 };
5396 // listen to dependency changes
5397 depList.forEach(function (depName) {
5398 var isOptional = false;
5399 if (depName.charAt(0) === '?') { // TODO: more DRY
5400 depName = depName.substring(1);
5401 isOptional = true;
5402 }
5403 bind('before:change:' + depName, function (val) {
5404 onBeforeDepChange(depName, val, isOptional);
5405 });
5406 bind('change:' + depName, function (val) {
5407 onDepChange(depName, val, isOptional);
5408 });
5409 });
5410 // process current dependency values
5411 depList.forEach(function (depName) {
5412 var isOptional = false;
5413 if (depName.charAt(0) === '?') { // TODO: more DRY
5414 depName = depName.substring(1);
5415 isOptional = true;
5416 }
5417 if (_this.has(depName)) {
5418 values[depName] = _this.get(depName);
5419 satisfyCnt++;
5420 }
5421 else if (isOptional) {
5422 satisfyCnt++;
5423 }
5424 });
5425 // initially satisfied
5426 if (satisfyCnt === depCnt) {
5427 startFunc(values);
5428 }
5429 return {
5430 teardown: function () {
5431 // remove all handlers
5432 for (var i = 0; i < bindTuples.length; i++) {
5433 _this.off(bindTuples[i][0], bindTuples[i][1]);
5434 }
5435 bindTuples = null;
5436 // was satisfied, so call stopFunc
5437 if (satisfyCnt === depCnt) {
5438 stopFunc();
5439 }
5440 },
5441 flash: function () {
5442 if (satisfyCnt === depCnt) {
5443 stopFunc();
5444 startFunc(values);
5445 }
5446 }
5447 };
5448 };
5449 Model.prototype.flash = function (name) {
5450 var watcher = this._watchers[name];
5451 if (watcher) {
5452 watcher.flash();
5453 }
5454 };
5455 return Model;
5456 }(Class_1.default));
5457 exports.default = Model;
5458 Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch
5459 EmitterMixin_1.default.mixInto(Model);
5460 ListenerMixin_1.default.mixInto(Model);
5461
5462
5463 /***/ }),
5464 /* 52 */
5465 /***/ (function(module, exports, __webpack_require__) {
5466
5467 /*
5468 USAGE:
5469 import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin'
5470 in class:
5471 applyProps: ParsableModelInterface['applyProps']
5472 applyManualStandardProps: ParsableModelInterface['applyManualStandardProps']
5473 applyMiscProps: ParsableModelInterface['applyMiscProps']
5474 isStandardProp: ParsableModelInterface['isStandardProp']
5475 static defineStandardProps = ParsableModelMixin.defineStandardProps
5476 static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps
5477 after class:
5478 ParsableModelMixin.mixInto(TheClass)
5479 */
5480 Object.defineProperty(exports, "__esModule", { value: true });
5481 var tslib_1 = __webpack_require__(2);
5482 var util_1 = __webpack_require__(4);
5483 var Mixin_1 = __webpack_require__(15);
5484 var ParsableModelMixin = /** @class */ (function (_super) {
5485 tslib_1.__extends(ParsableModelMixin, _super);
5486 function ParsableModelMixin() {
5487 return _super !== null && _super.apply(this, arguments) || this;
5488 }
5489 ParsableModelMixin.defineStandardProps = function (propDefs) {
5490 var proto = this.prototype;
5491 if (!proto.hasOwnProperty('standardPropMap')) {
5492 proto.standardPropMap = Object.create(proto.standardPropMap);
5493 }
5494 util_1.copyOwnProps(propDefs, proto.standardPropMap);
5495 };
5496 ParsableModelMixin.copyVerbatimStandardProps = function (src, dest) {
5497 var map = this.prototype.standardPropMap;
5498 var propName;
5499 for (propName in map) {
5500 if (src[propName] != null && // in the src object?
5501 map[propName] === true // false means "copy verbatim"
5502 ) {
5503 dest[propName] = src[propName];
5504 }
5505 }
5506 };
5507 /*
5508 Returns true/false for success.
5509 Meant to be only called ONCE, at object creation.
5510 */
5511 ParsableModelMixin.prototype.applyProps = function (rawProps) {
5512 var standardPropMap = this.standardPropMap;
5513 var manualProps = {};
5514 var miscProps = {};
5515 var propName;
5516 for (propName in rawProps) {
5517 if (standardPropMap[propName] === true) { // copy verbatim
5518 this[propName] = rawProps[propName];
5519 }
5520 else if (standardPropMap[propName] === false) {
5521 manualProps[propName] = rawProps[propName];
5522 }
5523 else {
5524 miscProps[propName] = rawProps[propName];
5525 }
5526 }
5527 this.applyMiscProps(miscProps);
5528 return this.applyManualStandardProps(manualProps);
5529 };
5530 /*
5531 If subclasses override, they must call this supermethod and return the boolean response.
5532 Meant to be only called ONCE, at object creation.
5533 */
5534 ParsableModelMixin.prototype.applyManualStandardProps = function (rawProps) {
5535 return true;
5536 };
5537 /*
5538 Can be called even after initial object creation.
5539 */
5540 ParsableModelMixin.prototype.applyMiscProps = function (rawProps) {
5541 // subclasses can implement
5542 };
5543 /*
5544 TODO: why is this a method when defineStandardProps is static
5545 */
5546 ParsableModelMixin.prototype.isStandardProp = function (propName) {
5547 return propName in this.standardPropMap;
5548 };
5549 return ParsableModelMixin;
5550 }(Mixin_1.default));
5551 exports.default = ParsableModelMixin;
5552 ParsableModelMixin.prototype.standardPropMap = {}; // will be cloned by defineStandardProps
5553
5554
5555 /***/ }),
5556 /* 53 */
5557 /***/ (function(module, exports) {
5558
5559 Object.defineProperty(exports, "__esModule", { value: true });
5560 var EventInstance = /** @class */ (function () {
5561 function EventInstance(def, dateProfile) {
5562 this.def = def;
5563 this.dateProfile = dateProfile;
5564 }
5565 EventInstance.prototype.toLegacy = function () {
5566 var dateProfile = this.dateProfile;
5567 var obj = this.def.toLegacy();
5568 obj.start = dateProfile.start.clone();
5569 obj.end = dateProfile.end ? dateProfile.end.clone() : null;
5570 return obj;
5571 };
5572 return EventInstance;
5573 }());
5574 exports.default = EventInstance;
5575
5576
5577 /***/ }),
5578 /* 54 */
5579 /***/ (function(module, exports, __webpack_require__) {
5580
5581 Object.defineProperty(exports, "__esModule", { value: true });
5582 var tslib_1 = __webpack_require__(2);
5583 var $ = __webpack_require__(3);
5584 var moment = __webpack_require__(0);
5585 var EventDef_1 = __webpack_require__(37);
5586 var EventInstance_1 = __webpack_require__(53);
5587 var EventDateProfile_1 = __webpack_require__(16);
5588 var RecurringEventDef = /** @class */ (function (_super) {
5589 tslib_1.__extends(RecurringEventDef, _super);
5590 function RecurringEventDef() {
5591 return _super !== null && _super.apply(this, arguments) || this;
5592 }
5593 RecurringEventDef.prototype.isAllDay = function () {
5594 return !this.startTime && !this.endTime;
5595 };
5596 RecurringEventDef.prototype.buildInstances = function (unzonedRange) {
5597 var calendar = this.source.calendar;
5598 var unzonedDate = unzonedRange.getStart();
5599 var unzonedEnd = unzonedRange.getEnd();
5600 var zonedDayStart;
5601 var instanceStart;
5602 var instanceEnd;
5603 var instances = [];
5604 while (unzonedDate.isBefore(unzonedEnd)) {
5605 // if everyday, or this particular day-of-week
5606 if (!this.dowHash || this.dowHash[unzonedDate.day()]) {
5607 zonedDayStart = calendar.applyTimezone(unzonedDate);
5608 instanceStart = zonedDayStart.clone();
5609 instanceEnd = null;
5610 if (this.startTime) {
5611 instanceStart.time(this.startTime);
5612 }
5613 else {
5614 instanceStart.stripTime();
5615 }
5616 if (this.endTime) {
5617 instanceEnd = zonedDayStart.clone().time(this.endTime);
5618 }
5619 instances.push(new EventInstance_1.default(this, // definition
5620 new EventDateProfile_1.default(instanceStart, instanceEnd, calendar)));
5621 }
5622 unzonedDate.add(1, 'days');
5623 }
5624 return instances;
5625 };
5626 RecurringEventDef.prototype.setDow = function (dowNumbers) {
5627 if (!this.dowHash) {
5628 this.dowHash = {};
5629 }
5630 for (var i = 0; i < dowNumbers.length; i++) {
5631 this.dowHash[dowNumbers[i]] = true;
5632 }
5633 };
5634 RecurringEventDef.prototype.clone = function () {
5635 var def = _super.prototype.clone.call(this);
5636 if (def.startTime) {
5637 def.startTime = moment.duration(this.startTime);
5638 }
5639 if (def.endTime) {
5640 def.endTime = moment.duration(this.endTime);
5641 }
5642 if (this.dowHash) {
5643 def.dowHash = $.extend({}, this.dowHash);
5644 }
5645 return def;
5646 };
5647 return RecurringEventDef;
5648 }(EventDef_1.default));
5649 exports.default = RecurringEventDef;
5650 /*
5651 HACK to work with TypeScript mixins
5652 NOTE: if super-method fails, should still attempt to apply
5653 */
5654 RecurringEventDef.prototype.applyProps = function (rawProps) {
5655 var superSuccess = EventDef_1.default.prototype.applyProps.call(this, rawProps);
5656 if (rawProps.start) {
5657 this.startTime = moment.duration(rawProps.start);
5658 }
5659 if (rawProps.end) {
5660 this.endTime = moment.duration(rawProps.end);
5661 }
5662 if (rawProps.dow) {
5663 this.setDow(rawProps.dow);
5664 }
5665 return superSuccess;
5666 };
5667 // Parsing
5668 // ---------------------------------------------------------------------------------------------------------------------
5669 RecurringEventDef.defineStandardProps({
5670 start: false,
5671 end: false,
5672 dow: false
5673 });
5674
5675
5676 /***/ }),
5677 /* 55 */
5678 /***/ (function(module, exports, __webpack_require__) {
5679
5680 Object.defineProperty(exports, "__esModule", { value: true });
5681 var moment = __webpack_require__(0);
5682 var util_1 = __webpack_require__(4);
5683 var UnzonedRange_1 = __webpack_require__(5);
5684 var DateProfileGenerator = /** @class */ (function () {
5685 function DateProfileGenerator(_view) {
5686 this._view = _view;
5687 }
5688 DateProfileGenerator.prototype.opt = function (name) {
5689 return this._view.opt(name);
5690 };
5691 DateProfileGenerator.prototype.trimHiddenDays = function (unzonedRange) {
5692 return this._view.trimHiddenDays(unzonedRange);
5693 };
5694 DateProfileGenerator.prototype.msToUtcMoment = function (ms, forceAllDay) {
5695 return this._view.calendar.msToUtcMoment(ms, forceAllDay);
5696 };
5697 /* Date Range Computation
5698 ------------------------------------------------------------------------------------------------------------------*/
5699 // Builds a structure with info about what the dates/ranges will be for the "prev" view.
5700 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile) {
5701 var prevDate = currentDateProfile.date.clone()
5702 .startOf(currentDateProfile.currentRangeUnit)
5703 .subtract(currentDateProfile.dateIncrement);
5704 return this.build(prevDate, -1);
5705 };
5706 // Builds a structure with info about what the dates/ranges will be for the "next" view.
5707 DateProfileGenerator.prototype.buildNext = function (currentDateProfile) {
5708 var nextDate = currentDateProfile.date.clone()
5709 .startOf(currentDateProfile.currentRangeUnit)
5710 .add(currentDateProfile.dateIncrement);
5711 return this.build(nextDate, 1);
5712 };
5713 // Builds a structure holding dates/ranges for rendering around the given date.
5714 // Optional direction param indicates whether the date is being incremented/decremented
5715 // from its previous value. decremented = -1, incremented = 1 (default).
5716 DateProfileGenerator.prototype.build = function (date, direction, forceToValid) {
5717 if (forceToValid === void 0) { forceToValid = false; }
5718 var isDateAllDay = !date.hasTime();
5719 var validUnzonedRange;
5720 var minTime = null;
5721 var maxTime = null;
5722 var currentInfo;
5723 var isRangeAllDay;
5724 var renderUnzonedRange;
5725 var activeUnzonedRange;
5726 var isValid;
5727 validUnzonedRange = this.buildValidRange();
5728 validUnzonedRange = this.trimHiddenDays(validUnzonedRange);
5729 if (forceToValid) {
5730 date = this.msToUtcMoment(validUnzonedRange.constrainDate(date), // returns MS
5731 isDateAllDay);
5732 }
5733 currentInfo = this.buildCurrentRangeInfo(date, direction);
5734 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
5735 renderUnzonedRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.unzonedRange), currentInfo.unit, isRangeAllDay);
5736 renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange);
5737 activeUnzonedRange = renderUnzonedRange.clone();
5738 if (!this.opt('showNonCurrentDates')) {
5739 activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange);
5740 }
5741 minTime = moment.duration(this.opt('minTime'));
5742 maxTime = moment.duration(this.opt('maxTime'));
5743 activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime);
5744 activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null
5745 if (activeUnzonedRange) {
5746 date = this.msToUtcMoment(activeUnzonedRange.constrainDate(date), // returns MS
5747 isDateAllDay);
5748 }
5749 // it's invalid if the originally requested date is not contained,
5750 // or if the range is completely outside of the valid range.
5751 isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange);
5752 return {
5753 // constraint for where prev/next operations can go and where events can be dragged/resized to.
5754 // an object with optional start and end properties.
5755 validUnzonedRange: validUnzonedRange,
5756 // range the view is formally responsible for.
5757 // for example, a month view might have 1st-31st, excluding padded dates
5758 currentUnzonedRange: currentInfo.unzonedRange,
5759 // name of largest unit being displayed, like "month" or "week"
5760 currentRangeUnit: currentInfo.unit,
5761 isRangeAllDay: isRangeAllDay,
5762 // dates that display events and accept drag-n-drop
5763 // will be `null` if no dates accept events
5764 activeUnzonedRange: activeUnzonedRange,
5765 // date range with a rendered skeleton
5766 // includes not-active days that need some sort of DOM
5767 renderUnzonedRange: renderUnzonedRange,
5768 // Duration object that denotes the first visible time of any given day
5769 minTime: minTime,
5770 // Duration object that denotes the exclusive visible end time of any given day
5771 maxTime: maxTime,
5772 isValid: isValid,
5773 date: date,
5774 // how far the current date will move for a prev/next operation
5775 dateIncrement: this.buildDateIncrement(currentInfo.duration)
5776 // pass a fallback (might be null) ^
5777 };
5778 };
5779 // Builds an object with optional start/end properties.
5780 // Indicates the minimum/maximum dates to display.
5781 // not responsible for trimming hidden days.
5782 DateProfileGenerator.prototype.buildValidRange = function () {
5783 return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) ||
5784 new UnzonedRange_1.default(); // completely open-ended
5785 };
5786 // Builds a structure with info about the "current" range, the range that is
5787 // highlighted as being the current month for example.
5788 // See build() for a description of `direction`.
5789 // Guaranteed to have `range` and `unit` properties. `duration` is optional.
5790 // TODO: accept a MS-time instead of a moment `date`?
5791 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
5792 var viewSpec = this._view.viewSpec;
5793 var duration = null;
5794 var unit = null;
5795 var unzonedRange = null;
5796 var dayCount;
5797 if (viewSpec.duration) {
5798 duration = viewSpec.duration;
5799 unit = viewSpec.durationUnit;
5800 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
5801 }
5802 else if ((dayCount = this.opt('dayCount'))) {
5803 unit = 'day';
5804 unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount);
5805 }
5806 else if ((unzonedRange = this.buildCustomVisibleRange(date))) {
5807 unit = util_1.computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd());
5808 }
5809 else {
5810 duration = this.getFallbackDuration();
5811 unit = util_1.computeGreatestUnit(duration);
5812 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
5813 }
5814 return { duration: duration, unit: unit, unzonedRange: unzonedRange };
5815 };
5816 DateProfileGenerator.prototype.getFallbackDuration = function () {
5817 return moment.duration({ days: 1 });
5818 };
5819 // Returns a new activeUnzonedRange to have time values (un-ambiguate)
5820 // minTime or maxTime causes the range to expand.
5821 DateProfileGenerator.prototype.adjustActiveRange = function (unzonedRange, minTime, maxTime) {
5822 var start = unzonedRange.getStart();
5823 var end = unzonedRange.getEnd();
5824 if (this._view.usesMinMaxTime) {
5825 if (minTime < 0) {
5826 start.time(0).add(minTime);
5827 }
5828 if (maxTime > 24 * 60 * 60 * 1000) { // beyond 24 hours?
5829 end.time(maxTime - (24 * 60 * 60 * 1000));
5830 }
5831 }
5832 return new UnzonedRange_1.default(start, end);
5833 };
5834 // Builds the "current" range when it is specified as an explicit duration.
5835 // `unit` is the already-computed computeGreatestUnit value of duration.
5836 // TODO: accept a MS-time instead of a moment `date`?
5837 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
5838 var alignment = this.opt('dateAlignment');
5839 var dateIncrementInput;
5840 var dateIncrementDuration;
5841 var start;
5842 var end;
5843 var res;
5844 // compute what the alignment should be
5845 if (!alignment) {
5846 dateIncrementInput = this.opt('dateIncrement');
5847 if (dateIncrementInput) {
5848 dateIncrementDuration = moment.duration(dateIncrementInput);
5849 // use the smaller of the two units
5850 if (dateIncrementDuration < duration) {
5851 alignment = util_1.computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput);
5852 }
5853 else {
5854 alignment = unit;
5855 }
5856 }
5857 else {
5858 alignment = unit;
5859 }
5860 }
5861 // if the view displays a single day or smaller
5862 if (duration.as('days') <= 1) {
5863 if (this._view.isHiddenDay(start)) {
5864 start = this._view.skipHiddenDays(start, direction);
5865 start.startOf('day');
5866 }
5867 }
5868 function computeRes() {
5869 start = date.clone().startOf(alignment);
5870 end = start.clone().add(duration);
5871 res = new UnzonedRange_1.default(start, end);
5872 }
5873 computeRes();
5874 // if range is completely enveloped by hidden days, go past the hidden days
5875 if (!this.trimHiddenDays(res)) {
5876 date = this._view.skipHiddenDays(date, direction);
5877 computeRes();
5878 }
5879 return res;
5880 };
5881 // Builds the "current" range when a dayCount is specified.
5882 // TODO: accept a MS-time instead of a moment `date`?
5883 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
5884 var customAlignment = this.opt('dateAlignment');
5885 var runningCount = 0;
5886 var start;
5887 var end;
5888 if (customAlignment || direction !== -1) {
5889 start = date.clone();
5890 if (customAlignment) {
5891 start.startOf(customAlignment);
5892 }
5893 start.startOf('day');
5894 start = this._view.skipHiddenDays(start);
5895 end = start.clone();
5896 do {
5897 end.add(1, 'day');
5898 if (!this._view.isHiddenDay(end)) {
5899 runningCount++;
5900 }
5901 } while (runningCount < dayCount);
5902 }
5903 else {
5904 end = date.clone().startOf('day').add(1, 'day');
5905 end = this._view.skipHiddenDays(end, -1, true);
5906 start = end.clone();
5907 do {
5908 start.add(-1, 'day');
5909 if (!this._view.isHiddenDay(start)) {
5910 runningCount++;
5911 }
5912 } while (runningCount < dayCount);
5913 }
5914 return new UnzonedRange_1.default(start, end);
5915 };
5916 // Builds a normalized range object for the "visible" range,
5917 // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time.
5918 // TODO: accept a MS-time instead of a moment `date`?
5919 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
5920 var visibleUnzonedRange = this._view.getUnzonedRangeOption('visibleRange', this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations
5921 );
5922 if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) {
5923 return null;
5924 }
5925 return visibleUnzonedRange;
5926 };
5927 // Computes the range that will represent the element/cells for *rendering*,
5928 // but which may have voided days/times.
5929 // not responsible for trimming hidden days.
5930 DateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
5931 return currentUnzonedRange.clone();
5932 };
5933 // Compute the duration value that should be added/substracted to the current date
5934 // when a prev/next operation happens.
5935 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
5936 var dateIncrementInput = this.opt('dateIncrement');
5937 var customAlignment;
5938 if (dateIncrementInput) {
5939 return moment.duration(dateIncrementInput);
5940 }
5941 else if ((customAlignment = this.opt('dateAlignment'))) {
5942 return moment.duration(1, customAlignment);
5943 }
5944 else if (fallback) {
5945 return fallback;
5946 }
5947 else {
5948 return moment.duration({ days: 1 });
5949 }
5950 };
5951 return DateProfileGenerator;
5952 }());
5953 exports.default = DateProfileGenerator;
5954
5955
5956 /***/ }),
5957 /* 56 */
5958 /***/ (function(module, exports, __webpack_require__) {
5959
5960 Object.defineProperty(exports, "__esModule", { value: true });
5961 var tslib_1 = __webpack_require__(2);
5962 var $ = __webpack_require__(3);
5963 var util_1 = __webpack_require__(4);
5964 var Promise_1 = __webpack_require__(21);
5965 var EventSource_1 = __webpack_require__(6);
5966 var SingleEventDef_1 = __webpack_require__(9);
5967 var ArrayEventSource = /** @class */ (function (_super) {
5968 tslib_1.__extends(ArrayEventSource, _super);
5969 function ArrayEventSource(calendar) {
5970 var _this = _super.call(this, calendar) || this;
5971 _this.eventDefs = []; // for if setRawEventDefs is never called
5972 return _this;
5973 }
5974 ArrayEventSource.parse = function (rawInput, calendar) {
5975 var rawProps;
5976 // normalize raw input
5977 if ($.isArray(rawInput.events)) { // extended form
5978 rawProps = rawInput;
5979 }
5980 else if ($.isArray(rawInput)) { // short form
5981 rawProps = { events: rawInput };
5982 }
5983 if (rawProps) {
5984 return EventSource_1.default.parse.call(this, rawProps, calendar);
5985 }
5986 return false;
5987 };
5988 ArrayEventSource.prototype.setRawEventDefs = function (rawEventDefs) {
5989 this.rawEventDefs = rawEventDefs;
5990 this.eventDefs = this.parseEventDefs(rawEventDefs);
5991 };
5992 ArrayEventSource.prototype.fetch = function (start, end, timezone) {
5993 var eventDefs = this.eventDefs;
5994 var i;
5995 if (this.currentTimezone != null &&
5996 this.currentTimezone !== timezone) {
5997 for (i = 0; i < eventDefs.length; i++) {
5998 if (eventDefs[i] instanceof SingleEventDef_1.default) {
5999 eventDefs[i].rezone();
6000 }
6001 }
6002 }
6003 this.currentTimezone = timezone;
6004 return Promise_1.default.resolve(eventDefs);
6005 };
6006 ArrayEventSource.prototype.addEventDef = function (eventDef) {
6007 this.eventDefs.push(eventDef);
6008 };
6009 /*
6010 eventDefId already normalized to a string
6011 */
6012 ArrayEventSource.prototype.removeEventDefsById = function (eventDefId) {
6013 return util_1.removeMatching(this.eventDefs, function (eventDef) {
6014 return eventDef.id === eventDefId;
6015 });
6016 };
6017 ArrayEventSource.prototype.removeAllEventDefs = function () {
6018 this.eventDefs = [];
6019 };
6020 ArrayEventSource.prototype.getPrimitive = function () {
6021 return this.rawEventDefs;
6022 };
6023 ArrayEventSource.prototype.applyManualStandardProps = function (rawProps) {
6024 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
6025 this.setRawEventDefs(rawProps.events);
6026 return superSuccess;
6027 };
6028 return ArrayEventSource;
6029 }(EventSource_1.default));
6030 exports.default = ArrayEventSource;
6031 ArrayEventSource.defineStandardProps({
6032 events: false // don't automatically transfer
6033 });
6034
6035
6036 /***/ }),
6037 /* 57 */
6038 /***/ (function(module, exports, __webpack_require__) {
6039
6040 Object.defineProperty(exports, "__esModule", { value: true });
6041 var StandardTheme_1 = __webpack_require__(221);
6042 var JqueryUiTheme_1 = __webpack_require__(222);
6043 var themeClassHash = {};
6044 function defineThemeSystem(themeName, themeClass) {
6045 themeClassHash[themeName] = themeClass;
6046 }
6047 exports.defineThemeSystem = defineThemeSystem;
6048 function getThemeSystemClass(themeSetting) {
6049 if (!themeSetting) {
6050 return StandardTheme_1.default;
6051 }
6052 else if (themeSetting === true) {
6053 return JqueryUiTheme_1.default;
6054 }
6055 else {
6056 return themeClassHash[themeSetting];
6057 }
6058 }
6059 exports.getThemeSystemClass = getThemeSystemClass;
6060
6061
6062 /***/ }),
6063 /* 58 */
6064 /***/ (function(module, exports, __webpack_require__) {
6065
6066 Object.defineProperty(exports, "__esModule", { value: true });
6067 var $ = __webpack_require__(3);
6068 var util_1 = __webpack_require__(4);
6069 /*
6070 A cache for the left/right/top/bottom/width/height values for one or more elements.
6071 Works with both offset (from topleft document) and position (from offsetParent).
6072
6073 options:
6074 - els
6075 - isHorizontal
6076 - isVertical
6077 */
6078 var CoordCache = /** @class */ (function () {
6079 function CoordCache(options) {
6080 this.isHorizontal = false; // whether to query for left/right/width
6081 this.isVertical = false; // whether to query for top/bottom/height
6082 this.els = $(options.els);
6083 this.isHorizontal = options.isHorizontal;
6084 this.isVertical = options.isVertical;
6085 this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null;
6086 }
6087 // Queries the els for coordinates and stores them.
6088 // Call this method before using and of the get* methods below.
6089 CoordCache.prototype.build = function () {
6090 var offsetParentEl = this.forcedOffsetParentEl;
6091 if (!offsetParentEl && this.els.length > 0) {
6092 offsetParentEl = this.els.eq(0).offsetParent();
6093 }
6094 this.origin = offsetParentEl ?
6095 offsetParentEl.offset() :
6096 null;
6097 this.boundingRect = this.queryBoundingRect();
6098 if (this.isHorizontal) {
6099 this.buildElHorizontals();
6100 }
6101 if (this.isVertical) {
6102 this.buildElVerticals();
6103 }
6104 };
6105 // Destroys all internal data about coordinates, freeing memory
6106 CoordCache.prototype.clear = function () {
6107 this.origin = null;
6108 this.boundingRect = null;
6109 this.lefts = null;
6110 this.rights = null;
6111 this.tops = null;
6112 this.bottoms = null;
6113 };
6114 // When called, if coord caches aren't built, builds them
6115 CoordCache.prototype.ensureBuilt = function () {
6116 if (!this.origin) {
6117 this.build();
6118 }
6119 };
6120 // Populates the left/right internal coordinate arrays
6121 CoordCache.prototype.buildElHorizontals = function () {
6122 var lefts = [];
6123 var rights = [];
6124 this.els.each(function (i, node) {
6125 var el = $(node);
6126 var left = el.offset().left;
6127 var width = el.outerWidth();
6128 lefts.push(left);
6129 rights.push(left + width);
6130 });
6131 this.lefts = lefts;
6132 this.rights = rights;
6133 };
6134 // Populates the top/bottom internal coordinate arrays
6135 CoordCache.prototype.buildElVerticals = function () {
6136 var tops = [];
6137 var bottoms = [];
6138 this.els.each(function (i, node) {
6139 var el = $(node);
6140 var top = el.offset().top;
6141 var height = el.outerHeight();
6142 tops.push(top);
6143 bottoms.push(top + height);
6144 });
6145 this.tops = tops;
6146 this.bottoms = bottoms;
6147 };
6148 // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
6149 // If no intersection is made, returns undefined.
6150 CoordCache.prototype.getHorizontalIndex = function (leftOffset) {
6151 this.ensureBuilt();
6152 var lefts = this.lefts;
6153 var rights = this.rights;
6154 var len = lefts.length;
6155 var i;
6156 for (i = 0; i < len; i++) {
6157 if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
6158 return i;
6159 }
6160 }
6161 };
6162 // Given a top offset (from document top), returns the index of the el that it vertically intersects.
6163 // If no intersection is made, returns undefined.
6164 CoordCache.prototype.getVerticalIndex = function (topOffset) {
6165 this.ensureBuilt();
6166 var tops = this.tops;
6167 var bottoms = this.bottoms;
6168 var len = tops.length;
6169 var i;
6170 for (i = 0; i < len; i++) {
6171 if (topOffset >= tops[i] && topOffset < bottoms[i]) {
6172 return i;
6173 }
6174 }
6175 };
6176 // Gets the left offset (from document left) of the element at the given index
6177 CoordCache.prototype.getLeftOffset = function (leftIndex) {
6178 this.ensureBuilt();
6179 return this.lefts[leftIndex];
6180 };
6181 // Gets the left position (from offsetParent left) of the element at the given index
6182 CoordCache.prototype.getLeftPosition = function (leftIndex) {
6183 this.ensureBuilt();
6184 return this.lefts[leftIndex] - this.origin.left;
6185 };
6186 // Gets the right offset (from document left) of the element at the given index.
6187 // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be.
6188 CoordCache.prototype.getRightOffset = function (leftIndex) {
6189 this.ensureBuilt();
6190 return this.rights[leftIndex];
6191 };
6192 // Gets the right position (from offsetParent left) of the element at the given index.
6193 // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be.
6194 CoordCache.prototype.getRightPosition = function (leftIndex) {
6195 this.ensureBuilt();
6196 return this.rights[leftIndex] - this.origin.left;
6197 };
6198 // Gets the width of the element at the given index
6199 CoordCache.prototype.getWidth = function (leftIndex) {
6200 this.ensureBuilt();
6201 return this.rights[leftIndex] - this.lefts[leftIndex];
6202 };
6203 // Gets the top offset (from document top) of the element at the given index
6204 CoordCache.prototype.getTopOffset = function (topIndex) {
6205 this.ensureBuilt();
6206 return this.tops[topIndex];
6207 };
6208 // Gets the top position (from offsetParent top) of the element at the given position
6209 CoordCache.prototype.getTopPosition = function (topIndex) {
6210 this.ensureBuilt();
6211 return this.tops[topIndex] - this.origin.top;
6212 };
6213 // Gets the bottom offset (from the document top) of the element at the given index.
6214 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
6215 CoordCache.prototype.getBottomOffset = function (topIndex) {
6216 this.ensureBuilt();
6217 return this.bottoms[topIndex];
6218 };
6219 // Gets the bottom position (from the offsetParent top) of the element at the given index.
6220 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
6221 CoordCache.prototype.getBottomPosition = function (topIndex) {
6222 this.ensureBuilt();
6223 return this.bottoms[topIndex] - this.origin.top;
6224 };
6225 // Gets the height of the element at the given index
6226 CoordCache.prototype.getHeight = function (topIndex) {
6227 this.ensureBuilt();
6228 return this.bottoms[topIndex] - this.tops[topIndex];
6229 };
6230 // Bounding Rect
6231 // TODO: decouple this from CoordCache
6232 // Compute and return what the elements' bounding rectangle is, from the user's perspective.
6233 // Right now, only returns a rectangle if constrained by an overflow:scroll element.
6234 // Returns null if there are no elements
6235 CoordCache.prototype.queryBoundingRect = function () {
6236 var scrollParentEl;
6237 if (this.els.length > 0) {
6238 scrollParentEl = util_1.getScrollParent(this.els.eq(0));
6239 if (!scrollParentEl.is(document) &&
6240 !scrollParentEl.is('html,body') // don't consider these bounding rects. solves issue 3615
6241 ) {
6242 return util_1.getClientRect(scrollParentEl);
6243 }
6244 }
6245 return null;
6246 };
6247 CoordCache.prototype.isPointInBounds = function (leftOffset, topOffset) {
6248 return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset);
6249 };
6250 CoordCache.prototype.isLeftInBounds = function (leftOffset) {
6251 return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right);
6252 };
6253 CoordCache.prototype.isTopInBounds = function (topOffset) {
6254 return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom);
6255 };
6256 return CoordCache;
6257 }());
6258 exports.default = CoordCache;
6259
6260
6261 /***/ }),
6262 /* 59 */
6263 /***/ (function(module, exports, __webpack_require__) {
6264
6265 Object.defineProperty(exports, "__esModule", { value: true });
6266 var $ = __webpack_require__(3);
6267 var util_1 = __webpack_require__(4);
6268 var ListenerMixin_1 = __webpack_require__(7);
6269 var GlobalEmitter_1 = __webpack_require__(23);
6270 /* Tracks a drag's mouse movement, firing various handlers
6271 ----------------------------------------------------------------------------------------------------------------------*/
6272 // TODO: use Emitter
6273 var DragListener = /** @class */ (function () {
6274 function DragListener(options) {
6275 this.isInteracting = false;
6276 this.isDistanceSurpassed = false;
6277 this.isDelayEnded = false;
6278 this.isDragging = false;
6279 this.isTouch = false;
6280 this.isGeneric = false; // initiated by 'dragstart' (jqui)
6281 this.shouldCancelTouchScroll = true;
6282 this.scrollAlwaysKills = false;
6283 this.isAutoScroll = false;
6284 // defaults
6285 this.scrollSensitivity = 30; // pixels from edge for scrolling to start
6286 this.scrollSpeed = 200; // pixels per second, at maximum speed
6287 this.scrollIntervalMs = 50; // millisecond wait between scroll increment
6288 this.options = options || {};
6289 }
6290 // Interaction (high-level)
6291 // -----------------------------------------------------------------------------------------------------------------
6292 DragListener.prototype.startInteraction = function (ev, extraOptions) {
6293 if (extraOptions === void 0) { extraOptions = {}; }
6294 if (ev.type === 'mousedown') {
6295 if (GlobalEmitter_1.default.get().shouldIgnoreMouse()) {
6296 return;
6297 }
6298 else if (!util_1.isPrimaryMouseButton(ev)) {
6299 return;
6300 }
6301 else {
6302 ev.preventDefault(); // prevents native selection in most browsers
6303 }
6304 }
6305 if (!this.isInteracting) {
6306 // process options
6307 this.delay = util_1.firstDefined(extraOptions.delay, this.options.delay, 0);
6308 this.minDistance = util_1.firstDefined(extraOptions.distance, this.options.distance, 0);
6309 this.subjectEl = this.options.subjectEl;
6310 util_1.preventSelection($('body'));
6311 this.isInteracting = true;
6312 this.isTouch = util_1.getEvIsTouch(ev);
6313 this.isGeneric = ev.type === 'dragstart';
6314 this.isDelayEnded = false;
6315 this.isDistanceSurpassed = false;
6316 this.originX = util_1.getEvX(ev);
6317 this.originY = util_1.getEvY(ev);
6318 this.scrollEl = util_1.getScrollParent($(ev.target));
6319 this.bindHandlers();
6320 this.initAutoScroll();
6321 this.handleInteractionStart(ev);
6322 this.startDelay(ev);
6323 if (!this.minDistance) {
6324 this.handleDistanceSurpassed(ev);
6325 }
6326 }
6327 };
6328 DragListener.prototype.handleInteractionStart = function (ev) {
6329 this.trigger('interactionStart', ev);
6330 };
6331 DragListener.prototype.endInteraction = function (ev, isCancelled) {
6332 if (this.isInteracting) {
6333 this.endDrag(ev);
6334 if (this.delayTimeoutId) {
6335 clearTimeout(this.delayTimeoutId);
6336 this.delayTimeoutId = null;
6337 }
6338 this.destroyAutoScroll();
6339 this.unbindHandlers();
6340 this.isInteracting = false;
6341 this.handleInteractionEnd(ev, isCancelled);
6342 util_1.allowSelection($('body'));
6343 }
6344 };
6345 DragListener.prototype.handleInteractionEnd = function (ev, isCancelled) {
6346 this.trigger('interactionEnd', ev, isCancelled || false);
6347 };
6348 // Binding To DOM
6349 // -----------------------------------------------------------------------------------------------------------------
6350 DragListener.prototype.bindHandlers = function () {
6351 // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart,
6352 // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly.
6353 var globalEmitter = GlobalEmitter_1.default.get();
6354 if (this.isGeneric) {
6355 this.listenTo($(document), {
6356 drag: this.handleMove,
6357 dragstop: this.endInteraction
6358 });
6359 }
6360 else if (this.isTouch) {
6361 this.listenTo(globalEmitter, {
6362 touchmove: this.handleTouchMove,
6363 touchend: this.endInteraction,
6364 scroll: this.handleTouchScroll
6365 });
6366 }
6367 else {
6368 this.listenTo(globalEmitter, {
6369 mousemove: this.handleMouseMove,
6370 mouseup: this.endInteraction
6371 });
6372 }
6373 this.listenTo(globalEmitter, {
6374 selectstart: util_1.preventDefault,
6375 contextmenu: util_1.preventDefault // long taps would open menu on Chrome dev tools
6376 });
6377 };
6378 DragListener.prototype.unbindHandlers = function () {
6379 this.stopListeningTo(GlobalEmitter_1.default.get());
6380 this.stopListeningTo($(document)); // for isGeneric
6381 };
6382 // Drag (high-level)
6383 // -----------------------------------------------------------------------------------------------------------------
6384 // extraOptions ignored if drag already started
6385 DragListener.prototype.startDrag = function (ev, extraOptions) {
6386 this.startInteraction(ev, extraOptions); // ensure interaction began
6387 if (!this.isDragging) {
6388 this.isDragging = true;
6389 this.handleDragStart(ev);
6390 }
6391 };
6392 DragListener.prototype.handleDragStart = function (ev) {
6393 this.trigger('dragStart', ev);
6394 };
6395 DragListener.prototype.handleMove = function (ev) {
6396 var dx = util_1.getEvX(ev) - this.originX;
6397 var dy = util_1.getEvY(ev) - this.originY;
6398 var minDistance = this.minDistance;
6399 var distanceSq; // current distance from the origin, squared
6400 if (!this.isDistanceSurpassed) {
6401 distanceSq = dx * dx + dy * dy;
6402 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
6403 this.handleDistanceSurpassed(ev);
6404 }
6405 }
6406 if (this.isDragging) {
6407 this.handleDrag(dx, dy, ev);
6408 }
6409 };
6410 // Called while the mouse is being moved and when we know a legitimate drag is taking place
6411 DragListener.prototype.handleDrag = function (dx, dy, ev) {
6412 this.trigger('drag', dx, dy, ev);
6413 this.updateAutoScroll(ev); // will possibly cause scrolling
6414 };
6415 DragListener.prototype.endDrag = function (ev) {
6416 if (this.isDragging) {
6417 this.isDragging = false;
6418 this.handleDragEnd(ev);
6419 }
6420 };
6421 DragListener.prototype.handleDragEnd = function (ev) {
6422 this.trigger('dragEnd', ev);
6423 };
6424 // Delay
6425 // -----------------------------------------------------------------------------------------------------------------
6426 DragListener.prototype.startDelay = function (initialEv) {
6427 var _this = this;
6428 if (this.delay) {
6429 this.delayTimeoutId = setTimeout(function () {
6430 _this.handleDelayEnd(initialEv);
6431 }, this.delay);
6432 }
6433 else {
6434 this.handleDelayEnd(initialEv);
6435 }
6436 };
6437 DragListener.prototype.handleDelayEnd = function (initialEv) {
6438 this.isDelayEnded = true;
6439 if (this.isDistanceSurpassed) {
6440 this.startDrag(initialEv);
6441 }
6442 };
6443 // Distance
6444 // -----------------------------------------------------------------------------------------------------------------
6445 DragListener.prototype.handleDistanceSurpassed = function (ev) {
6446 this.isDistanceSurpassed = true;
6447 if (this.isDelayEnded) {
6448 this.startDrag(ev);
6449 }
6450 };
6451 // Mouse / Touch
6452 // -----------------------------------------------------------------------------------------------------------------
6453 DragListener.prototype.handleTouchMove = function (ev) {
6454 // prevent inertia and touchmove-scrolling while dragging
6455 if (this.isDragging && this.shouldCancelTouchScroll) {
6456 ev.preventDefault();
6457 }
6458 this.handleMove(ev);
6459 };
6460 DragListener.prototype.handleMouseMove = function (ev) {
6461 this.handleMove(ev);
6462 };
6463 // Scrolling (unrelated to auto-scroll)
6464 // -----------------------------------------------------------------------------------------------------------------
6465 DragListener.prototype.handleTouchScroll = function (ev) {
6466 // if the drag is being initiated by touch, but a scroll happens before
6467 // the drag-initiating delay is over, cancel the drag
6468 if (!this.isDragging || this.scrollAlwaysKills) {
6469 this.endInteraction(ev, true); // isCancelled=true
6470 }
6471 };
6472 // Utils
6473 // -----------------------------------------------------------------------------------------------------------------
6474 // Triggers a callback. Calls a function in the option hash of the same name.
6475 // Arguments beyond the first `name` are forwarded on.
6476 DragListener.prototype.trigger = function (name) {
6477 var args = [];
6478 for (var _i = 1; _i < arguments.length; _i++) {
6479 args[_i - 1] = arguments[_i];
6480 }
6481 if (this.options[name]) {
6482 this.options[name].apply(this, args);
6483 }
6484 // makes _methods callable by event name. TODO: kill this
6485 if (this['_' + name]) {
6486 this['_' + name].apply(this, args);
6487 }
6488 };
6489 // Auto-scroll
6490 // -----------------------------------------------------------------------------------------------------------------
6491 DragListener.prototype.initAutoScroll = function () {
6492 var scrollEl = this.scrollEl;
6493 this.isAutoScroll =
6494 this.options.scroll &&
6495 scrollEl &&
6496 !scrollEl.is(window) &&
6497 !scrollEl.is(document);
6498 if (this.isAutoScroll) {
6499 // debounce makes sure rapid calls don't happen
6500 this.listenTo(scrollEl, 'scroll', util_1.debounce(this.handleDebouncedScroll, 100));
6501 }
6502 };
6503 DragListener.prototype.destroyAutoScroll = function () {
6504 this.endAutoScroll(); // kill any animation loop
6505 // remove the scroll handler if there is a scrollEl
6506 if (this.isAutoScroll) {
6507 this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :(
6508 }
6509 };
6510 // Computes and stores the bounding rectangle of scrollEl
6511 DragListener.prototype.computeScrollBounds = function () {
6512 if (this.isAutoScroll) {
6513 this.scrollBounds = util_1.getOuterRect(this.scrollEl);
6514 // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars
6515 }
6516 };
6517 // Called when the dragging is in progress and scrolling should be updated
6518 DragListener.prototype.updateAutoScroll = function (ev) {
6519 var sensitivity = this.scrollSensitivity;
6520 var bounds = this.scrollBounds;
6521 var topCloseness;
6522 var bottomCloseness;
6523 var leftCloseness;
6524 var rightCloseness;
6525 var topVel = 0;
6526 var leftVel = 0;
6527 if (bounds) { // only scroll if scrollEl exists
6528 // compute closeness to edges. valid range is from 0.0 - 1.0
6529 topCloseness = (sensitivity - (util_1.getEvY(ev) - bounds.top)) / sensitivity;
6530 bottomCloseness = (sensitivity - (bounds.bottom - util_1.getEvY(ev))) / sensitivity;
6531 leftCloseness = (sensitivity - (util_1.getEvX(ev) - bounds.left)) / sensitivity;
6532 rightCloseness = (sensitivity - (bounds.right - util_1.getEvX(ev))) / sensitivity;
6533 // translate vertical closeness into velocity.
6534 // mouse must be completely in bounds for velocity to happen.
6535 if (topCloseness >= 0 && topCloseness <= 1) {
6536 topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up
6537 }
6538 else if (bottomCloseness >= 0 && bottomCloseness <= 1) {
6539 topVel = bottomCloseness * this.scrollSpeed;
6540 }
6541 // translate horizontal closeness into velocity
6542 if (leftCloseness >= 0 && leftCloseness <= 1) {
6543 leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left
6544 }
6545 else if (rightCloseness >= 0 && rightCloseness <= 1) {
6546 leftVel = rightCloseness * this.scrollSpeed;
6547 }
6548 }
6549 this.setScrollVel(topVel, leftVel);
6550 };
6551 // Sets the speed-of-scrolling for the scrollEl
6552 DragListener.prototype.setScrollVel = function (topVel, leftVel) {
6553 this.scrollTopVel = topVel;
6554 this.scrollLeftVel = leftVel;
6555 this.constrainScrollVel(); // massages into realistic values
6556 // if there is non-zero velocity, and an animation loop hasn't already started, then START
6557 if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {
6558 this.scrollIntervalId = setInterval(util_1.proxy(this, 'scrollIntervalFunc'), // scope to `this`
6559 this.scrollIntervalMs);
6560 }
6561 };
6562 // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way
6563 DragListener.prototype.constrainScrollVel = function () {
6564 var el = this.scrollEl;
6565 if (this.scrollTopVel < 0) { // scrolling up?
6566 if (el.scrollTop() <= 0) { // already scrolled all the way up?
6567 this.scrollTopVel = 0;
6568 }
6569 }
6570 else if (this.scrollTopVel > 0) { // scrolling down?
6571 if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?
6572 this.scrollTopVel = 0;
6573 }
6574 }
6575 if (this.scrollLeftVel < 0) { // scrolling left?
6576 if (el.scrollLeft() <= 0) { // already scrolled all the left?
6577 this.scrollLeftVel = 0;
6578 }
6579 }
6580 else if (this.scrollLeftVel > 0) { // scrolling right?
6581 if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?
6582 this.scrollLeftVel = 0;
6583 }
6584 }
6585 };
6586 // This function gets called during every iteration of the scrolling animation loop
6587 DragListener.prototype.scrollIntervalFunc = function () {
6588 var el = this.scrollEl;
6589 var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by
6590 // change the value of scrollEl's scroll
6591 if (this.scrollTopVel) {
6592 el.scrollTop(el.scrollTop() + this.scrollTopVel * frac);
6593 }
6594 if (this.scrollLeftVel) {
6595 el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);
6596 }
6597 this.constrainScrollVel(); // since the scroll values changed, recompute the velocities
6598 // if scrolled all the way, which causes the vels to be zero, stop the animation loop
6599 if (!this.scrollTopVel && !this.scrollLeftVel) {
6600 this.endAutoScroll();
6601 }
6602 };
6603 // Kills any existing scrolling animation loop
6604 DragListener.prototype.endAutoScroll = function () {
6605 if (this.scrollIntervalId) {
6606 clearInterval(this.scrollIntervalId);
6607 this.scrollIntervalId = null;
6608 this.handleScrollEnd();
6609 }
6610 };
6611 // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)
6612 DragListener.prototype.handleDebouncedScroll = function () {
6613 // recompute all coordinates, but *only* if this is *not* part of our scrolling animation
6614 if (!this.scrollIntervalId) {
6615 this.handleScrollEnd();
6616 }
6617 };
6618 DragListener.prototype.handleScrollEnd = function () {
6619 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
6620 };
6621 return DragListener;
6622 }());
6623 exports.default = DragListener;
6624 ListenerMixin_1.default.mixInto(DragListener);
6625
6626
6627 /***/ }),
6628 /* 60 */
6629 /***/ (function(module, exports, __webpack_require__) {
6630
6631 Object.defineProperty(exports, "__esModule", { value: true });
6632 var tslib_1 = __webpack_require__(2);
6633 var util_1 = __webpack_require__(4);
6634 var Mixin_1 = __webpack_require__(15);
6635 /*
6636 A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns.
6637 Prerequisite: the object being mixed into needs to be a *Grid*
6638 */
6639 var DayTableMixin = /** @class */ (function (_super) {
6640 tslib_1.__extends(DayTableMixin, _super);
6641 function DayTableMixin() {
6642 return _super !== null && _super.apply(this, arguments) || this;
6643 }
6644 // Populates internal variables used for date calculation and rendering
6645 DayTableMixin.prototype.updateDayTable = function () {
6646 var t = this;
6647 var view = t.view;
6648 var calendar = view.calendar;
6649 var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true);
6650 var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true);
6651 var dayIndex = -1;
6652 var dayIndices = [];
6653 var dayDates = [];
6654 var daysPerRow;
6655 var firstDay;
6656 var rowCnt;
6657 while (date.isBefore(end)) { // loop each day from start to end
6658 if (view.isHiddenDay(date)) {
6659 dayIndices.push(dayIndex + 0.5); // mark that it's between indices
6660 }
6661 else {
6662 dayIndex++;
6663 dayIndices.push(dayIndex);
6664 dayDates.push(date.clone());
6665 }
6666 date.add(1, 'days');
6667 }
6668 if (this.breakOnWeeks) {
6669 // count columns until the day-of-week repeats
6670 firstDay = dayDates[0].day();
6671 for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) {
6672 if (dayDates[daysPerRow].day() === firstDay) {
6673 break;
6674 }
6675 }
6676 rowCnt = Math.ceil(dayDates.length / daysPerRow);
6677 }
6678 else {
6679 rowCnt = 1;
6680 daysPerRow = dayDates.length;
6681 }
6682 this.dayDates = dayDates;
6683 this.dayIndices = dayIndices;
6684 this.daysPerRow = daysPerRow;
6685 this.rowCnt = rowCnt;
6686 this.updateDayTableCols();
6687 };
6688 // Computes and assigned the colCnt property and updates any options that may be computed from it
6689 DayTableMixin.prototype.updateDayTableCols = function () {
6690 this.colCnt = this.computeColCnt();
6691 this.colHeadFormat =
6692 this.opt('columnHeaderFormat') ||
6693 this.opt('columnFormat') || // deprecated
6694 this.computeColHeadFormat();
6695 };
6696 // Determines how many columns there should be in the table
6697 DayTableMixin.prototype.computeColCnt = function () {
6698 return this.daysPerRow;
6699 };
6700 // Computes the ambiguously-timed moment for the given cell
6701 DayTableMixin.prototype.getCellDate = function (row, col) {
6702 return this.dayDates[this.getCellDayIndex(row, col)].clone();
6703 };
6704 // Computes the ambiguously-timed date range for the given cell
6705 DayTableMixin.prototype.getCellRange = function (row, col) {
6706 var start = this.getCellDate(row, col);
6707 var end = start.clone().add(1, 'days');
6708 return { start: start, end: end };
6709 };
6710 // Returns the number of day cells, chronologically, from the first of the grid (0-based)
6711 DayTableMixin.prototype.getCellDayIndex = function (row, col) {
6712 return row * this.daysPerRow + this.getColDayIndex(col);
6713 };
6714 // Returns the numner of day cells, chronologically, from the first cell in *any given row*
6715 DayTableMixin.prototype.getColDayIndex = function (col) {
6716 if (this.isRTL) {
6717 return this.colCnt - 1 - col;
6718 }
6719 else {
6720 return col;
6721 }
6722 };
6723 // Given a date, returns its chronolocial cell-index from the first cell of the grid.
6724 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
6725 // If before the first offset, returns a negative number.
6726 // If after the last offset, returns an offset past the last cell offset.
6727 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
6728 DayTableMixin.prototype.getDateDayIndex = function (date) {
6729 var dayIndices = this.dayIndices;
6730 var dayOffset = date.diff(this.dayDates[0], 'days');
6731 if (dayOffset < 0) {
6732 return dayIndices[0] - 1;
6733 }
6734 else if (dayOffset >= dayIndices.length) {
6735 return dayIndices[dayIndices.length - 1] + 1;
6736 }
6737 else {
6738 return dayIndices[dayOffset];
6739 }
6740 };
6741 /* Options
6742 ------------------------------------------------------------------------------------------------------------------*/
6743 // Computes a default column header formatting string if `colFormat` is not explicitly defined
6744 DayTableMixin.prototype.computeColHeadFormat = function () {
6745 // if more than one week row, or if there are a lot of columns with not much space,
6746 // put just the day numbers will be in each cell
6747 if (this.rowCnt > 1 || this.colCnt > 10) {
6748 return 'ddd'; // "Sat"
6749 }
6750 else if (this.colCnt > 1) {
6751 return this.opt('dayOfMonthFormat'); // "Sat 12/10"
6752 }
6753 else {
6754 return 'dddd'; // "Saturday"
6755 }
6756 };
6757 /* Slicing
6758 ------------------------------------------------------------------------------------------------------------------*/
6759 // Slices up a date range into a segment for every week-row it intersects with
6760 DayTableMixin.prototype.sliceRangeByRow = function (unzonedRange) {
6761 var daysPerRow = this.daysPerRow;
6762 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
6763 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
6764 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
6765 var segs = [];
6766 var row;
6767 var rowFirst;
6768 var rowLast; // inclusive day-index range for current row
6769 var segFirst;
6770 var segLast; // inclusive day-index range for segment
6771 for (row = 0; row < this.rowCnt; row++) {
6772 rowFirst = row * daysPerRow;
6773 rowLast = rowFirst + daysPerRow - 1;
6774 // intersect segment's offset range with the row's
6775 segFirst = Math.max(rangeFirst, rowFirst);
6776 segLast = Math.min(rangeLast, rowLast);
6777 // deal with in-between indices
6778 segFirst = Math.ceil(segFirst); // in-between starts round to next cell
6779 segLast = Math.floor(segLast); // in-between ends round to prev cell
6780 if (segFirst <= segLast) { // was there any intersection with the current row?
6781 segs.push({
6782 row: row,
6783 // normalize to start of row
6784 firstRowDayIndex: segFirst - rowFirst,
6785 lastRowDayIndex: segLast - rowFirst,
6786 // must be matching integers to be the segment's start/end
6787 isStart: segFirst === rangeFirst,
6788 isEnd: segLast === rangeLast
6789 });
6790 }
6791 }
6792 return segs;
6793 };
6794 // Slices up a date range into a segment for every day-cell it intersects with.
6795 // TODO: make more DRY with sliceRangeByRow somehow.
6796 DayTableMixin.prototype.sliceRangeByDay = function (unzonedRange) {
6797 var daysPerRow = this.daysPerRow;
6798 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
6799 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
6800 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
6801 var segs = [];
6802 var row;
6803 var rowFirst;
6804 var rowLast; // inclusive day-index range for current row
6805 var i;
6806 var segFirst;
6807 var segLast; // inclusive day-index range for segment
6808 for (row = 0; row < this.rowCnt; row++) {
6809 rowFirst = row * daysPerRow;
6810 rowLast = rowFirst + daysPerRow - 1;
6811 for (i = rowFirst; i <= rowLast; i++) {
6812 // intersect segment's offset range with the row's
6813 segFirst = Math.max(rangeFirst, i);
6814 segLast = Math.min(rangeLast, i);
6815 // deal with in-between indices
6816 segFirst = Math.ceil(segFirst); // in-between starts round to next cell
6817 segLast = Math.floor(segLast); // in-between ends round to prev cell
6818 if (segFirst <= segLast) { // was there any intersection with the current row?
6819 segs.push({
6820 row: row,
6821 // normalize to start of row
6822 firstRowDayIndex: segFirst - rowFirst,
6823 lastRowDayIndex: segLast - rowFirst,
6824 // must be matching integers to be the segment's start/end
6825 isStart: segFirst === rangeFirst,
6826 isEnd: segLast === rangeLast
6827 });
6828 }
6829 }
6830 }
6831 return segs;
6832 };
6833 /* Header Rendering
6834 ------------------------------------------------------------------------------------------------------------------*/
6835 DayTableMixin.prototype.renderHeadHtml = function () {
6836 var theme = this.view.calendar.theme;
6837 return '' +
6838 '<div class="fc-row ' + theme.getClass('headerRow') + '">' +
6839 '<table class="' + theme.getClass('tableGrid') + '">' +
6840 '<thead>' +
6841 this.renderHeadTrHtml() +
6842 '</thead>' +
6843 '</table>' +
6844 '</div>';
6845 };
6846 DayTableMixin.prototype.renderHeadIntroHtml = function () {
6847 return this.renderIntroHtml(); // fall back to generic
6848 };
6849 DayTableMixin.prototype.renderHeadTrHtml = function () {
6850 return '' +
6851 '<tr>' +
6852 (this.isRTL ? '' : this.renderHeadIntroHtml()) +
6853 this.renderHeadDateCellsHtml() +
6854 (this.isRTL ? this.renderHeadIntroHtml() : '') +
6855 '</tr>';
6856 };
6857 DayTableMixin.prototype.renderHeadDateCellsHtml = function () {
6858 var htmls = [];
6859 var col;
6860 var date;
6861 for (col = 0; col < this.colCnt; col++) {
6862 date = this.getCellDate(0, col);
6863 htmls.push(this.renderHeadDateCellHtml(date));
6864 }
6865 return htmls.join('');
6866 };
6867 // TODO: when internalApiVersion, accept an object for HTML attributes
6868 // (colspan should be no different)
6869 DayTableMixin.prototype.renderHeadDateCellHtml = function (date, colspan, otherAttrs) {
6870 var t = this;
6871 var view = t.view;
6872 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
6873 var classNames = [
6874 'fc-day-header',
6875 view.calendar.theme.getClass('widgetHeader')
6876 ];
6877 var innerHtml;
6878 if (typeof t.opt('columnHeaderHtml') === 'function') {
6879 innerHtml = t.opt('columnHeaderHtml')(date);
6880 }
6881 else if (typeof t.opt('columnHeaderText') === 'function') {
6882 innerHtml = util_1.htmlEscape(t.opt('columnHeaderText')(date));
6883 }
6884 else {
6885 innerHtml = util_1.htmlEscape(date.format(t.colHeadFormat));
6886 }
6887 // if only one row of days, the classNames on the header can represent the specific days beneath
6888 if (t.rowCnt === 1) {
6889 classNames = classNames.concat(
6890 // includes the day-of-week class
6891 // noThemeHighlight=true (don't highlight the header)
6892 t.getDayClasses(date, true));
6893 }
6894 else {
6895 classNames.push('fc-' + util_1.dayIDs[date.day()]); // only add the day-of-week class
6896 }
6897 return '' +
6898 '<th class="' + classNames.join(' ') + '"' +
6899 ((isDateValid && t.rowCnt) === 1 ?
6900 ' data-date="' + date.format('YYYY-MM-DD') + '"' :
6901 '') +
6902 (colspan > 1 ?
6903 ' colspan="' + colspan + '"' :
6904 '') +
6905 (otherAttrs ?
6906 ' ' + otherAttrs :
6907 '') +
6908 '>' +
6909 (isDateValid ?
6910 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
6911 view.buildGotoAnchorHtml({ date: date, forceOff: t.rowCnt > 1 || t.colCnt === 1 }, innerHtml) :
6912 // if not valid, display text, but no link
6913 innerHtml) +
6914 '</th>';
6915 };
6916 /* Background Rendering
6917 ------------------------------------------------------------------------------------------------------------------*/
6918 DayTableMixin.prototype.renderBgTrHtml = function (row) {
6919 return '' +
6920 '<tr>' +
6921 (this.isRTL ? '' : this.renderBgIntroHtml(row)) +
6922 this.renderBgCellsHtml(row) +
6923 (this.isRTL ? this.renderBgIntroHtml(row) : '') +
6924 '</tr>';
6925 };
6926 DayTableMixin.prototype.renderBgIntroHtml = function (row) {
6927 return this.renderIntroHtml(); // fall back to generic
6928 };
6929 DayTableMixin.prototype.renderBgCellsHtml = function (row) {
6930 var htmls = [];
6931 var col;
6932 var date;
6933 for (col = 0; col < this.colCnt; col++) {
6934 date = this.getCellDate(row, col);
6935 htmls.push(this.renderBgCellHtml(date));
6936 }
6937 return htmls.join('');
6938 };
6939 DayTableMixin.prototype.renderBgCellHtml = function (date, otherAttrs) {
6940 var t = this;
6941 var view = t.view;
6942 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
6943 var classes = t.getDayClasses(date);
6944 classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent'));
6945 return '<td class="' + classes.join(' ') + '"' +
6946 (isDateValid ?
6947 ' data-date="' + date.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it
6948 '') +
6949 (otherAttrs ?
6950 ' ' + otherAttrs :
6951 '') +
6952 '></td>';
6953 };
6954 /* Generic
6955 ------------------------------------------------------------------------------------------------------------------*/
6956 DayTableMixin.prototype.renderIntroHtml = function () {
6957 // Generates the default HTML intro for any row. User classes should override
6958 };
6959 // TODO: a generic method for dealing with <tr>, RTL, intro
6960 // when increment internalApiVersion
6961 // wrapTr (scheduler)
6962 /* Utils
6963 ------------------------------------------------------------------------------------------------------------------*/
6964 // Applies the generic "intro" and "outro" HTML to the given cells.
6965 // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
6966 DayTableMixin.prototype.bookendCells = function (trEl) {
6967 var introHtml = this.renderIntroHtml();
6968 if (introHtml) {
6969 if (this.isRTL) {
6970 trEl.append(introHtml);
6971 }
6972 else {
6973 trEl.prepend(introHtml);
6974 }
6975 }
6976 };
6977 return DayTableMixin;
6978 }(Mixin_1.default));
6979 exports.default = DayTableMixin;
6980
6981
6982 /***/ }),
6983 /* 61 */
6984 /***/ (function(module, exports) {
6985
6986 Object.defineProperty(exports, "__esModule", { value: true });
6987 var BusinessHourRenderer = /** @class */ (function () {
6988 /*
6989 component implements:
6990 - eventRangesToEventFootprints
6991 - eventFootprintsToSegs
6992 */
6993 function BusinessHourRenderer(component, fillRenderer) {
6994 this.component = component;
6995 this.fillRenderer = fillRenderer;
6996 }
6997 BusinessHourRenderer.prototype.render = function (businessHourGenerator) {
6998 var component = this.component;
6999 var unzonedRange = component._getDateProfile().activeUnzonedRange;
7000 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(component.hasAllDayBusinessHours, unzonedRange);
7001 var eventFootprints = eventInstanceGroup ?
7002 component.eventRangesToEventFootprints(eventInstanceGroup.sliceRenderRanges(unzonedRange)) :
7003 [];
7004 this.renderEventFootprints(eventFootprints);
7005 };
7006 BusinessHourRenderer.prototype.renderEventFootprints = function (eventFootprints) {
7007 var segs = this.component.eventFootprintsToSegs(eventFootprints);
7008 this.renderSegs(segs);
7009 this.segs = segs;
7010 };
7011 BusinessHourRenderer.prototype.renderSegs = function (segs) {
7012 if (this.fillRenderer) {
7013 this.fillRenderer.renderSegs('businessHours', segs, {
7014 getClasses: function (seg) {
7015 return ['fc-nonbusiness', 'fc-bgevent'];
7016 }
7017 });
7018 }
7019 };
7020 BusinessHourRenderer.prototype.unrender = function () {
7021 if (this.fillRenderer) {
7022 this.fillRenderer.unrender('businessHours');
7023 }
7024 this.segs = null;
7025 };
7026 BusinessHourRenderer.prototype.getSegs = function () {
7027 return this.segs || [];
7028 };
7029 return BusinessHourRenderer;
7030 }());
7031 exports.default = BusinessHourRenderer;
7032
7033
7034 /***/ }),
7035 /* 62 */
7036 /***/ (function(module, exports, __webpack_require__) {
7037
7038 Object.defineProperty(exports, "__esModule", { value: true });
7039 var $ = __webpack_require__(3);
7040 var util_1 = __webpack_require__(4);
7041 var FillRenderer = /** @class */ (function () {
7042 function FillRenderer(component) {
7043 this.fillSegTag = 'div';
7044 this.component = component;
7045 this.elsByFill = {};
7046 }
7047 FillRenderer.prototype.renderFootprint = function (type, componentFootprint, props) {
7048 this.renderSegs(type, this.component.componentFootprintToSegs(componentFootprint), props);
7049 };
7050 FillRenderer.prototype.renderSegs = function (type, segs, props) {
7051 var els;
7052 segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs
7053 els = this.attachSegEls(type, segs);
7054 if (els) {
7055 this.reportEls(type, els);
7056 }
7057 return segs;
7058 };
7059 // Unrenders a specific type of fill that is currently rendered on the grid
7060 FillRenderer.prototype.unrender = function (type) {
7061 var el = this.elsByFill[type];
7062 if (el) {
7063 el.remove();
7064 delete this.elsByFill[type];
7065 }
7066 };
7067 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
7068 // Only returns segments that successfully rendered.
7069 FillRenderer.prototype.buildSegEls = function (type, segs, props) {
7070 var _this = this;
7071 var html = '';
7072 var renderedSegs = [];
7073 var i;
7074 if (segs.length) {
7075 // build a large concatenation of segment HTML
7076 for (i = 0; i < segs.length; i++) {
7077 html += this.buildSegHtml(type, segs[i], props);
7078 }
7079 // Grab individual elements from the combined HTML string. Use each as the default rendering.
7080 // Then, compute the 'el' for each segment.
7081 $(html).each(function (i, node) {
7082 var seg = segs[i];
7083 var el = $(node);
7084 // allow custom filter methods per-type
7085 if (props.filterEl) {
7086 el = props.filterEl(seg, el);
7087 }
7088 if (el) { // custom filters did not cancel the render
7089 el = $(el); // allow custom filter to return raw DOM node
7090 // correct element type? (would be bad if a non-TD were inserted into a table for example)
7091 if (el.is(_this.fillSegTag)) {
7092 seg.el = el;
7093 renderedSegs.push(seg);
7094 }
7095 }
7096 });
7097 }
7098 return renderedSegs;
7099 };
7100 // Builds the HTML needed for one fill segment. Generic enough to work with different types.
7101 FillRenderer.prototype.buildSegHtml = function (type, seg, props) {
7102 // custom hooks per-type
7103 var classes = props.getClasses ? props.getClasses(seg) : [];
7104 var css = util_1.cssToStr(props.getCss ? props.getCss(seg) : {});
7105 return '<' + this.fillSegTag +
7106 (classes.length ? ' class="' + classes.join(' ') + '"' : '') +
7107 (css ? ' style="' + css + '"' : '') +
7108 '></' + this.fillSegTag + '>';
7109 };
7110 // Should return wrapping DOM structure
7111 FillRenderer.prototype.attachSegEls = function (type, segs) {
7112 // subclasses must implement
7113 };
7114 FillRenderer.prototype.reportEls = function (type, nodes) {
7115 if (this.elsByFill[type]) {
7116 this.elsByFill[type] = this.elsByFill[type].add(nodes);
7117 }
7118 else {
7119 this.elsByFill[type] = $(nodes);
7120 }
7121 };
7122 return FillRenderer;
7123 }());
7124 exports.default = FillRenderer;
7125
7126
7127 /***/ }),
7128 /* 63 */
7129 /***/ (function(module, exports, __webpack_require__) {
7130
7131 Object.defineProperty(exports, "__esModule", { value: true });
7132 var SingleEventDef_1 = __webpack_require__(9);
7133 var EventFootprint_1 = __webpack_require__(34);
7134 var EventSource_1 = __webpack_require__(6);
7135 var HelperRenderer = /** @class */ (function () {
7136 function HelperRenderer(component, eventRenderer) {
7137 this.view = component._getView();
7138 this.component = component;
7139 this.eventRenderer = eventRenderer;
7140 }
7141 HelperRenderer.prototype.renderComponentFootprint = function (componentFootprint) {
7142 this.renderEventFootprints([
7143 this.fabricateEventFootprint(componentFootprint)
7144 ]);
7145 };
7146 HelperRenderer.prototype.renderEventDraggingFootprints = function (eventFootprints, sourceSeg, isTouch) {
7147 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-dragging', isTouch ? null : this.view.opt('dragOpacity'));
7148 };
7149 HelperRenderer.prototype.renderEventResizingFootprints = function (eventFootprints, sourceSeg, isTouch) {
7150 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-resizing');
7151 };
7152 HelperRenderer.prototype.renderEventFootprints = function (eventFootprints, sourceSeg, extraClassNames, opacity) {
7153 var segs = this.component.eventFootprintsToSegs(eventFootprints);
7154 var classNames = 'fc-helper ' + (extraClassNames || '');
7155 var i;
7156 // assigns each seg's el and returns a subset of segs that were rendered
7157 segs = this.eventRenderer.renderFgSegEls(segs);
7158 for (i = 0; i < segs.length; i++) {
7159 segs[i].el.addClass(classNames);
7160 }
7161 if (opacity != null) {
7162 for (i = 0; i < segs.length; i++) {
7163 segs[i].el.css('opacity', opacity);
7164 }
7165 }
7166 this.helperEls = this.renderSegs(segs, sourceSeg);
7167 };
7168 /*
7169 Must return all mock event elements
7170 */
7171 HelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
7172 // Subclasses must implement
7173 };
7174 HelperRenderer.prototype.unrender = function () {
7175 if (this.helperEls) {
7176 this.helperEls.remove();
7177 this.helperEls = null;
7178 }
7179 };
7180 HelperRenderer.prototype.fabricateEventFootprint = function (componentFootprint) {
7181 var calendar = this.view.calendar;
7182 var eventDateProfile = calendar.footprintToDateProfile(componentFootprint);
7183 var dummyEvent = new SingleEventDef_1.default(new EventSource_1.default(calendar));
7184 var dummyInstance;
7185 dummyEvent.dateProfile = eventDateProfile;
7186 dummyInstance = dummyEvent.buildInstance();
7187 return new EventFootprint_1.default(componentFootprint, dummyEvent, dummyInstance);
7188 };
7189 return HelperRenderer;
7190 }());
7191 exports.default = HelperRenderer;
7192
7193
7194 /***/ }),
7195 /* 64 */
7196 /***/ (function(module, exports, __webpack_require__) {
7197
7198 Object.defineProperty(exports, "__esModule", { value: true });
7199 var tslib_1 = __webpack_require__(2);
7200 var GlobalEmitter_1 = __webpack_require__(23);
7201 var Interaction_1 = __webpack_require__(14);
7202 var EventPointing = /** @class */ (function (_super) {
7203 tslib_1.__extends(EventPointing, _super);
7204 function EventPointing() {
7205 return _super !== null && _super.apply(this, arguments) || this;
7206 }
7207 /*
7208 component must implement:
7209 - publiclyTrigger
7210 */
7211 EventPointing.prototype.bindToEl = function (el) {
7212 var component = this.component;
7213 component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this));
7214 component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this));
7215 component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this));
7216 };
7217 EventPointing.prototype.handleClick = function (seg, ev) {
7218 var res = this.component.publiclyTrigger('eventClick', {
7219 context: seg.el[0],
7220 args: [seg.footprint.getEventLegacy(), ev, this.view]
7221 });
7222 if (res === false) {
7223 ev.preventDefault();
7224 }
7225 };
7226 // Updates internal state and triggers handlers for when an event element is moused over
7227 EventPointing.prototype.handleMouseover = function (seg, ev) {
7228 if (!GlobalEmitter_1.default.get().shouldIgnoreMouse() &&
7229 !this.mousedOverSeg) {
7230 this.mousedOverSeg = seg;
7231 // TODO: move to EventSelecting's responsibility
7232 if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
7233 seg.el.addClass('fc-allow-mouse-resize');
7234 }
7235 this.component.publiclyTrigger('eventMouseover', {
7236 context: seg.el[0],
7237 args: [seg.footprint.getEventLegacy(), ev, this.view]
7238 });
7239 }
7240 };
7241 // Updates internal state and triggers handlers for when an event element is moused out.
7242 // Can be given no arguments, in which case it will mouseout the segment that was previously moused over.
7243 EventPointing.prototype.handleMouseout = function (seg, ev) {
7244 if (this.mousedOverSeg) {
7245 this.mousedOverSeg = null;
7246 // TODO: move to EventSelecting's responsibility
7247 if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
7248 seg.el.removeClass('fc-allow-mouse-resize');
7249 }
7250 this.component.publiclyTrigger('eventMouseout', {
7251 context: seg.el[0],
7252 args: [
7253 seg.footprint.getEventLegacy(),
7254 ev || {},
7255 this.view
7256 ]
7257 });
7258 }
7259 };
7260 EventPointing.prototype.end = function () {
7261 if (this.mousedOverSeg) {
7262 this.handleMouseout(this.mousedOverSeg);
7263 }
7264 };
7265 return EventPointing;
7266 }(Interaction_1.default));
7267 exports.default = EventPointing;
7268
7269
7270 /***/ }),
7271 /* 65 */
7272 /***/ (function(module, exports, __webpack_require__) {
7273
7274 Object.defineProperty(exports, "__esModule", { value: true });
7275 var tslib_1 = __webpack_require__(2);
7276 var Mixin_1 = __webpack_require__(15);
7277 var DateClicking_1 = __webpack_require__(237);
7278 var DateSelecting_1 = __webpack_require__(236);
7279 var EventPointing_1 = __webpack_require__(64);
7280 var EventDragging_1 = __webpack_require__(235);
7281 var EventResizing_1 = __webpack_require__(234);
7282 var ExternalDropping_1 = __webpack_require__(233);
7283 var StandardInteractionsMixin = /** @class */ (function (_super) {
7284 tslib_1.__extends(StandardInteractionsMixin, _super);
7285 function StandardInteractionsMixin() {
7286 return _super !== null && _super.apply(this, arguments) || this;
7287 }
7288 return StandardInteractionsMixin;
7289 }(Mixin_1.default));
7290 exports.default = StandardInteractionsMixin;
7291 StandardInteractionsMixin.prototype.dateClickingClass = DateClicking_1.default;
7292 StandardInteractionsMixin.prototype.dateSelectingClass = DateSelecting_1.default;
7293 StandardInteractionsMixin.prototype.eventPointingClass = EventPointing_1.default;
7294 StandardInteractionsMixin.prototype.eventDraggingClass = EventDragging_1.default;
7295 StandardInteractionsMixin.prototype.eventResizingClass = EventResizing_1.default;
7296 StandardInteractionsMixin.prototype.externalDroppingClass = ExternalDropping_1.default;
7297
7298
7299 /***/ }),
7300 /* 66 */
7301 /***/ (function(module, exports, __webpack_require__) {
7302
7303 Object.defineProperty(exports, "__esModule", { value: true });
7304 var tslib_1 = __webpack_require__(2);
7305 var $ = __webpack_require__(3);
7306 var util_1 = __webpack_require__(4);
7307 var CoordCache_1 = __webpack_require__(58);
7308 var Popover_1 = __webpack_require__(227);
7309 var UnzonedRange_1 = __webpack_require__(5);
7310 var ComponentFootprint_1 = __webpack_require__(12);
7311 var EventFootprint_1 = __webpack_require__(34);
7312 var BusinessHourRenderer_1 = __webpack_require__(61);
7313 var StandardInteractionsMixin_1 = __webpack_require__(65);
7314 var InteractiveDateComponent_1 = __webpack_require__(42);
7315 var DayTableMixin_1 = __webpack_require__(60);
7316 var DayGridEventRenderer_1 = __webpack_require__(243);
7317 var DayGridHelperRenderer_1 = __webpack_require__(244);
7318 var DayGridFillRenderer_1 = __webpack_require__(245);
7319 /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
7320 ----------------------------------------------------------------------------------------------------------------------*/
7321 var DayGrid = /** @class */ (function (_super) {
7322 tslib_1.__extends(DayGrid, _super);
7323 function DayGrid(view) {
7324 var _this = _super.call(this, view) || this;
7325 _this.cellWeekNumbersVisible = false; // display week numbers in day cell?
7326 _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
7327 // isRigid determines whether the individual rows should ignore the contents and be a constant height.
7328 // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.
7329 _this.isRigid = false;
7330 _this.hasAllDayBusinessHours = true;
7331 return _this;
7332 }
7333 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
7334 DayGrid.prototype.componentFootprintToSegs = function (componentFootprint) {
7335 var segs = this.sliceRangeByRow(componentFootprint.unzonedRange);
7336 var i;
7337 var seg;
7338 for (i = 0; i < segs.length; i++) {
7339 seg = segs[i];
7340 if (this.isRTL) {
7341 seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex;
7342 seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex;
7343 }
7344 else {
7345 seg.leftCol = seg.firstRowDayIndex;
7346 seg.rightCol = seg.lastRowDayIndex;
7347 }
7348 }
7349 return segs;
7350 };
7351 /* Date Rendering
7352 ------------------------------------------------------------------------------------------------------------------*/
7353 DayGrid.prototype.renderDates = function (dateProfile) {
7354 this.dateProfile = dateProfile;
7355 this.updateDayTable();
7356 this.renderGrid();
7357 };
7358 DayGrid.prototype.unrenderDates = function () {
7359 this.removeSegPopover();
7360 };
7361 // Renders the rows and columns into the component's `this.el`, which should already be assigned.
7362 DayGrid.prototype.renderGrid = function () {
7363 var view = this.view;
7364 var rowCnt = this.rowCnt;
7365 var colCnt = this.colCnt;
7366 var html = '';
7367 var row;
7368 var col;
7369 if (this.headContainerEl) {
7370 this.headContainerEl.html(this.renderHeadHtml());
7371 }
7372 for (row = 0; row < rowCnt; row++) {
7373 html += this.renderDayRowHtml(row, this.isRigid);
7374 }
7375 this.el.html(html);
7376 this.rowEls = this.el.find('.fc-row');
7377 this.cellEls = this.el.find('.fc-day, .fc-disabled-day');
7378 this.rowCoordCache = new CoordCache_1.default({
7379 els: this.rowEls,
7380 isVertical: true
7381 });
7382 this.colCoordCache = new CoordCache_1.default({
7383 els: this.cellEls.slice(0, this.colCnt),
7384 isHorizontal: true
7385 });
7386 // trigger dayRender with each cell's element
7387 for (row = 0; row < rowCnt; row++) {
7388 for (col = 0; col < colCnt; col++) {
7389 this.publiclyTrigger('dayRender', {
7390 context: view,
7391 args: [
7392 this.getCellDate(row, col),
7393 this.getCellEl(row, col),
7394 view
7395 ]
7396 });
7397 }
7398 }
7399 };
7400 // Generates the HTML for a single row, which is a div that wraps a table.
7401 // `row` is the row number.
7402 DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
7403 var theme = this.view.calendar.theme;
7404 var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
7405 if (isRigid) {
7406 classes.push('fc-rigid');
7407 }
7408 return '' +
7409 '<div class="' + classes.join(' ') + '">' +
7410 '<div class="fc-bg">' +
7411 '<table class="' + theme.getClass('tableGrid') + '">' +
7412 this.renderBgTrHtml(row) +
7413 '</table>' +
7414 '</div>' +
7415 '<div class="fc-content-skeleton">' +
7416 '<table>' +
7417 (this.getIsNumbersVisible() ?
7418 '<thead>' +
7419 this.renderNumberTrHtml(row) +
7420 '</thead>' :
7421 '') +
7422 '</table>' +
7423 '</div>' +
7424 '</div>';
7425 };
7426 DayGrid.prototype.getIsNumbersVisible = function () {
7427 return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible;
7428 };
7429 DayGrid.prototype.getIsDayNumbersVisible = function () {
7430 return this.rowCnt > 1;
7431 };
7432 /* Grid Number Rendering
7433 ------------------------------------------------------------------------------------------------------------------*/
7434 DayGrid.prototype.renderNumberTrHtml = function (row) {
7435 return '' +
7436 '<tr>' +
7437 (this.isRTL ? '' : this.renderNumberIntroHtml(row)) +
7438 this.renderNumberCellsHtml(row) +
7439 (this.isRTL ? this.renderNumberIntroHtml(row) : '') +
7440 '</tr>';
7441 };
7442 DayGrid.prototype.renderNumberIntroHtml = function (row) {
7443 return this.renderIntroHtml();
7444 };
7445 DayGrid.prototype.renderNumberCellsHtml = function (row) {
7446 var htmls = [];
7447 var col;
7448 var date;
7449 for (col = 0; col < this.colCnt; col++) {
7450 date = this.getCellDate(row, col);
7451 htmls.push(this.renderNumberCellHtml(date));
7452 }
7453 return htmls.join('');
7454 };
7455 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
7456 // The number row will only exist if either day numbers or week numbers are turned on.
7457 DayGrid.prototype.renderNumberCellHtml = function (date) {
7458 var view = this.view;
7459 var html = '';
7460 var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
7461 var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
7462 var classes;
7463 var weekCalcFirstDoW;
7464 if (!isDayNumberVisible && !this.cellWeekNumbersVisible) {
7465 // no numbers in day cell (week number must be along the side)
7466 return '<td></td>'; // will create an empty space above events :(
7467 }
7468 classes = this.getDayClasses(date);
7469 classes.unshift('fc-day-top');
7470 if (this.cellWeekNumbersVisible) {
7471 // To determine the day of week number change under ISO, we cannot
7472 // rely on moment.js methods such as firstDayOfWeek() or weekday(),
7473 // because they rely on the locale's dow (possibly overridden by
7474 // our firstDay option), which may not be Monday. We cannot change
7475 // dow, because that would affect the calendar start day as well.
7476 if (date._locale._fullCalendar_weekCalc === 'ISO') {
7477 weekCalcFirstDoW = 1; // Monday by ISO 8601 definition
7478 }
7479 else {
7480 weekCalcFirstDoW = date._locale.firstDayOfWeek();
7481 }
7482 }
7483 html += '<td class="' + classes.join(' ') + '"' +
7484 (isDateValid ?
7485 ' data-date="' + date.format() + '"' :
7486 '') +
7487 '>';
7488 if (this.cellWeekNumbersVisible && (date.day() === weekCalcFirstDoW)) {
7489 html += view.buildGotoAnchorHtml({ date: date, type: 'week' }, { 'class': 'fc-week-number' }, date.format('w') // inner HTML
7490 );
7491 }
7492 if (isDayNumberVisible) {
7493 html += view.buildGotoAnchorHtml(date, { 'class': 'fc-day-number' }, date.format('D') // inner HTML
7494 );
7495 }
7496 html += '</td>';
7497 return html;
7498 };
7499 /* Hit System
7500 ------------------------------------------------------------------------------------------------------------------*/
7501 DayGrid.prototype.prepareHits = function () {
7502 this.colCoordCache.build();
7503 this.rowCoordCache.build();
7504 this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
7505 };
7506 DayGrid.prototype.releaseHits = function () {
7507 this.colCoordCache.clear();
7508 this.rowCoordCache.clear();
7509 };
7510 DayGrid.prototype.queryHit = function (leftOffset, topOffset) {
7511 if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) {
7512 var col = this.colCoordCache.getHorizontalIndex(leftOffset);
7513 var row = this.rowCoordCache.getVerticalIndex(topOffset);
7514 if (row != null && col != null) {
7515 return this.getCellHit(row, col);
7516 }
7517 }
7518 };
7519 DayGrid.prototype.getHitFootprint = function (hit) {
7520 var range = this.getCellRange(hit.row, hit.col);
7521 return new ComponentFootprint_1.default(new UnzonedRange_1.default(range.start, range.end), true // all-day?
7522 );
7523 };
7524 DayGrid.prototype.getHitEl = function (hit) {
7525 return this.getCellEl(hit.row, hit.col);
7526 };
7527 /* Cell System
7528 ------------------------------------------------------------------------------------------------------------------*/
7529 // FYI: the first column is the leftmost column, regardless of date
7530 DayGrid.prototype.getCellHit = function (row, col) {
7531 return {
7532 row: row,
7533 col: col,
7534 component: this,
7535 left: this.colCoordCache.getLeftOffset(col),
7536 right: this.colCoordCache.getRightOffset(col),
7537 top: this.rowCoordCache.getTopOffset(row),
7538 bottom: this.rowCoordCache.getBottomOffset(row)
7539 };
7540 };
7541 DayGrid.prototype.getCellEl = function (row, col) {
7542 return this.cellEls.eq(row * this.colCnt + col);
7543 };
7544 /* Event Rendering
7545 ------------------------------------------------------------------------------------------------------------------*/
7546 // Unrenders all events currently rendered on the grid
7547 DayGrid.prototype.executeEventUnrender = function () {
7548 this.removeSegPopover(); // removes the "more.." events popover
7549 _super.prototype.executeEventUnrender.call(this);
7550 };
7551 // Retrieves all rendered segment objects currently rendered on the grid
7552 DayGrid.prototype.getOwnEventSegs = function () {
7553 // append the segments from the "more..." popover
7554 return _super.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs || []);
7555 };
7556 /* Event Drag Visualization
7557 ------------------------------------------------------------------------------------------------------------------*/
7558 // Renders a visual indication of an event or external element being dragged.
7559 // `eventLocation` has zoned start and end (optional)
7560 DayGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
7561 var i;
7562 for (i = 0; i < eventFootprints.length; i++) {
7563 this.renderHighlight(eventFootprints[i].componentFootprint);
7564 }
7565 // render drags from OTHER components as helpers
7566 if (eventFootprints.length && seg && seg.component !== this) {
7567 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
7568 return true; // signal helpers rendered
7569 }
7570 };
7571 // Unrenders any visual indication of a hovering event
7572 DayGrid.prototype.unrenderDrag = function () {
7573 this.unrenderHighlight();
7574 this.helperRenderer.unrender();
7575 };
7576 /* Event Resize Visualization
7577 ------------------------------------------------------------------------------------------------------------------*/
7578 // Renders a visual indication of an event being resized
7579 DayGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
7580 var i;
7581 for (i = 0; i < eventFootprints.length; i++) {
7582 this.renderHighlight(eventFootprints[i].componentFootprint);
7583 }
7584 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
7585 };
7586 // Unrenders a visual indication of an event being resized
7587 DayGrid.prototype.unrenderEventResize = function () {
7588 this.unrenderHighlight();
7589 this.helperRenderer.unrender();
7590 };
7591 /* More+ Link Popover
7592 ------------------------------------------------------------------------------------------------------------------*/
7593 DayGrid.prototype.removeSegPopover = function () {
7594 if (this.segPopover) {
7595 this.segPopover.hide(); // in handler, will call segPopover's removeElement
7596 }
7597 };
7598 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
7599 // `levelLimit` can be false (don't limit), a number, or true (should be computed).
7600 DayGrid.prototype.limitRows = function (levelLimit) {
7601 var rowStructs = this.eventRenderer.rowStructs || [];
7602 var row; // row #
7603 var rowLevelLimit;
7604 for (row = 0; row < rowStructs.length; row++) {
7605 this.unlimitRow(row);
7606 if (!levelLimit) {
7607 rowLevelLimit = false;
7608 }
7609 else if (typeof levelLimit === 'number') {
7610 rowLevelLimit = levelLimit;
7611 }
7612 else {
7613 rowLevelLimit = this.computeRowLevelLimit(row);
7614 }
7615 if (rowLevelLimit !== false) {
7616 this.limitRow(row, rowLevelLimit);
7617 }
7618 }
7619 };
7620 // Computes the number of levels a row will accomodate without going outside its bounds.
7621 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
7622 // `row` is the row number.
7623 DayGrid.prototype.computeRowLevelLimit = function (row) {
7624 var rowEl = this.rowEls.eq(row); // the containing "fake" row div
7625 var rowHeight = rowEl.height(); // TODO: cache somehow?
7626 var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children();
7627 var i;
7628 var trEl;
7629 var trHeight;
7630 function iterInnerHeights(i, childNode) {
7631 trHeight = Math.max(trHeight, $(childNode).outerHeight());
7632 }
7633 // Reveal one level <tr> at a time and stop when we find one out of bounds
7634 for (i = 0; i < trEls.length; i++) {
7635 trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)
7636 // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,
7637 // so instead, find the tallest inner content element.
7638 trHeight = 0;
7639 trEl.find('> td > :first-child').each(iterInnerHeights);
7640 if (trEl.position().top + trHeight > rowHeight) {
7641 return i;
7642 }
7643 }
7644 return false; // should not limit at all
7645 };
7646 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
7647 // `row` is the row number.
7648 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
7649 DayGrid.prototype.limitRow = function (row, levelLimit) {
7650 var _this = this;
7651 var rowStruct = this.eventRenderer.rowStructs[row];
7652 var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
7653 var col = 0; // col #, left-to-right (not chronologically)
7654 var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
7655 var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row
7656 var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
7657 var i;
7658 var seg;
7659 var segsBelow; // array of segment objects below `seg` in the current `col`
7660 var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
7661 var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
7662 var td;
7663 var rowspan;
7664 var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
7665 var j;
7666 var moreTd;
7667 var moreWrap;
7668 var moreLink;
7669 // Iterates through empty level cells and places "more" links inside if need be
7670 var emptyCellsUntil = function (endCol) {
7671 while (col < endCol) {
7672 segsBelow = _this.getCellSegs(row, col, levelLimit);
7673 if (segsBelow.length) {
7674 td = cellMatrix[levelLimit - 1][col];
7675 moreLink = _this.renderMoreLink(row, col, segsBelow);
7676 moreWrap = $('<div>').append(moreLink);
7677 td.append(moreWrap);
7678 moreNodes.push(moreWrap[0]);
7679 }
7680 col++;
7681 }
7682 };
7683 if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
7684 levelSegs = rowStruct.segLevels[levelLimit - 1];
7685 cellMatrix = rowStruct.cellMatrix;
7686 limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit
7687 .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array
7688 // iterate though segments in the last allowable level
7689 for (i = 0; i < levelSegs.length; i++) {
7690 seg = levelSegs[i];
7691 emptyCellsUntil(seg.leftCol); // process empty cells before the segment
7692 // determine *all* segments below `seg` that occupy the same columns
7693 colSegsBelow = [];
7694 totalSegsBelow = 0;
7695 while (col <= seg.rightCol) {
7696 segsBelow = this.getCellSegs(row, col, levelLimit);
7697 colSegsBelow.push(segsBelow);
7698 totalSegsBelow += segsBelow.length;
7699 col++;
7700 }
7701 if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
7702 td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell
7703 rowspan = td.attr('rowspan') || 1;
7704 segMoreNodes = [];
7705 // make a replacement <td> for each column the segment occupies. will be one for each colspan
7706 for (j = 0; j < colSegsBelow.length; j++) {
7707 moreTd = $('<td class="fc-more-cell">').attr('rowspan', rowspan);
7708 segsBelow = colSegsBelow[j];
7709 moreLink = this.renderMoreLink(row, seg.leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
7710 );
7711 moreWrap = $('<div>').append(moreLink);
7712 moreTd.append(moreWrap);
7713 segMoreNodes.push(moreTd[0]);
7714 moreNodes.push(moreTd[0]);
7715 }
7716 td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements
7717 limitedNodes.push(td[0]);
7718 }
7719 }
7720 emptyCellsUntil(this.colCnt); // finish off the level
7721 rowStruct.moreEls = $(moreNodes); // for easy undoing later
7722 rowStruct.limitedEls = $(limitedNodes); // for easy undoing later
7723 }
7724 };
7725 // Reveals all levels and removes all "more"-related elements for a grid's row.
7726 // `row` is a row number.
7727 DayGrid.prototype.unlimitRow = function (row) {
7728 var rowStruct = this.eventRenderer.rowStructs[row];
7729 if (rowStruct.moreEls) {
7730 rowStruct.moreEls.remove();
7731 rowStruct.moreEls = null;
7732 }
7733 if (rowStruct.limitedEls) {
7734 rowStruct.limitedEls.removeClass('fc-limited');
7735 rowStruct.limitedEls = null;
7736 }
7737 };
7738 // Renders an <a> element that represents hidden event element for a cell.
7739 // Responsible for attaching click handler as well.
7740 DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
7741 var _this = this;
7742 var view = this.view;
7743 return $('<a class="fc-more">')
7744 .text(this.getMoreLinkText(hiddenSegs.length))
7745 .on('click', function (ev) {
7746 var clickOption = _this.opt('eventLimitClick');
7747 var date = _this.getCellDate(row, col);
7748 var moreEl = $(ev.currentTarget);
7749 var dayEl = _this.getCellEl(row, col);
7750 var allSegs = _this.getCellSegs(row, col);
7751 // rescope the segments to be within the cell's date
7752 var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
7753 var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
7754 if (typeof clickOption === 'function') {
7755 // the returned value can be an atomic option
7756 clickOption = _this.publiclyTrigger('eventLimitClick', {
7757 context: view,
7758 args: [
7759 {
7760 date: date.clone(),
7761 dayEl: dayEl,
7762 moreEl: moreEl,
7763 segs: reslicedAllSegs,
7764 hiddenSegs: reslicedHiddenSegs
7765 },
7766 ev,
7767 view
7768 ]
7769 });
7770 }
7771 if (clickOption === 'popover') {
7772 _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
7773 }
7774 else if (typeof clickOption === 'string') { // a view name
7775 view.calendar.zoomTo(date, clickOption);
7776 }
7777 });
7778 };
7779 // Reveals the popover that displays all events within a cell
7780 DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
7781 var _this = this;
7782 var view = this.view;
7783 var moreWrap = moreLink.parent(); // the <div> wrapper around the <a>
7784 var topEl; // the element we want to match the top coordinate of
7785 var options;
7786 if (this.rowCnt === 1) {
7787 topEl = view.el; // will cause the popover to cover any sort of header
7788 }
7789 else {
7790 topEl = this.rowEls.eq(row); // will align with top of row
7791 }
7792 options = {
7793 className: 'fc-more-popover ' + view.calendar.theme.getClass('popover'),
7794 content: this.renderSegPopoverContent(row, col, segs),
7795 parentEl: view.el,
7796 top: topEl.offset().top,
7797 autoHide: true,
7798 viewportConstrain: this.opt('popoverViewportConstrain'),
7799 hide: function () {
7800 // kill everything when the popover is hidden
7801 // notify events to be removed
7802 if (_this.popoverSegs) {
7803 _this.triggerBeforeEventSegsDestroyed(_this.popoverSegs);
7804 }
7805 _this.segPopover.removeElement();
7806 _this.segPopover = null;
7807 _this.popoverSegs = null;
7808 }
7809 };
7810 // Determine horizontal coordinate.
7811 // We use the moreWrap instead of the <td> to avoid border confusion.
7812 if (this.isRTL) {
7813 options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border
7814 }
7815 else {
7816 options.left = moreWrap.offset().left - 1; // -1 to be over cell border
7817 }
7818 this.segPopover = new Popover_1.default(options);
7819 this.segPopover.show();
7820 // the popover doesn't live within the grid's container element, and thus won't get the event
7821 // delegated-handlers for free. attach event-related handlers to the popover.
7822 this.bindAllSegHandlersToEl(this.segPopover.el);
7823 this.triggerAfterEventSegsRendered(segs);
7824 };
7825 // Builds the inner DOM contents of the segment popover
7826 DayGrid.prototype.renderSegPopoverContent = function (row, col, segs) {
7827 var view = this.view;
7828 var theme = view.calendar.theme;
7829 var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat'));
7830 var content = $('<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
7831 '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
7832 '<span class="fc-title">' +
7833 util_1.htmlEscape(title) +
7834 '</span>' +
7835 '<div class="fc-clear"></div>' +
7836 '</div>' +
7837 '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
7838 '<div class="fc-event-container"></div>' +
7839 '</div>');
7840 var segContainer = content.find('.fc-event-container');
7841 var i;
7842 // render each seg's `el` and only return the visible segs
7843 segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true
7844 this.popoverSegs = segs;
7845 for (i = 0; i < segs.length; i++) {
7846 // because segments in the popover are not part of a grid coordinate system, provide a hint to any
7847 // grids that want to do drag-n-drop about which cell it came from
7848 this.hitsNeeded();
7849 segs[i].hit = this.getCellHit(row, col);
7850 this.hitsNotNeeded();
7851 segContainer.append(segs[i].el);
7852 }
7853 return content;
7854 };
7855 // Given the events within an array of segment objects, reslice them to be in a single day
7856 DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
7857 var dayStart = dayDate.clone();
7858 var dayEnd = dayStart.clone().add(1, 'days');
7859 var dayRange = new UnzonedRange_1.default(dayStart, dayEnd);
7860 var newSegs = [];
7861 var i;
7862 var seg;
7863 var slicedRange;
7864 for (i = 0; i < segs.length; i++) {
7865 seg = segs[i];
7866 slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange);
7867 if (slicedRange) {
7868 newSegs.push($.extend({}, seg, {
7869 footprint: new EventFootprint_1.default(new ComponentFootprint_1.default(slicedRange, seg.footprint.componentFootprint.isAllDay), seg.footprint.eventDef, seg.footprint.eventInstance),
7870 isStart: seg.isStart && slicedRange.isStart,
7871 isEnd: seg.isEnd && slicedRange.isEnd
7872 }));
7873 }
7874 }
7875 // force an order because eventsToSegs doesn't guarantee one
7876 // TODO: research if still needed
7877 this.eventRenderer.sortEventSegs(newSegs);
7878 return newSegs;
7879 };
7880 // Generates the text that should be inside a "more" link, given the number of events it represents
7881 DayGrid.prototype.getMoreLinkText = function (num) {
7882 var opt = this.opt('eventLimitText');
7883 if (typeof opt === 'function') {
7884 return opt(num);
7885 }
7886 else {
7887 return '+' + num + ' ' + opt;
7888 }
7889 };
7890 // Returns segments within a given cell.
7891 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
7892 DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
7893 var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
7894 var level = startLevel || 0;
7895 var segs = [];
7896 var seg;
7897 while (level < segMatrix.length) {
7898 seg = segMatrix[level][col];
7899 if (seg) {
7900 segs.push(seg);
7901 }
7902 level++;
7903 }
7904 return segs;
7905 };
7906 return DayGrid;
7907 }(InteractiveDateComponent_1.default));
7908 exports.default = DayGrid;
7909 DayGrid.prototype.eventRendererClass = DayGridEventRenderer_1.default;
7910 DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default;
7911 DayGrid.prototype.helperRendererClass = DayGridHelperRenderer_1.default;
7912 DayGrid.prototype.fillRendererClass = DayGridFillRenderer_1.default;
7913 StandardInteractionsMixin_1.default.mixInto(DayGrid);
7914 DayTableMixin_1.default.mixInto(DayGrid);
7915
7916
7917 /***/ }),
7918 /* 67 */
7919 /***/ (function(module, exports, __webpack_require__) {
7920
7921 Object.defineProperty(exports, "__esModule", { value: true });
7922 var tslib_1 = __webpack_require__(2);
7923 var $ = __webpack_require__(3);
7924 var util_1 = __webpack_require__(4);
7925 var Scroller_1 = __webpack_require__(41);
7926 var View_1 = __webpack_require__(43);
7927 var BasicViewDateProfileGenerator_1 = __webpack_require__(68);
7928 var DayGrid_1 = __webpack_require__(66);
7929 /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
7930 ----------------------------------------------------------------------------------------------------------------------*/
7931 // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
7932 // It is responsible for managing width/height.
7933 var BasicView = /** @class */ (function (_super) {
7934 tslib_1.__extends(BasicView, _super);
7935 function BasicView(calendar, viewSpec) {
7936 var _this = _super.call(this, calendar, viewSpec) || this;
7937 _this.dayGrid = _this.instantiateDayGrid();
7938 _this.dayGrid.isRigid = _this.hasRigidRows();
7939 if (_this.opt('weekNumbers')) {
7940 if (_this.opt('weekNumbersWithinDays')) {
7941 _this.dayGrid.cellWeekNumbersVisible = true;
7942 _this.dayGrid.colWeekNumbersVisible = false;
7943 }
7944 else {
7945 _this.dayGrid.cellWeekNumbersVisible = false;
7946 _this.dayGrid.colWeekNumbersVisible = true;
7947 }
7948 }
7949 _this.addChild(_this.dayGrid);
7950 _this.scroller = new Scroller_1.default({
7951 overflowX: 'hidden',
7952 overflowY: 'auto'
7953 });
7954 return _this;
7955 }
7956 // Generates the DayGrid object this view needs. Draws from this.dayGridClass
7957 BasicView.prototype.instantiateDayGrid = function () {
7958 // generate a subclass on the fly with BasicView-specific behavior
7959 // TODO: cache this subclass
7960 var subclass = makeDayGridSubclass(this.dayGridClass);
7961 return new subclass(this);
7962 };
7963 BasicView.prototype.executeDateRender = function (dateProfile) {
7964 this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit);
7965 _super.prototype.executeDateRender.call(this, dateProfile);
7966 };
7967 BasicView.prototype.renderSkeleton = function () {
7968 var dayGridContainerEl;
7969 var dayGridEl;
7970 this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml());
7971 this.scroller.render();
7972 dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container');
7973 dayGridEl = $('<div class="fc-day-grid">').appendTo(dayGridContainerEl);
7974 this.el.find('.fc-body > tr > td').append(dayGridContainerEl);
7975 this.dayGrid.headContainerEl = this.el.find('.fc-head-container');
7976 this.dayGrid.setElement(dayGridEl);
7977 };
7978 BasicView.prototype.unrenderSkeleton = function () {
7979 this.dayGrid.removeElement();
7980 this.scroller.destroy();
7981 };
7982 // Builds the HTML skeleton for the view.
7983 // The day-grid component will render inside of a container defined by this HTML.
7984 BasicView.prototype.renderSkeletonHtml = function () {
7985 var theme = this.calendar.theme;
7986 return '' +
7987 '<table class="' + theme.getClass('tableGrid') + '">' +
7988 (this.opt('columnHeader') ?
7989 '<thead class="fc-head">' +
7990 '<tr>' +
7991 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
7992 '</tr>' +
7993 '</thead>' :
7994 '') +
7995 '<tbody class="fc-body">' +
7996 '<tr>' +
7997 '<td class="' + theme.getClass('widgetContent') + '"></td>' +
7998 '</tr>' +
7999 '</tbody>' +
8000 '</table>';
8001 };
8002 // Generates an HTML attribute string for setting the width of the week number column, if it is known
8003 BasicView.prototype.weekNumberStyleAttr = function () {
8004 if (this.weekNumberWidth != null) {
8005 return 'style="width:' + this.weekNumberWidth + 'px"';
8006 }
8007 return '';
8008 };
8009 // Determines whether each row should have a constant height
8010 BasicView.prototype.hasRigidRows = function () {
8011 var eventLimit = this.opt('eventLimit');
8012 return eventLimit && typeof eventLimit !== 'number';
8013 };
8014 /* Dimensions
8015 ------------------------------------------------------------------------------------------------------------------*/
8016 // Refreshes the horizontal dimensions of the view
8017 BasicView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
8018 var eventLimit = this.opt('eventLimit');
8019 var headRowEl = this.dayGrid.headContainerEl.find('.fc-row');
8020 var scrollerHeight;
8021 var scrollbarWidths;
8022 // hack to give the view some height prior to dayGrid's columns being rendered
8023 // TODO: separate setting height from scroller VS dayGrid.
8024 if (!this.dayGrid.rowEls) {
8025 if (!isAuto) {
8026 scrollerHeight = this.computeScrollerHeight(totalHeight);
8027 this.scroller.setHeight(scrollerHeight);
8028 }
8029 return;
8030 }
8031 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
8032 if (this.dayGrid.colWeekNumbersVisible) {
8033 // Make sure all week number cells running down the side have the same width.
8034 // Record the width for cells created later.
8035 this.weekNumberWidth = util_1.matchCellWidths(this.el.find('.fc-week-number'));
8036 }
8037 // reset all heights to be natural
8038 this.scroller.clear();
8039 util_1.uncompensateScroll(headRowEl);
8040 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
8041 // is the event limit a constant level number?
8042 if (eventLimit && typeof eventLimit === 'number') {
8043 this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
8044 }
8045 // distribute the height to the rows
8046 // (totalHeight is a "recommended" value if isAuto)
8047 scrollerHeight = this.computeScrollerHeight(totalHeight);
8048 this.setGridHeight(scrollerHeight, isAuto);
8049 // is the event limit dynamically calculated?
8050 if (eventLimit && typeof eventLimit !== 'number') {
8051 this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
8052 }
8053 if (!isAuto) { // should we force dimensions of the scroll container?
8054 this.scroller.setHeight(scrollerHeight);
8055 scrollbarWidths = this.scroller.getScrollbarWidths();
8056 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
8057 util_1.compensateScroll(headRowEl, scrollbarWidths);
8058 // doing the scrollbar compensation might have created text overflow which created more height. redo
8059 scrollerHeight = this.computeScrollerHeight(totalHeight);
8060 this.scroller.setHeight(scrollerHeight);
8061 }
8062 // guarantees the same scrollbar widths
8063 this.scroller.lockOverflow(scrollbarWidths);
8064 }
8065 };
8066 // given a desired total height of the view, returns what the height of the scroller should be
8067 BasicView.prototype.computeScrollerHeight = function (totalHeight) {
8068 return totalHeight -
8069 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
8070 };
8071 // Sets the height of just the DayGrid component in this view
8072 BasicView.prototype.setGridHeight = function (height, isAuto) {
8073 if (isAuto) {
8074 util_1.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
8075 }
8076 else {
8077 util_1.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
8078 }
8079 };
8080 /* Scroll
8081 ------------------------------------------------------------------------------------------------------------------*/
8082 BasicView.prototype.computeInitialDateScroll = function () {
8083 return { top: 0 };
8084 };
8085 BasicView.prototype.queryDateScroll = function () {
8086 return { top: this.scroller.getScrollTop() };
8087 };
8088 BasicView.prototype.applyDateScroll = function (scroll) {
8089 if (scroll.top !== undefined) {
8090 this.scroller.setScrollTop(scroll.top);
8091 }
8092 };
8093 return BasicView;
8094 }(View_1.default));
8095 exports.default = BasicView;
8096 BasicView.prototype.dateProfileGeneratorClass = BasicViewDateProfileGenerator_1.default;
8097 BasicView.prototype.dayGridClass = DayGrid_1.default;
8098 // customize the rendering behavior of BasicView's dayGrid
8099 function makeDayGridSubclass(SuperClass) {
8100 return /** @class */ (function (_super) {
8101 tslib_1.__extends(SubClass, _super);
8102 function SubClass() {
8103 var _this = _super !== null && _super.apply(this, arguments) || this;
8104 _this.colWeekNumbersVisible = false; // display week numbers along the side?
8105 return _this;
8106 }
8107 // Generates the HTML that will go before the day-of week header cells
8108 SubClass.prototype.renderHeadIntroHtml = function () {
8109 var view = this.view;
8110 if (this.colWeekNumbersVisible) {
8111 return '' +
8112 '<th class="fc-week-number ' + view.calendar.theme.getClass('widgetHeader') + '" ' + view.weekNumberStyleAttr() + '>' +
8113 '<span>' + // needed for matchCellWidths
8114 util_1.htmlEscape(this.opt('weekNumberTitle')) +
8115 '</span>' +
8116 '</th>';
8117 }
8118 return '';
8119 };
8120 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
8121 SubClass.prototype.renderNumberIntroHtml = function (row) {
8122 var view = this.view;
8123 var weekStart = this.getCellDate(row, 0);
8124 if (this.colWeekNumbersVisible) {
8125 return '' +
8126 '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' +
8127 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
8128 { date: weekStart, type: 'week', forceOff: this.colCnt === 1 }, weekStart.format('w') // inner HTML
8129 ) +
8130 '</td>';
8131 }
8132 return '';
8133 };
8134 // Generates the HTML that goes before the day bg cells for each day-row
8135 SubClass.prototype.renderBgIntroHtml = function () {
8136 var view = this.view;
8137 if (this.colWeekNumbersVisible) {
8138 return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' +
8139 view.weekNumberStyleAttr() + '></td>';
8140 }
8141 return '';
8142 };
8143 // Generates the HTML that goes before every other type of row generated by DayGrid.
8144 // Affects helper-skeleton and highlight-skeleton rows.
8145 SubClass.prototype.renderIntroHtml = function () {
8146 var view = this.view;
8147 if (this.colWeekNumbersVisible) {
8148 return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>';
8149 }
8150 return '';
8151 };
8152 SubClass.prototype.getIsNumbersVisible = function () {
8153 return DayGrid_1.default.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible;
8154 };
8155 return SubClass;
8156 }(SuperClass));
8157 }
8158
8159
8160 /***/ }),
8161 /* 68 */
8162 /***/ (function(module, exports, __webpack_require__) {
8163
8164 Object.defineProperty(exports, "__esModule", { value: true });
8165 var tslib_1 = __webpack_require__(2);
8166 var UnzonedRange_1 = __webpack_require__(5);
8167 var DateProfileGenerator_1 = __webpack_require__(55);
8168 var BasicViewDateProfileGenerator = /** @class */ (function (_super) {
8169 tslib_1.__extends(BasicViewDateProfileGenerator, _super);
8170 function BasicViewDateProfileGenerator() {
8171 return _super !== null && _super.apply(this, arguments) || this;
8172 }
8173 // Computes the date range that will be rendered.
8174 BasicViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
8175 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange
8176 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
8177 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
8178 // year and month views should be aligned with weeks. this is already done for week
8179 if (/^(year|month)$/.test(currentRangeUnit)) {
8180 start.startOf('week');
8181 // make end-of-week if not already
8182 if (end.weekday()) {
8183 end.add(1, 'week').startOf('week'); // exclusively move backwards
8184 }
8185 }
8186 return new UnzonedRange_1.default(start, end);
8187 };
8188 return BasicViewDateProfileGenerator;
8189 }(DateProfileGenerator_1.default));
8190 exports.default = BasicViewDateProfileGenerator;
8191
8192
8193 /***/ }),
8194 /* 69 */,
8195 /* 70 */,
8196 /* 71 */,
8197 /* 72 */,
8198 /* 73 */,
8199 /* 74 */,
8200 /* 75 */,
8201 /* 76 */,
8202 /* 77 */,
8203 /* 78 */,
8204 /* 79 */,
8205 /* 80 */,
8206 /* 81 */,
8207 /* 82 */,
8208 /* 83 */,
8209 /* 84 */,
8210 /* 85 */,
8211 /* 86 */,
8212 /* 87 */,
8213 /* 88 */,
8214 /* 89 */,
8215 /* 90 */,
8216 /* 91 */,
8217 /* 92 */,
8218 /* 93 */,
8219 /* 94 */,
8220 /* 95 */,
8221 /* 96 */,
8222 /* 97 */,
8223 /* 98 */,
8224 /* 99 */,
8225 /* 100 */,
8226 /* 101 */,
8227 /* 102 */,
8228 /* 103 */,
8229 /* 104 */,
8230 /* 105 */,
8231 /* 106 */,
8232 /* 107 */,
8233 /* 108 */,
8234 /* 109 */,
8235 /* 110 */,
8236 /* 111 */,
8237 /* 112 */,
8238 /* 113 */,
8239 /* 114 */,
8240 /* 115 */,
8241 /* 116 */,
8242 /* 117 */,
8243 /* 118 */,
8244 /* 119 */,
8245 /* 120 */,
8246 /* 121 */,
8247 /* 122 */,
8248 /* 123 */,
8249 /* 124 */,
8250 /* 125 */,
8251 /* 126 */,
8252 /* 127 */,
8253 /* 128 */,
8254 /* 129 */,
8255 /* 130 */,
8256 /* 131 */,
8257 /* 132 */,
8258 /* 133 */,
8259 /* 134 */,
8260 /* 135 */,
8261 /* 136 */,
8262 /* 137 */,
8263 /* 138 */,
8264 /* 139 */,
8265 /* 140 */,
8266 /* 141 */,
8267 /* 142 */,
8268 /* 143 */,
8269 /* 144 */,
8270 /* 145 */,
8271 /* 146 */,
8272 /* 147 */,
8273 /* 148 */,
8274 /* 149 */,
8275 /* 150 */,
8276 /* 151 */,
8277 /* 152 */,
8278 /* 153 */,
8279 /* 154 */,
8280 /* 155 */,
8281 /* 156 */,
8282 /* 157 */,
8283 /* 158 */,
8284 /* 159 */,
8285 /* 160 */,
8286 /* 161 */,
8287 /* 162 */,
8288 /* 163 */,
8289 /* 164 */,
8290 /* 165 */,
8291 /* 166 */,
8292 /* 167 */,
8293 /* 168 */,
8294 /* 169 */,
8295 /* 170 */,
8296 /* 171 */,
8297 /* 172 */,
8298 /* 173 */,
8299 /* 174 */,
8300 /* 175 */,
8301 /* 176 */,
8302 /* 177 */,
8303 /* 178 */,
8304 /* 179 */,
8305 /* 180 */,
8306 /* 181 */,
8307 /* 182 */,
8308 /* 183 */,
8309 /* 184 */,
8310 /* 185 */,
8311 /* 186 */,
8312 /* 187 */,
8313 /* 188 */,
8314 /* 189 */,
8315 /* 190 */,
8316 /* 191 */,
8317 /* 192 */,
8318 /* 193 */,
8319 /* 194 */,
8320 /* 195 */,
8321 /* 196 */,
8322 /* 197 */,
8323 /* 198 */,
8324 /* 199 */,
8325 /* 200 */,
8326 /* 201 */,
8327 /* 202 */,
8328 /* 203 */,
8329 /* 204 */,
8330 /* 205 */,
8331 /* 206 */,
8332 /* 207 */,
8333 /* 208 */,
8334 /* 209 */,
8335 /* 210 */,
8336 /* 211 */,
8337 /* 212 */,
8338 /* 213 */,
8339 /* 214 */,
8340 /* 215 */,
8341 /* 216 */,
8342 /* 217 */
8343 /***/ (function(module, exports, __webpack_require__) {
8344
8345 Object.defineProperty(exports, "__esModule", { value: true });
8346 var UnzonedRange_1 = __webpack_require__(5);
8347 var ComponentFootprint_1 = __webpack_require__(12);
8348 var EventDefParser_1 = __webpack_require__(36);
8349 var EventSource_1 = __webpack_require__(6);
8350 var util_1 = __webpack_require__(19);
8351 var Constraints = /** @class */ (function () {
8352 function Constraints(eventManager, _calendar) {
8353 this.eventManager = eventManager;
8354 this._calendar = _calendar;
8355 }
8356 Constraints.prototype.opt = function (name) {
8357 return this._calendar.opt(name);
8358 };
8359 /*
8360 determines if eventInstanceGroup is allowed,
8361 in relation to other EVENTS and business hours.
8362 */
8363 Constraints.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) {
8364 var eventDef = eventInstanceGroup.getEventDef();
8365 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
8366 var i;
8367 var peerEventInstances = this.getPeerEventInstances(eventDef);
8368 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange);
8369 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
8370 var constraintVal = eventDef.getConstraint();
8371 var overlapVal = eventDef.getOverlap();
8372 var eventAllowFunc = this.opt('eventAllow');
8373 for (i = 0; i < eventFootprints.length; i++) {
8374 if (!this.isFootprintAllowed(eventFootprints[i].componentFootprint, peerEventFootprints, constraintVal, overlapVal, eventFootprints[i].eventInstance)) {
8375 return false;
8376 }
8377 }
8378 if (eventAllowFunc) {
8379 for (i = 0; i < eventFootprints.length; i++) {
8380 if (eventAllowFunc(eventFootprints[i].componentFootprint.toLegacy(this._calendar), eventFootprints[i].getEventLegacy()) === false) {
8381 return false;
8382 }
8383 }
8384 }
8385 return true;
8386 };
8387 Constraints.prototype.getPeerEventInstances = function (eventDef) {
8388 return this.eventManager.getEventInstancesWithoutId(eventDef.id);
8389 };
8390 Constraints.prototype.isSelectionFootprintAllowed = function (componentFootprint) {
8391 var peerEventInstances = this.eventManager.getEventInstances();
8392 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange);
8393 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
8394 var selectAllowFunc;
8395 if (this.isFootprintAllowed(componentFootprint, peerEventFootprints, this.opt('selectConstraint'), this.opt('selectOverlap'))) {
8396 selectAllowFunc = this.opt('selectAllow');
8397 if (selectAllowFunc) {
8398 return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false;
8399 }
8400 else {
8401 return true;
8402 }
8403 }
8404 return false;
8405 };
8406 Constraints.prototype.isFootprintAllowed = function (componentFootprint, peerEventFootprints, constraintVal, overlapVal, subjectEventInstance // optional
8407 ) {
8408 var constraintFootprints; // ComponentFootprint[]
8409 var overlapEventFootprints; // EventFootprint[]
8410 if (constraintVal != null) {
8411 constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay);
8412 if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) {
8413 return false;
8414 }
8415 }
8416 overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint);
8417 if (overlapVal === false) {
8418 if (overlapEventFootprints.length) {
8419 return false;
8420 }
8421 }
8422 else if (typeof overlapVal === 'function') {
8423 if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) {
8424 return false;
8425 }
8426 }
8427 if (subjectEventInstance) {
8428 if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) {
8429 return false;
8430 }
8431 }
8432 return true;
8433 };
8434 // Constraint
8435 // ------------------------------------------------------------------------------------------------
8436 Constraints.prototype.isFootprintWithinConstraints = function (componentFootprint, constraintFootprints) {
8437 var i;
8438 for (i = 0; i < constraintFootprints.length; i++) {
8439 if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) {
8440 return true;
8441 }
8442 }
8443 return false;
8444 };
8445 Constraints.prototype.constraintValToFootprints = function (constraintVal, isAllDay) {
8446 var eventInstances;
8447 if (constraintVal === 'businessHours') {
8448 return this.buildCurrentBusinessFootprints(isAllDay);
8449 }
8450 else if (typeof constraintVal === 'object') {
8451 eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events
8452 if (!eventInstances) { // invalid input. fallback to parsing footprint directly
8453 return this.parseFootprints(constraintVal);
8454 }
8455 else {
8456 return this.eventInstancesToFootprints(eventInstances);
8457 }
8458 }
8459 else if (constraintVal != null) { // an ID
8460 eventInstances = this.eventManager.getEventInstancesWithId(constraintVal);
8461 return this.eventInstancesToFootprints(eventInstances);
8462 }
8463 };
8464 // returns ComponentFootprint[]
8465 // uses current view's range
8466 Constraints.prototype.buildCurrentBusinessFootprints = function (isAllDay) {
8467 var view = this._calendar.view;
8468 var businessHourGenerator = view.get('businessHourGenerator');
8469 var unzonedRange = view.dateProfile.activeUnzonedRange;
8470 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange);
8471 if (eventInstanceGroup) {
8472 return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances);
8473 }
8474 else {
8475 return [];
8476 }
8477 };
8478 // conversion util
8479 Constraints.prototype.eventInstancesToFootprints = function (eventInstances) {
8480 var eventRanges = eventInstances.map(util_1.eventInstanceToEventRange);
8481 var eventFootprints = this.eventRangesToEventFootprints(eventRanges);
8482 return eventFootprints.map(util_1.eventFootprintToComponentFootprint);
8483 };
8484 // Overlap
8485 // ------------------------------------------------------------------------------------------------
8486 Constraints.prototype.collectOverlapEventFootprints = function (peerEventFootprints, targetFootprint) {
8487 var overlapEventFootprints = [];
8488 var i;
8489 for (i = 0; i < peerEventFootprints.length; i++) {
8490 if (this.footprintsIntersect(targetFootprint, peerEventFootprints[i].componentFootprint)) {
8491 overlapEventFootprints.push(peerEventFootprints[i]);
8492 }
8493 }
8494 return overlapEventFootprints;
8495 };
8496 // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints
8497 // ------------------------------------------------------------------------------------------------
8498 // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to
8499 // constraints whereas the Grid code is related to rendering. Each approach might want to convert
8500 // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make
8501 // this more DRY.
8502 /*
8503 Returns false on invalid input.
8504 */
8505 Constraints.prototype.parseEventDefToInstances = function (eventInput) {
8506 var eventManager = this.eventManager;
8507 var eventDef = EventDefParser_1.default.parse(eventInput, new EventSource_1.default(this._calendar));
8508 if (!eventDef) { // invalid
8509 return false;
8510 }
8511 return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange);
8512 };
8513 Constraints.prototype.eventRangesToEventFootprints = function (eventRanges) {
8514 var i;
8515 var eventFootprints = [];
8516 for (i = 0; i < eventRanges.length; i++) {
8517 eventFootprints.push.apply(// footprints
8518 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i]));
8519 }
8520 return eventFootprints;
8521 };
8522 Constraints.prototype.eventRangeToEventFootprints = function (eventRange) {
8523 return [util_1.eventRangeToEventFootprint(eventRange)];
8524 };
8525 /*
8526 Parses footprints directly.
8527 Very similar to EventDateProfile::parse :(
8528 */
8529 Constraints.prototype.parseFootprints = function (rawInput) {
8530 var start;
8531 var end;
8532 if (rawInput.start) {
8533 start = this._calendar.moment(rawInput.start);
8534 if (!start.isValid()) {
8535 start = null;
8536 }
8537 }
8538 if (rawInput.end) {
8539 end = this._calendar.moment(rawInput.end);
8540 if (!end.isValid()) {
8541 end = null;
8542 }
8543 }
8544 return [
8545 new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay
8546 )
8547 ];
8548 };
8549 // Footprint Utils
8550 // ----------------------------------------------------------------------------------------
8551 Constraints.prototype.footprintContainsFootprint = function (outerFootprint, innerFootprint) {
8552 return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange);
8553 };
8554 Constraints.prototype.footprintsIntersect = function (footprint0, footprint1) {
8555 return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange);
8556 };
8557 return Constraints;
8558 }());
8559 exports.default = Constraints;
8560 // optional subjectEventInstance
8561 function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) {
8562 var i;
8563 for (i = 0; i < overlapEventFootprints.length; i++) {
8564 if (!overlapFunc(overlapEventFootprints[i].eventInstance.toLegacy(), subjectEventInstance ? subjectEventInstance.toLegacy() : null)) {
8565 return false;
8566 }
8567 }
8568 return true;
8569 }
8570 function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) {
8571 var subjectLegacyInstance = subjectEventInstance.toLegacy();
8572 var i;
8573 var overlapEventInstance;
8574 var overlapEventDef;
8575 var overlapVal;
8576 for (i = 0; i < overlapEventFootprints.length; i++) {
8577 overlapEventInstance = overlapEventFootprints[i].eventInstance;
8578 overlapEventDef = overlapEventInstance.def;
8579 // don't need to pass in calendar, because don't want to consider global eventOverlap property,
8580 // because we already considered that earlier in the process.
8581 overlapVal = overlapEventDef.getOverlap();
8582 if (overlapVal === false) {
8583 return false;
8584 }
8585 else if (typeof overlapVal === 'function') {
8586 if (!overlapVal(overlapEventInstance.toLegacy(), subjectLegacyInstance)) {
8587 return false;
8588 }
8589 }
8590 }
8591 return true;
8592 }
8593
8594
8595 /***/ }),
8596 /* 218 */
8597 /***/ (function(module, exports, __webpack_require__) {
8598
8599 Object.defineProperty(exports, "__esModule", { value: true });
8600 var $ = __webpack_require__(3);
8601 var util_1 = __webpack_require__(19);
8602 var EventInstanceGroup_1 = __webpack_require__(20);
8603 var RecurringEventDef_1 = __webpack_require__(54);
8604 var EventSource_1 = __webpack_require__(6);
8605 var BUSINESS_HOUR_EVENT_DEFAULTS = {
8606 start: '09:00',
8607 end: '17:00',
8608 dow: [1, 2, 3, 4, 5],
8609 rendering: 'inverse-background'
8610 // classNames are defined in businessHoursSegClasses
8611 };
8612 var BusinessHourGenerator = /** @class */ (function () {
8613 function BusinessHourGenerator(rawComplexDef, calendar) {
8614 this.rawComplexDef = rawComplexDef;
8615 this.calendar = calendar;
8616 }
8617 BusinessHourGenerator.prototype.buildEventInstanceGroup = function (isAllDay, unzonedRange) {
8618 var eventDefs = this.buildEventDefs(isAllDay);
8619 var eventInstanceGroup;
8620 if (eventDefs.length) {
8621 eventInstanceGroup = new EventInstanceGroup_1.default(util_1.eventDefsToEventInstances(eventDefs, unzonedRange));
8622 // so that inverse-background rendering can happen even when no eventRanges in view
8623 eventInstanceGroup.explicitEventDef = eventDefs[0];
8624 return eventInstanceGroup;
8625 }
8626 };
8627 BusinessHourGenerator.prototype.buildEventDefs = function (isAllDay) {
8628 var rawComplexDef = this.rawComplexDef;
8629 var rawDefs = [];
8630 var requireDow = false;
8631 var i;
8632 var defs = [];
8633 if (rawComplexDef === true) {
8634 rawDefs = [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
8635 }
8636 else if ($.isPlainObject(rawComplexDef)) {
8637 rawDefs = [rawComplexDef];
8638 }
8639 else if ($.isArray(rawComplexDef)) {
8640 rawDefs = rawComplexDef;
8641 requireDow = true; // every sub-definition NEEDS a day-of-week
8642 }
8643 for (i = 0; i < rawDefs.length; i++) {
8644 if (!requireDow || rawDefs[i].dow) {
8645 defs.push(this.buildEventDef(isAllDay, rawDefs[i]));
8646 }
8647 }
8648 return defs;
8649 };
8650 BusinessHourGenerator.prototype.buildEventDef = function (isAllDay, rawDef) {
8651 var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef);
8652 if (isAllDay) {
8653 fullRawDef.start = null;
8654 fullRawDef.end = null;
8655 }
8656 return RecurringEventDef_1.default.parse(fullRawDef, new EventSource_1.default(this.calendar) // dummy source
8657 );
8658 };
8659 return BusinessHourGenerator;
8660 }());
8661 exports.default = BusinessHourGenerator;
8662
8663
8664 /***/ }),
8665 /* 219 */
8666 /***/ (function(module, exports, __webpack_require__) {
8667
8668 Object.defineProperty(exports, "__esModule", { value: true });
8669 var $ = __webpack_require__(3);
8670 var util_1 = __webpack_require__(4);
8671 var Promise_1 = __webpack_require__(21);
8672 var EmitterMixin_1 = __webpack_require__(13);
8673 var UnzonedRange_1 = __webpack_require__(5);
8674 var EventInstanceGroup_1 = __webpack_require__(20);
8675 var EventPeriod = /** @class */ (function () {
8676 function EventPeriod(start, end, timezone) {
8677 this.pendingCnt = 0;
8678 this.freezeDepth = 0;
8679 this.stuntedReleaseCnt = 0;
8680 this.releaseCnt = 0;
8681 this.start = start;
8682 this.end = end;
8683 this.timezone = timezone;
8684 this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone());
8685 this.requestsByUid = {};
8686 this.eventDefsByUid = {};
8687 this.eventDefsById = {};
8688 this.eventInstanceGroupsById = {};
8689 }
8690 EventPeriod.prototype.isWithinRange = function (start, end) {
8691 // TODO: use a range util function?
8692 return !start.isBefore(this.start) && !end.isAfter(this.end);
8693 };
8694 // Requesting and Purging
8695 // -----------------------------------------------------------------------------------------------------------------
8696 EventPeriod.prototype.requestSources = function (sources) {
8697 this.freeze();
8698 for (var i = 0; i < sources.length; i++) {
8699 this.requestSource(sources[i]);
8700 }
8701 this.thaw();
8702 };
8703 EventPeriod.prototype.requestSource = function (source) {
8704 var _this = this;
8705 var request = { source: source, status: 'pending', eventDefs: null };
8706 this.requestsByUid[source.uid] = request;
8707 this.pendingCnt += 1;
8708 source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) {
8709 if (request.status !== 'cancelled') {
8710 request.status = 'completed';
8711 request.eventDefs = eventDefs;
8712 _this.addEventDefs(eventDefs);
8713 _this.pendingCnt--;
8714 _this.tryRelease();
8715 }
8716 }, function () {
8717 if (request.status !== 'cancelled') {
8718 request.status = 'failed';
8719 _this.pendingCnt--;
8720 _this.tryRelease();
8721 }
8722 });
8723 };
8724 EventPeriod.prototype.purgeSource = function (source) {
8725 var request = this.requestsByUid[source.uid];
8726 if (request) {
8727 delete this.requestsByUid[source.uid];
8728 if (request.status === 'pending') {
8729 request.status = 'cancelled';
8730 this.pendingCnt--;
8731 this.tryRelease();
8732 }
8733 else if (request.status === 'completed') {
8734 request.eventDefs.forEach(this.removeEventDef.bind(this));
8735 }
8736 }
8737 };
8738 EventPeriod.prototype.purgeAllSources = function () {
8739 var requestsByUid = this.requestsByUid;
8740 var uid;
8741 var request;
8742 var completedCnt = 0;
8743 for (uid in requestsByUid) {
8744 request = requestsByUid[uid];
8745 if (request.status === 'pending') {
8746 request.status = 'cancelled';
8747 }
8748 else if (request.status === 'completed') {
8749 completedCnt++;
8750 }
8751 }
8752 this.requestsByUid = {};
8753 this.pendingCnt = 0;
8754 if (completedCnt) {
8755 this.removeAllEventDefs(); // might release
8756 }
8757 };
8758 // Event Definitions
8759 // -----------------------------------------------------------------------------------------------------------------
8760 EventPeriod.prototype.getEventDefByUid = function (eventDefUid) {
8761 return this.eventDefsByUid[eventDefUid];
8762 };
8763 EventPeriod.prototype.getEventDefsById = function (eventDefId) {
8764 var a = this.eventDefsById[eventDefId];
8765 if (a) {
8766 return a.slice(); // clone
8767 }
8768 return [];
8769 };
8770 EventPeriod.prototype.addEventDefs = function (eventDefs) {
8771 for (var i = 0; i < eventDefs.length; i++) {
8772 this.addEventDef(eventDefs[i]);
8773 }
8774 };
8775 EventPeriod.prototype.addEventDef = function (eventDef) {
8776 var eventDefsById = this.eventDefsById;
8777 var eventDefId = eventDef.id;
8778 var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []);
8779 var eventInstances = eventDef.buildInstances(this.unzonedRange);
8780 var i;
8781 eventDefs.push(eventDef);
8782 this.eventDefsByUid[eventDef.uid] = eventDef;
8783 for (i = 0; i < eventInstances.length; i++) {
8784 this.addEventInstance(eventInstances[i], eventDefId);
8785 }
8786 };
8787 EventPeriod.prototype.removeEventDefsById = function (eventDefId) {
8788 var _this = this;
8789 this.getEventDefsById(eventDefId).forEach(function (eventDef) {
8790 _this.removeEventDef(eventDef);
8791 });
8792 };
8793 EventPeriod.prototype.removeAllEventDefs = function () {
8794 var isEmpty = $.isEmptyObject(this.eventDefsByUid);
8795 this.eventDefsByUid = {};
8796 this.eventDefsById = {};
8797 this.eventInstanceGroupsById = {};
8798 if (!isEmpty) {
8799 this.tryRelease();
8800 }
8801 };
8802 EventPeriod.prototype.removeEventDef = function (eventDef) {
8803 var eventDefsById = this.eventDefsById;
8804 var eventDefs = eventDefsById[eventDef.id];
8805 delete this.eventDefsByUid[eventDef.uid];
8806 if (eventDefs) {
8807 util_1.removeExact(eventDefs, eventDef);
8808 if (!eventDefs.length) {
8809 delete eventDefsById[eventDef.id];
8810 }
8811 this.removeEventInstancesForDef(eventDef);
8812 }
8813 };
8814 // Event Instances
8815 // -----------------------------------------------------------------------------------------------------------------
8816 EventPeriod.prototype.getEventInstances = function () {
8817 var eventInstanceGroupsById = this.eventInstanceGroupsById;
8818 var eventInstances = [];
8819 var id;
8820 for (id in eventInstanceGroupsById) {
8821 eventInstances.push.apply(eventInstances, // append
8822 eventInstanceGroupsById[id].eventInstances);
8823 }
8824 return eventInstances;
8825 };
8826 EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) {
8827 var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId];
8828 if (eventInstanceGroup) {
8829 return eventInstanceGroup.eventInstances.slice(); // clone
8830 }
8831 return [];
8832 };
8833 EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) {
8834 var eventInstanceGroupsById = this.eventInstanceGroupsById;
8835 var matchingInstances = [];
8836 var id;
8837 for (id in eventInstanceGroupsById) {
8838 if (id !== eventDefId) {
8839 matchingInstances.push.apply(matchingInstances, // append
8840 eventInstanceGroupsById[id].eventInstances);
8841 }
8842 }
8843 return matchingInstances;
8844 };
8845 EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) {
8846 var eventInstanceGroupsById = this.eventInstanceGroupsById;
8847 var eventInstanceGroup = eventInstanceGroupsById[eventDefId] ||
8848 (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default());
8849 eventInstanceGroup.eventInstances.push(eventInstance);
8850 this.tryRelease();
8851 };
8852 EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) {
8853 var eventInstanceGroupsById = this.eventInstanceGroupsById;
8854 var eventInstanceGroup = eventInstanceGroupsById[eventDef.id];
8855 var removeCnt;
8856 if (eventInstanceGroup) {
8857 removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) {
8858 return currentEventInstance.def === eventDef;
8859 });
8860 if (!eventInstanceGroup.eventInstances.length) {
8861 delete eventInstanceGroupsById[eventDef.id];
8862 }
8863 if (removeCnt) {
8864 this.tryRelease();
8865 }
8866 }
8867 };
8868 // Releasing and Freezing
8869 // -----------------------------------------------------------------------------------------------------------------
8870 EventPeriod.prototype.tryRelease = function () {
8871 if (!this.pendingCnt) {
8872 if (!this.freezeDepth) {
8873 this.release();
8874 }
8875 else {
8876 this.stuntedReleaseCnt++;
8877 }
8878 }
8879 };
8880 EventPeriod.prototype.release = function () {
8881 this.releaseCnt++;
8882 this.trigger('release', this.eventInstanceGroupsById);
8883 };
8884 EventPeriod.prototype.whenReleased = function () {
8885 var _this = this;
8886 if (this.releaseCnt) {
8887 return Promise_1.default.resolve(this.eventInstanceGroupsById);
8888 }
8889 else {
8890 return Promise_1.default.construct(function (onResolve) {
8891 _this.one('release', onResolve);
8892 });
8893 }
8894 };
8895 EventPeriod.prototype.freeze = function () {
8896 if (!(this.freezeDepth++)) {
8897 this.stuntedReleaseCnt = 0;
8898 }
8899 };
8900 EventPeriod.prototype.thaw = function () {
8901 if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) {
8902 this.release();
8903 }
8904 };
8905 return EventPeriod;
8906 }());
8907 exports.default = EventPeriod;
8908 EmitterMixin_1.default.mixInto(EventPeriod);
8909
8910
8911 /***/ }),
8912 /* 220 */
8913 /***/ (function(module, exports, __webpack_require__) {
8914
8915 Object.defineProperty(exports, "__esModule", { value: true });
8916 var $ = __webpack_require__(3);
8917 var util_1 = __webpack_require__(4);
8918 var EventPeriod_1 = __webpack_require__(219);
8919 var ArrayEventSource_1 = __webpack_require__(56);
8920 var EventSource_1 = __webpack_require__(6);
8921 var EventSourceParser_1 = __webpack_require__(38);
8922 var SingleEventDef_1 = __webpack_require__(9);
8923 var EventInstanceGroup_1 = __webpack_require__(20);
8924 var EmitterMixin_1 = __webpack_require__(13);
8925 var ListenerMixin_1 = __webpack_require__(7);
8926 var EventManager = /** @class */ (function () {
8927 function EventManager(calendar) {
8928 this.calendar = calendar;
8929 this.stickySource = new ArrayEventSource_1.default(calendar);
8930 this.otherSources = [];
8931 }
8932 EventManager.prototype.requestEvents = function (start, end, timezone, force) {
8933 if (force ||
8934 !this.currentPeriod ||
8935 !this.currentPeriod.isWithinRange(start, end) ||
8936 timezone !== this.currentPeriod.timezone) {
8937 this.setPeriod(// will change this.currentPeriod
8938 new EventPeriod_1.default(start, end, timezone));
8939 }
8940 return this.currentPeriod.whenReleased();
8941 };
8942 // Source Adding/Removing
8943 // -----------------------------------------------------------------------------------------------------------------
8944 EventManager.prototype.addSource = function (eventSource) {
8945 this.otherSources.push(eventSource);
8946 if (this.currentPeriod) {
8947 this.currentPeriod.requestSource(eventSource); // might release
8948 }
8949 };
8950 EventManager.prototype.removeSource = function (doomedSource) {
8951 util_1.removeExact(this.otherSources, doomedSource);
8952 if (this.currentPeriod) {
8953 this.currentPeriod.purgeSource(doomedSource); // might release
8954 }
8955 };
8956 EventManager.prototype.removeAllSources = function () {
8957 this.otherSources = [];
8958 if (this.currentPeriod) {
8959 this.currentPeriod.purgeAllSources(); // might release
8960 }
8961 };
8962 // Source Refetching
8963 // -----------------------------------------------------------------------------------------------------------------
8964 EventManager.prototype.refetchSource = function (eventSource) {
8965 var currentPeriod = this.currentPeriod;
8966 if (currentPeriod) {
8967 currentPeriod.freeze();
8968 currentPeriod.purgeSource(eventSource);
8969 currentPeriod.requestSource(eventSource);
8970 currentPeriod.thaw();
8971 }
8972 };
8973 EventManager.prototype.refetchAllSources = function () {
8974 var currentPeriod = this.currentPeriod;
8975 if (currentPeriod) {
8976 currentPeriod.freeze();
8977 currentPeriod.purgeAllSources();
8978 currentPeriod.requestSources(this.getSources());
8979 currentPeriod.thaw();
8980 }
8981 };
8982 // Source Querying
8983 // -----------------------------------------------------------------------------------------------------------------
8984 EventManager.prototype.getSources = function () {
8985 return [this.stickySource].concat(this.otherSources);
8986 };
8987 // like querySources, but accepts multple match criteria (like multiple IDs)
8988 EventManager.prototype.multiQuerySources = function (matchInputs) {
8989 // coerce into an array
8990 if (!matchInputs) {
8991 matchInputs = [];
8992 }
8993 else if (!$.isArray(matchInputs)) {
8994 matchInputs = [matchInputs];
8995 }
8996 var matchingSources = [];
8997 var i;
8998 // resolve raw inputs to real event source objects
8999 for (i = 0; i < matchInputs.length; i++) {
9000 matchingSources.push.apply(// append
9001 matchingSources, this.querySources(matchInputs[i]));
9002 }
9003 return matchingSources;
9004 };
9005 // matchInput can either by a real event source object, an ID, or the function/URL for the source.
9006 // returns an array of matching source objects.
9007 EventManager.prototype.querySources = function (matchInput) {
9008 var sources = this.otherSources;
9009 var i;
9010 var source;
9011 // given a proper event source object
9012 for (i = 0; i < sources.length; i++) {
9013 source = sources[i];
9014 if (source === matchInput) {
9015 return [source];
9016 }
9017 }
9018 // an ID match
9019 source = this.getSourceById(EventSource_1.default.normalizeId(matchInput));
9020 if (source) {
9021 return [source];
9022 }
9023 // parse as an event source
9024 matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar);
9025 if (matchInput) {
9026 return $.grep(sources, function (source) {
9027 return isSourcesEquivalent(matchInput, source);
9028 });
9029 }
9030 };
9031 /*
9032 ID assumed to already be normalized
9033 */
9034 EventManager.prototype.getSourceById = function (id) {
9035 return $.grep(this.otherSources, function (source) {
9036 return source.id && source.id === id;
9037 })[0];
9038 };
9039 // Event-Period
9040 // -----------------------------------------------------------------------------------------------------------------
9041 EventManager.prototype.setPeriod = function (eventPeriod) {
9042 if (this.currentPeriod) {
9043 this.unbindPeriod(this.currentPeriod);
9044 this.currentPeriod = null;
9045 }
9046 this.currentPeriod = eventPeriod;
9047 this.bindPeriod(eventPeriod);
9048 eventPeriod.requestSources(this.getSources());
9049 };
9050 EventManager.prototype.bindPeriod = function (eventPeriod) {
9051 this.listenTo(eventPeriod, 'release', function (eventsPayload) {
9052 this.trigger('release', eventsPayload);
9053 });
9054 };
9055 EventManager.prototype.unbindPeriod = function (eventPeriod) {
9056 this.stopListeningTo(eventPeriod);
9057 };
9058 // Event Getting/Adding/Removing
9059 // -----------------------------------------------------------------------------------------------------------------
9060 EventManager.prototype.getEventDefByUid = function (uid) {
9061 if (this.currentPeriod) {
9062 return this.currentPeriod.getEventDefByUid(uid);
9063 }
9064 };
9065 EventManager.prototype.addEventDef = function (eventDef, isSticky) {
9066 if (isSticky) {
9067 this.stickySource.addEventDef(eventDef);
9068 }
9069 if (this.currentPeriod) {
9070 this.currentPeriod.addEventDef(eventDef); // might release
9071 }
9072 };
9073 EventManager.prototype.removeEventDefsById = function (eventId) {
9074 this.getSources().forEach(function (eventSource) {
9075 eventSource.removeEventDefsById(eventId);
9076 });
9077 if (this.currentPeriod) {
9078 this.currentPeriod.removeEventDefsById(eventId); // might release
9079 }
9080 };
9081 EventManager.prototype.removeAllEventDefs = function () {
9082 this.getSources().forEach(function (eventSource) {
9083 eventSource.removeAllEventDefs();
9084 });
9085 if (this.currentPeriod) {
9086 this.currentPeriod.removeAllEventDefs();
9087 }
9088 };
9089 // Event Mutating
9090 // -----------------------------------------------------------------------------------------------------------------
9091 /*
9092 Returns an undo function.
9093 */
9094 EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) {
9095 var currentPeriod = this.currentPeriod;
9096 var eventDefs;
9097 var undoFuncs = [];
9098 if (currentPeriod) {
9099 currentPeriod.freeze();
9100 eventDefs = currentPeriod.getEventDefsById(eventDefId);
9101 eventDefs.forEach(function (eventDef) {
9102 // add/remove esp because id might change
9103 currentPeriod.removeEventDef(eventDef);
9104 undoFuncs.push(eventDefMutation.mutateSingle(eventDef));
9105 currentPeriod.addEventDef(eventDef);
9106 });
9107 currentPeriod.thaw();
9108 return function () {
9109 currentPeriod.freeze();
9110 for (var i = 0; i < eventDefs.length; i++) {
9111 currentPeriod.removeEventDef(eventDefs[i]);
9112 undoFuncs[i]();
9113 currentPeriod.addEventDef(eventDefs[i]);
9114 }
9115 currentPeriod.thaw();
9116 };
9117 }
9118 return function () { };
9119 };
9120 /*
9121 copies and then mutates
9122 */
9123 EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) {
9124 var eventDefs = this.getEventDefsById(eventDefId);
9125 var i;
9126 var defCopy;
9127 var allInstances = [];
9128 for (i = 0; i < eventDefs.length; i++) {
9129 defCopy = eventDefs[i].clone();
9130 if (defCopy instanceof SingleEventDef_1.default) {
9131 eventDefMutation.mutateSingle(defCopy);
9132 allInstances.push.apply(allInstances, // append
9133 defCopy.buildInstances());
9134 }
9135 }
9136 return new EventInstanceGroup_1.default(allInstances);
9137 };
9138 // Freezing
9139 // -----------------------------------------------------------------------------------------------------------------
9140 EventManager.prototype.freeze = function () {
9141 if (this.currentPeriod) {
9142 this.currentPeriod.freeze();
9143 }
9144 };
9145 EventManager.prototype.thaw = function () {
9146 if (this.currentPeriod) {
9147 this.currentPeriod.thaw();
9148 }
9149 };
9150 // methods that simply forward to EventPeriod
9151 EventManager.prototype.getEventDefsById = function (eventDefId) {
9152 return this.currentPeriod.getEventDefsById(eventDefId);
9153 };
9154 EventManager.prototype.getEventInstances = function () {
9155 return this.currentPeriod.getEventInstances();
9156 };
9157 EventManager.prototype.getEventInstancesWithId = function (eventDefId) {
9158 return this.currentPeriod.getEventInstancesWithId(eventDefId);
9159 };
9160 EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) {
9161 return this.currentPeriod.getEventInstancesWithoutId(eventDefId);
9162 };
9163 return EventManager;
9164 }());
9165 exports.default = EventManager;
9166 EmitterMixin_1.default.mixInto(EventManager);
9167 ListenerMixin_1.default.mixInto(EventManager);
9168 function isSourcesEquivalent(source0, source1) {
9169 return source0.getPrimitive() === source1.getPrimitive();
9170 }
9171
9172
9173 /***/ }),
9174 /* 221 */
9175 /***/ (function(module, exports, __webpack_require__) {
9176
9177 Object.defineProperty(exports, "__esModule", { value: true });
9178 var tslib_1 = __webpack_require__(2);
9179 var Theme_1 = __webpack_require__(22);
9180 var StandardTheme = /** @class */ (function (_super) {
9181 tslib_1.__extends(StandardTheme, _super);
9182 function StandardTheme() {
9183 return _super !== null && _super.apply(this, arguments) || this;
9184 }
9185 return StandardTheme;
9186 }(Theme_1.default));
9187 exports.default = StandardTheme;
9188 StandardTheme.prototype.classes = {
9189 widget: 'fc-unthemed',
9190 widgetHeader: 'fc-widget-header',
9191 widgetContent: 'fc-widget-content',
9192 buttonGroup: 'fc-button-group',
9193 button: 'fc-button',
9194 cornerLeft: 'fc-corner-left',
9195 cornerRight: 'fc-corner-right',
9196 stateDefault: 'fc-state-default',
9197 stateActive: 'fc-state-active',
9198 stateDisabled: 'fc-state-disabled',
9199 stateHover: 'fc-state-hover',
9200 stateDown: 'fc-state-down',
9201 popoverHeader: 'fc-widget-header',
9202 popoverContent: 'fc-widget-content',
9203 // day grid
9204 headerRow: 'fc-widget-header',
9205 dayRow: 'fc-widget-content',
9206 // list view
9207 listView: 'fc-widget-content'
9208 };
9209 StandardTheme.prototype.baseIconClass = 'fc-icon';
9210 StandardTheme.prototype.iconClasses = {
9211 close: 'fc-icon-x',
9212 prev: 'fc-icon-left-single-arrow',
9213 next: 'fc-icon-right-single-arrow',
9214 prevYear: 'fc-icon-left-double-arrow',
9215 nextYear: 'fc-icon-right-double-arrow'
9216 };
9217 StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
9218 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
9219 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
9220
9221
9222 /***/ }),
9223 /* 222 */
9224 /***/ (function(module, exports, __webpack_require__) {
9225
9226 Object.defineProperty(exports, "__esModule", { value: true });
9227 var tslib_1 = __webpack_require__(2);
9228 var Theme_1 = __webpack_require__(22);
9229 var JqueryUiTheme = /** @class */ (function (_super) {
9230 tslib_1.__extends(JqueryUiTheme, _super);
9231 function JqueryUiTheme() {
9232 return _super !== null && _super.apply(this, arguments) || this;
9233 }
9234 return JqueryUiTheme;
9235 }(Theme_1.default));
9236 exports.default = JqueryUiTheme;
9237 JqueryUiTheme.prototype.classes = {
9238 widget: 'ui-widget',
9239 widgetHeader: 'ui-widget-header',
9240 widgetContent: 'ui-widget-content',
9241 buttonGroup: 'fc-button-group',
9242 button: 'ui-button',
9243 cornerLeft: 'ui-corner-left',
9244 cornerRight: 'ui-corner-right',
9245 stateDefault: 'ui-state-default',
9246 stateActive: 'ui-state-active',
9247 stateDisabled: 'ui-state-disabled',
9248 stateHover: 'ui-state-hover',
9249 stateDown: 'ui-state-down',
9250 today: 'ui-state-highlight',
9251 popoverHeader: 'ui-widget-header',
9252 popoverContent: 'ui-widget-content',
9253 // day grid
9254 headerRow: 'ui-widget-header',
9255 dayRow: 'ui-widget-content',
9256 // list view
9257 listView: 'ui-widget-content'
9258 };
9259 JqueryUiTheme.prototype.baseIconClass = 'ui-icon';
9260 JqueryUiTheme.prototype.iconClasses = {
9261 close: 'ui-icon-closethick',
9262 prev: 'ui-icon-circle-triangle-w',
9263 next: 'ui-icon-circle-triangle-e',
9264 prevYear: 'ui-icon-seek-prev',
9265 nextYear: 'ui-icon-seek-next'
9266 };
9267 JqueryUiTheme.prototype.iconOverrideOption = 'themeButtonIcons';
9268 JqueryUiTheme.prototype.iconOverrideCustomButtonOption = 'themeIcon';
9269 JqueryUiTheme.prototype.iconOverridePrefix = 'ui-icon-';
9270
9271
9272 /***/ }),
9273 /* 223 */
9274 /***/ (function(module, exports, __webpack_require__) {
9275
9276 Object.defineProperty(exports, "__esModule", { value: true });
9277 var tslib_1 = __webpack_require__(2);
9278 var $ = __webpack_require__(3);
9279 var Promise_1 = __webpack_require__(21);
9280 var EventSource_1 = __webpack_require__(6);
9281 var FuncEventSource = /** @class */ (function (_super) {
9282 tslib_1.__extends(FuncEventSource, _super);
9283 function FuncEventSource() {
9284 return _super !== null && _super.apply(this, arguments) || this;
9285 }
9286 FuncEventSource.parse = function (rawInput, calendar) {
9287 var rawProps;
9288 // normalize raw input
9289 if ($.isFunction(rawInput.events)) { // extended form
9290 rawProps = rawInput;
9291 }
9292 else if ($.isFunction(rawInput)) { // short form
9293 rawProps = { events: rawInput };
9294 }
9295 if (rawProps) {
9296 return EventSource_1.default.parse.call(this, rawProps, calendar);
9297 }
9298 return false;
9299 };
9300 FuncEventSource.prototype.fetch = function (start, end, timezone) {
9301 var _this = this;
9302 this.calendar.pushLoading();
9303 return Promise_1.default.construct(function (onResolve) {
9304 _this.func.call(_this.calendar, start.clone(), end.clone(), timezone, function (rawEventDefs) {
9305 _this.calendar.popLoading();
9306 onResolve(_this.parseEventDefs(rawEventDefs));
9307 });
9308 });
9309 };
9310 FuncEventSource.prototype.getPrimitive = function () {
9311 return this.func;
9312 };
9313 FuncEventSource.prototype.applyManualStandardProps = function (rawProps) {
9314 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
9315 this.func = rawProps.events;
9316 return superSuccess;
9317 };
9318 return FuncEventSource;
9319 }(EventSource_1.default));
9320 exports.default = FuncEventSource;
9321 FuncEventSource.defineStandardProps({
9322 events: false // don't automatically transfer
9323 });
9324
9325
9326 /***/ }),
9327 /* 224 */
9328 /***/ (function(module, exports, __webpack_require__) {
9329
9330 Object.defineProperty(exports, "__esModule", { value: true });
9331 var tslib_1 = __webpack_require__(2);
9332 var $ = __webpack_require__(3);
9333 var util_1 = __webpack_require__(4);
9334 var Promise_1 = __webpack_require__(21);
9335 var EventSource_1 = __webpack_require__(6);
9336 var JsonFeedEventSource = /** @class */ (function (_super) {
9337 tslib_1.__extends(JsonFeedEventSource, _super);
9338 function JsonFeedEventSource() {
9339 return _super !== null && _super.apply(this, arguments) || this;
9340 }
9341 JsonFeedEventSource.parse = function (rawInput, calendar) {
9342 var rawProps;
9343 // normalize raw input
9344 if (typeof rawInput.url === 'string') { // extended form
9345 rawProps = rawInput;
9346 }
9347 else if (typeof rawInput === 'string') { // short form
9348 rawProps = { url: rawInput };
9349 }
9350 if (rawProps) {
9351 return EventSource_1.default.parse.call(this, rawProps, calendar);
9352 }
9353 return false;
9354 };
9355 JsonFeedEventSource.prototype.fetch = function (start, end, timezone) {
9356 var _this = this;
9357 var ajaxSettings = this.ajaxSettings;
9358 var onSuccess = ajaxSettings.success;
9359 var onError = ajaxSettings.error;
9360 var requestParams = this.buildRequestParams(start, end, timezone);
9361 // todo: eventually handle the promise's then,
9362 // don't intercept success/error
9363 // tho will be a breaking API change
9364 this.calendar.pushLoading();
9365 return Promise_1.default.construct(function (onResolve, onReject) {
9366 $.ajax($.extend({}, // destination
9367 JsonFeedEventSource.AJAX_DEFAULTS, ajaxSettings, {
9368 url: _this.url,
9369 data: requestParams,
9370 success: function (rawEventDefs, status, xhr) {
9371 var callbackRes;
9372 _this.calendar.popLoading();
9373 if (rawEventDefs) {
9374 callbackRes = util_1.applyAll(onSuccess, _this, [rawEventDefs, status, xhr]); // redirect `this`
9375 if ($.isArray(callbackRes)) {
9376 rawEventDefs = callbackRes;
9377 }
9378 onResolve(_this.parseEventDefs(rawEventDefs));
9379 }
9380 else {
9381 onReject();
9382 }
9383 },
9384 error: function (xhr, statusText, errorThrown) {
9385 _this.calendar.popLoading();
9386 util_1.applyAll(onError, _this, [xhr, statusText, errorThrown]); // redirect `this`
9387 onReject();
9388 }
9389 }));
9390 });
9391 };
9392 JsonFeedEventSource.prototype.buildRequestParams = function (start, end, timezone) {
9393 var calendar = this.calendar;
9394 var ajaxSettings = this.ajaxSettings;
9395 var startParam;
9396 var endParam;
9397 var timezoneParam;
9398 var customRequestParams;
9399 var params = {};
9400 startParam = this.startParam;
9401 if (startParam == null) {
9402 startParam = calendar.opt('startParam');
9403 }
9404 endParam = this.endParam;
9405 if (endParam == null) {
9406 endParam = calendar.opt('endParam');
9407 }
9408 timezoneParam = this.timezoneParam;
9409 if (timezoneParam == null) {
9410 timezoneParam = calendar.opt('timezoneParam');
9411 }
9412 // retrieve any outbound GET/POST $.ajax data from the options
9413 if ($.isFunction(ajaxSettings.data)) {
9414 // supplied as a function that returns a key/value object
9415 customRequestParams = ajaxSettings.data();
9416 }
9417 else {
9418 // probably supplied as a straight key/value object
9419 customRequestParams = ajaxSettings.data || {};
9420 }
9421 $.extend(params, customRequestParams);
9422 params[startParam] = start.format();
9423 params[endParam] = end.format();
9424 if (timezone && timezone !== 'local') {
9425 params[timezoneParam] = timezone;
9426 }
9427 return params;
9428 };
9429 JsonFeedEventSource.prototype.getPrimitive = function () {
9430 return this.url;
9431 };
9432 JsonFeedEventSource.prototype.applyMiscProps = function (rawProps) {
9433 this.ajaxSettings = rawProps;
9434 };
9435 JsonFeedEventSource.AJAX_DEFAULTS = {
9436 dataType: 'json',
9437 cache: false
9438 };
9439 return JsonFeedEventSource;
9440 }(EventSource_1.default));
9441 exports.default = JsonFeedEventSource;
9442 JsonFeedEventSource.defineStandardProps({
9443 // automatically transfer (true)...
9444 url: true,
9445 startParam: true,
9446 endParam: true,
9447 timezoneParam: true
9448 });
9449
9450
9451 /***/ }),
9452 /* 225 */
9453 /***/ (function(module, exports) {
9454
9455 Object.defineProperty(exports, "__esModule", { value: true });
9456 var Iterator = /** @class */ (function () {
9457 function Iterator(items) {
9458 this.items = items || [];
9459 }
9460 /* Calls a method on every item passing the arguments through */
9461 Iterator.prototype.proxyCall = function (methodName) {
9462 var args = [];
9463 for (var _i = 1; _i < arguments.length; _i++) {
9464 args[_i - 1] = arguments[_i];
9465 }
9466 var results = [];
9467 this.items.forEach(function (item) {
9468 results.push(item[methodName].apply(item, args));
9469 });
9470 return results;
9471 };
9472 return Iterator;
9473 }());
9474 exports.default = Iterator;
9475
9476
9477 /***/ }),
9478 /* 226 */
9479 /***/ (function(module, exports, __webpack_require__) {
9480
9481 Object.defineProperty(exports, "__esModule", { value: true });
9482 var $ = __webpack_require__(3);
9483 var util_1 = __webpack_require__(4);
9484 var ListenerMixin_1 = __webpack_require__(7);
9485 /* Creates a clone of an element and lets it track the mouse as it moves
9486 ----------------------------------------------------------------------------------------------------------------------*/
9487 var MouseFollower = /** @class */ (function () {
9488 function MouseFollower(sourceEl, options) {
9489 this.isFollowing = false;
9490 this.isHidden = false;
9491 this.isAnimating = false; // doing the revert animation?
9492 this.options = options = options || {};
9493 this.sourceEl = sourceEl;
9494 this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent
9495 }
9496 // Causes the element to start following the mouse
9497 MouseFollower.prototype.start = function (ev) {
9498 if (!this.isFollowing) {
9499 this.isFollowing = true;
9500 this.y0 = util_1.getEvY(ev);
9501 this.x0 = util_1.getEvX(ev);
9502 this.topDelta = 0;
9503 this.leftDelta = 0;
9504 if (!this.isHidden) {
9505 this.updatePosition();
9506 }
9507 if (util_1.getEvIsTouch(ev)) {
9508 this.listenTo($(document), 'touchmove', this.handleMove);
9509 }
9510 else {
9511 this.listenTo($(document), 'mousemove', this.handleMove);
9512 }
9513 }
9514 };
9515 // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
9516 // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.
9517 MouseFollower.prototype.stop = function (shouldRevert, callback) {
9518 var _this = this;
9519 var revertDuration = this.options.revertDuration;
9520 var complete = function () {
9521 _this.isAnimating = false;
9522 _this.removeElement();
9523 _this.top0 = _this.left0 = null; // reset state for future updatePosition calls
9524 if (callback) {
9525 callback();
9526 }
9527 };
9528 if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time
9529 this.isFollowing = false;
9530 this.stopListeningTo($(document));
9531 if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?
9532 this.isAnimating = true;
9533 this.el.animate({
9534 top: this.top0,
9535 left: this.left0
9536 }, {
9537 duration: revertDuration,
9538 complete: complete
9539 });
9540 }
9541 else {
9542 complete();
9543 }
9544 }
9545 };
9546 // Gets the tracking element. Create it if necessary
9547 MouseFollower.prototype.getEl = function () {
9548 var el = this.el;
9549 if (!el) {
9550 el = this.el = this.sourceEl.clone()
9551 .addClass(this.options.additionalClass || '')
9552 .css({
9553 position: 'absolute',
9554 visibility: '',
9555 display: this.isHidden ? 'none' : '',
9556 margin: 0,
9557 right: 'auto',
9558 bottom: 'auto',
9559 width: this.sourceEl.width(),
9560 height: this.sourceEl.height(),
9561 opacity: this.options.opacity || '',
9562 zIndex: this.options.zIndex
9563 });
9564 // we don't want long taps or any mouse interaction causing selection/menus.
9565 // would use preventSelection(), but that prevents selectstart, causing problems.
9566 el.addClass('fc-unselectable');
9567 el.appendTo(this.parentEl);
9568 }
9569 return el;
9570 };
9571 // Removes the tracking element if it has already been created
9572 MouseFollower.prototype.removeElement = function () {
9573 if (this.el) {
9574 this.el.remove();
9575 this.el = null;
9576 }
9577 };
9578 // Update the CSS position of the tracking element
9579 MouseFollower.prototype.updatePosition = function () {
9580 var sourceOffset;
9581 var origin;
9582 this.getEl(); // ensure this.el
9583 // make sure origin info was computed
9584 if (this.top0 == null) {
9585 sourceOffset = this.sourceEl.offset();
9586 origin = this.el.offsetParent().offset();
9587 this.top0 = sourceOffset.top - origin.top;
9588 this.left0 = sourceOffset.left - origin.left;
9589 }
9590 this.el.css({
9591 top: this.top0 + this.topDelta,
9592 left: this.left0 + this.leftDelta
9593 });
9594 };
9595 // Gets called when the user moves the mouse
9596 MouseFollower.prototype.handleMove = function (ev) {
9597 this.topDelta = util_1.getEvY(ev) - this.y0;
9598 this.leftDelta = util_1.getEvX(ev) - this.x0;
9599 if (!this.isHidden) {
9600 this.updatePosition();
9601 }
9602 };
9603 // Temporarily makes the tracking element invisible. Can be called before following starts
9604 MouseFollower.prototype.hide = function () {
9605 if (!this.isHidden) {
9606 this.isHidden = true;
9607 if (this.el) {
9608 this.el.hide();
9609 }
9610 }
9611 };
9612 // Show the tracking element after it has been temporarily hidden
9613 MouseFollower.prototype.show = function () {
9614 if (this.isHidden) {
9615 this.isHidden = false;
9616 this.updatePosition();
9617 this.getEl().show();
9618 }
9619 };
9620 return MouseFollower;
9621 }());
9622 exports.default = MouseFollower;
9623 ListenerMixin_1.default.mixInto(MouseFollower);
9624
9625
9626 /***/ }),
9627 /* 227 */
9628 /***/ (function(module, exports, __webpack_require__) {
9629
9630 /* A rectangular panel that is absolutely positioned over other content
9631 ------------------------------------------------------------------------------------------------------------------------
9632 Options:
9633 - className (string)
9634 - content (HTML string or jQuery element set)
9635 - parentEl
9636 - top
9637 - left
9638 - right (the x coord of where the right edge should be. not a "CSS" right)
9639 - autoHide (boolean)
9640 - show (callback)
9641 - hide (callback)
9642 */
9643 Object.defineProperty(exports, "__esModule", { value: true });
9644 var $ = __webpack_require__(3);
9645 var util_1 = __webpack_require__(4);
9646 var ListenerMixin_1 = __webpack_require__(7);
9647 var Popover = /** @class */ (function () {
9648 function Popover(options) {
9649 this.isHidden = true;
9650 this.margin = 10; // the space required between the popover and the edges of the scroll container
9651 this.options = options || {};
9652 }
9653 // Shows the popover on the specified position. Renders it if not already
9654 Popover.prototype.show = function () {
9655 if (this.isHidden) {
9656 if (!this.el) {
9657 this.render();
9658 }
9659 this.el.show();
9660 this.position();
9661 this.isHidden = false;
9662 this.trigger('show');
9663 }
9664 };
9665 // Hides the popover, through CSS, but does not remove it from the DOM
9666 Popover.prototype.hide = function () {
9667 if (!this.isHidden) {
9668 this.el.hide();
9669 this.isHidden = true;
9670 this.trigger('hide');
9671 }
9672 };
9673 // Creates `this.el` and renders content inside of it
9674 Popover.prototype.render = function () {
9675 var _this = this;
9676 var options = this.options;
9677 this.el = $('<div class="fc-popover">')
9678 .addClass(options.className || '')
9679 .css({
9680 // position initially to the top left to avoid creating scrollbars
9681 top: 0,
9682 left: 0
9683 })
9684 .append(options.content)
9685 .appendTo(options.parentEl);
9686 // when a click happens on anything inside with a 'fc-close' className, hide the popover
9687 this.el.on('click', '.fc-close', function () {
9688 _this.hide();
9689 });
9690 if (options.autoHide) {
9691 this.listenTo($(document), 'mousedown', this.documentMousedown);
9692 }
9693 };
9694 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
9695 Popover.prototype.documentMousedown = function (ev) {
9696 // only hide the popover if the click happened outside the popover
9697 if (this.el && !$(ev.target).closest(this.el).length) {
9698 this.hide();
9699 }
9700 };
9701 // Hides and unregisters any handlers
9702 Popover.prototype.removeElement = function () {
9703 this.hide();
9704 if (this.el) {
9705 this.el.remove();
9706 this.el = null;
9707 }
9708 this.stopListeningTo($(document), 'mousedown');
9709 };
9710 // Positions the popover optimally, using the top/left/right options
9711 Popover.prototype.position = function () {
9712 var options = this.options;
9713 var origin = this.el.offsetParent().offset();
9714 var width = this.el.outerWidth();
9715 var height = this.el.outerHeight();
9716 var windowEl = $(window);
9717 var viewportEl = util_1.getScrollParent(this.el);
9718 var viewportTop;
9719 var viewportLeft;
9720 var viewportOffset;
9721 var top; // the "position" (not "offset") values for the popover
9722 var left; //
9723 // compute top and left
9724 top = options.top || 0;
9725 if (options.left !== undefined) {
9726 left = options.left;
9727 }
9728 else if (options.right !== undefined) {
9729 left = options.right - width; // derive the left value from the right value
9730 }
9731 else {
9732 left = 0;
9733 }
9734 if (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result
9735 viewportEl = windowEl;
9736 viewportTop = 0; // the window is always at the top left
9737 viewportLeft = 0; // (and .offset() won't work if called here)
9738 }
9739 else {
9740 viewportOffset = viewportEl.offset();
9741 viewportTop = viewportOffset.top;
9742 viewportLeft = viewportOffset.left;
9743 }
9744 // if the window is scrolled, it causes the visible area to be further down
9745 viewportTop += windowEl.scrollTop();
9746 viewportLeft += windowEl.scrollLeft();
9747 // constrain to the view port. if constrained by two edges, give precedence to top/left
9748 if (options.viewportConstrain !== false) {
9749 top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);
9750 top = Math.max(top, viewportTop + this.margin);
9751 left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);
9752 left = Math.max(left, viewportLeft + this.margin);
9753 }
9754 this.el.css({
9755 top: top - origin.top,
9756 left: left - origin.left
9757 });
9758 };
9759 // Triggers a callback. Calls a function in the option hash of the same name.
9760 // Arguments beyond the first `name` are forwarded on.
9761 // TODO: better code reuse for this. Repeat code
9762 Popover.prototype.trigger = function (name) {
9763 if (this.options[name]) {
9764 this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
9765 }
9766 };
9767 return Popover;
9768 }());
9769 exports.default = Popover;
9770 ListenerMixin_1.default.mixInto(Popover);
9771
9772
9773 /***/ }),
9774 /* 228 */
9775 /***/ (function(module, exports, __webpack_require__) {
9776
9777 Object.defineProperty(exports, "__esModule", { value: true });
9778 var EmitterMixin_1 = __webpack_require__(13);
9779 var TaskQueue = /** @class */ (function () {
9780 function TaskQueue() {
9781 this.q = [];
9782 this.isPaused = false;
9783 this.isRunning = false;
9784 }
9785 TaskQueue.prototype.queue = function () {
9786 var args = [];
9787 for (var _i = 0; _i < arguments.length; _i++) {
9788 args[_i] = arguments[_i];
9789 }
9790 this.q.push.apply(this.q, args); // append
9791 this.tryStart();
9792 };
9793 TaskQueue.prototype.pause = function () {
9794 this.isPaused = true;
9795 };
9796 TaskQueue.prototype.resume = function () {
9797 this.isPaused = false;
9798 this.tryStart();
9799 };
9800 TaskQueue.prototype.getIsIdle = function () {
9801 return !this.isRunning && !this.isPaused;
9802 };
9803 TaskQueue.prototype.tryStart = function () {
9804 if (!this.isRunning && this.canRunNext()) {
9805 this.isRunning = true;
9806 this.trigger('start');
9807 this.runRemaining();
9808 }
9809 };
9810 TaskQueue.prototype.canRunNext = function () {
9811 return !this.isPaused && this.q.length;
9812 };
9813 TaskQueue.prototype.runRemaining = function () {
9814 var _this = this;
9815 var task;
9816 var res;
9817 do {
9818 task = this.q.shift(); // always freshly reference q. might have been reassigned.
9819 res = this.runTask(task);
9820 if (res && res.then) {
9821 res.then(function () {
9822 if (_this.canRunNext()) {
9823 _this.runRemaining();
9824 }
9825 });
9826 return; // prevent marking as stopped
9827 }
9828 } while (this.canRunNext());
9829 this.trigger('stop'); // not really a 'stop' ... more of a 'drained'
9830 this.isRunning = false;
9831 // if 'stop' handler added more tasks.... TODO: write test for this
9832 this.tryStart();
9833 };
9834 TaskQueue.prototype.runTask = function (task) {
9835 return task(); // task *is* the function, but subclasses can change the format of a task
9836 };
9837 return TaskQueue;
9838 }());
9839 exports.default = TaskQueue;
9840 EmitterMixin_1.default.mixInto(TaskQueue);
9841
9842
9843 /***/ }),
9844 /* 229 */
9845 /***/ (function(module, exports, __webpack_require__) {
9846
9847 Object.defineProperty(exports, "__esModule", { value: true });
9848 var tslib_1 = __webpack_require__(2);
9849 var TaskQueue_1 = __webpack_require__(228);
9850 var RenderQueue = /** @class */ (function (_super) {
9851 tslib_1.__extends(RenderQueue, _super);
9852 function RenderQueue(waitsByNamespace) {
9853 var _this = _super.call(this) || this;
9854 _this.waitsByNamespace = waitsByNamespace || {};
9855 return _this;
9856 }
9857 RenderQueue.prototype.queue = function (taskFunc, namespace, type) {
9858 var task = {
9859 func: taskFunc,
9860 namespace: namespace,
9861 type: type
9862 };
9863 var waitMs;
9864 if (namespace) {
9865 waitMs = this.waitsByNamespace[namespace];
9866 }
9867 if (this.waitNamespace) {
9868 if (namespace === this.waitNamespace && waitMs != null) {
9869 this.delayWait(waitMs);
9870 }
9871 else {
9872 this.clearWait();
9873 this.tryStart();
9874 }
9875 }
9876 if (this.compoundTask(task)) { // appended to queue?
9877 if (!this.waitNamespace && waitMs != null) {
9878 this.startWait(namespace, waitMs);
9879 }
9880 else {
9881 this.tryStart();
9882 }
9883 }
9884 };
9885 RenderQueue.prototype.startWait = function (namespace, waitMs) {
9886 this.waitNamespace = namespace;
9887 this.spawnWait(waitMs);
9888 };
9889 RenderQueue.prototype.delayWait = function (waitMs) {
9890 clearTimeout(this.waitId);
9891 this.spawnWait(waitMs);
9892 };
9893 RenderQueue.prototype.spawnWait = function (waitMs) {
9894 var _this = this;
9895 this.waitId = setTimeout(function () {
9896 _this.waitNamespace = null;
9897 _this.tryStart();
9898 }, waitMs);
9899 };
9900 RenderQueue.prototype.clearWait = function () {
9901 if (this.waitNamespace) {
9902 clearTimeout(this.waitId);
9903 this.waitId = null;
9904 this.waitNamespace = null;
9905 }
9906 };
9907 RenderQueue.prototype.canRunNext = function () {
9908 if (!_super.prototype.canRunNext.call(this)) {
9909 return false;
9910 }
9911 // waiting for a certain namespace to stop receiving tasks?
9912 if (this.waitNamespace) {
9913 var q = this.q;
9914 // if there was a different namespace task in the meantime,
9915 // that forces all previously-waiting tasks to suddenly execute.
9916 // TODO: find a way to do this in constant time.
9917 for (var i = 0; i < q.length; i++) {
9918 if (q[i].namespace !== this.waitNamespace) {
9919 return true; // allow execution
9920 }
9921 }
9922 return false;
9923 }
9924 return true;
9925 };
9926 RenderQueue.prototype.runTask = function (task) {
9927 task.func();
9928 };
9929 RenderQueue.prototype.compoundTask = function (newTask) {
9930 var q = this.q;
9931 var shouldAppend = true;
9932 var i;
9933 var task;
9934 if (newTask.namespace && newTask.type === 'destroy') {
9935 // remove all init/add/remove ops with same namespace, regardless of order
9936 for (i = q.length - 1; i >= 0; i--) {
9937 task = q[i];
9938 if (task.namespace === newTask.namespace) {
9939 switch (task.type) {
9940 case 'init':
9941 shouldAppend = false;
9942 // the latest destroy is cancelled out by not doing the init
9943 /* falls through */
9944 case 'add':
9945 /* falls through */
9946 case 'remove':
9947 q.splice(i, 1); // remove task
9948 }
9949 }
9950 }
9951 }
9952 if (shouldAppend) {
9953 q.push(newTask);
9954 }
9955 return shouldAppend;
9956 };
9957 return RenderQueue;
9958 }(TaskQueue_1.default));
9959 exports.default = RenderQueue;
9960
9961
9962 /***/ }),
9963 /* 230 */
9964 /***/ (function(module, exports, __webpack_require__) {
9965
9966 Object.defineProperty(exports, "__esModule", { value: true });
9967 var tslib_1 = __webpack_require__(2);
9968 var Model_1 = __webpack_require__(51);
9969 var Component = /** @class */ (function (_super) {
9970 tslib_1.__extends(Component, _super);
9971 function Component() {
9972 return _super !== null && _super.apply(this, arguments) || this;
9973 }
9974 Component.prototype.setElement = function (el) {
9975 this.el = el;
9976 this.bindGlobalHandlers();
9977 this.renderSkeleton();
9978 this.set('isInDom', true);
9979 };
9980 Component.prototype.removeElement = function () {
9981 this.unset('isInDom');
9982 this.unrenderSkeleton();
9983 this.unbindGlobalHandlers();
9984 this.el.remove();
9985 // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
9986 // We don't null-out the View's other jQuery element references upon destroy,
9987 // so we shouldn't kill this.el either.
9988 };
9989 Component.prototype.bindGlobalHandlers = function () {
9990 // subclasses can override
9991 };
9992 Component.prototype.unbindGlobalHandlers = function () {
9993 // subclasses can override
9994 };
9995 /*
9996 NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender
9997 */
9998 // Renders the basic structure of the view before any content is rendered
9999 Component.prototype.renderSkeleton = function () {
10000 // subclasses should implement
10001 };
10002 // Unrenders the basic structure of the view
10003 Component.prototype.unrenderSkeleton = function () {
10004 // subclasses should implement
10005 };
10006 return Component;
10007 }(Model_1.default));
10008 exports.default = Component;
10009
10010
10011 /***/ }),
10012 /* 231 */
10013 /***/ (function(module, exports, __webpack_require__) {
10014
10015 Object.defineProperty(exports, "__esModule", { value: true });
10016 var tslib_1 = __webpack_require__(2);
10017 var $ = __webpack_require__(3);
10018 var moment = __webpack_require__(0);
10019 var util_1 = __webpack_require__(4);
10020 var moment_ext_1 = __webpack_require__(11);
10021 var date_formatting_1 = __webpack_require__(49);
10022 var Component_1 = __webpack_require__(230);
10023 var util_2 = __webpack_require__(19);
10024 var DateComponent = /** @class */ (function (_super) {
10025 tslib_1.__extends(DateComponent, _super);
10026 function DateComponent(_view, _options) {
10027 var _this = _super.call(this) || this;
10028 _this.isRTL = false; // frequently accessed options
10029 _this.hitsNeededDepth = 0; // necessary because multiple callers might need the same hits
10030 _this.hasAllDayBusinessHours = false; // TODO: unify with largeUnit and isTimeScale?
10031 _this.isDatesRendered = false;
10032 // hack to set options prior to the this.opt calls
10033 if (_view) {
10034 _this['view'] = _view;
10035 }
10036 if (_options) {
10037 _this['options'] = _options;
10038 }
10039 _this.uid = String(DateComponent.guid++);
10040 _this.childrenByUid = {};
10041 _this.nextDayThreshold = moment.duration(_this.opt('nextDayThreshold'));
10042 _this.isRTL = _this.opt('isRTL');
10043 if (_this.fillRendererClass) {
10044 _this.fillRenderer = new _this.fillRendererClass(_this);
10045 }
10046 if (_this.eventRendererClass) { // fillRenderer is optional -----v
10047 _this.eventRenderer = new _this.eventRendererClass(_this, _this.fillRenderer);
10048 }
10049 if (_this.helperRendererClass && _this.eventRenderer) {
10050 _this.helperRenderer = new _this.helperRendererClass(_this, _this.eventRenderer);
10051 }
10052 if (_this.businessHourRendererClass && _this.fillRenderer) {
10053 _this.businessHourRenderer = new _this.businessHourRendererClass(_this, _this.fillRenderer);
10054 }
10055 return _this;
10056 }
10057 DateComponent.prototype.addChild = function (child) {
10058 if (!this.childrenByUid[child.uid]) {
10059 this.childrenByUid[child.uid] = child;
10060 return true;
10061 }
10062 return false;
10063 };
10064 DateComponent.prototype.removeChild = function (child) {
10065 if (this.childrenByUid[child.uid]) {
10066 delete this.childrenByUid[child.uid];
10067 return true;
10068 }
10069 return false;
10070 };
10071 // TODO: only do if isInDom?
10072 // TODO: make part of Component, along with children/batch-render system?
10073 DateComponent.prototype.updateSize = function (totalHeight, isAuto, isResize) {
10074 this.callChildren('updateSize', arguments);
10075 };
10076 // Options
10077 // -----------------------------------------------------------------------------------------------------------------
10078 DateComponent.prototype.opt = function (name) {
10079 return this._getView().opt(name); // default implementation
10080 };
10081 DateComponent.prototype.publiclyTrigger = function () {
10082 var args = [];
10083 for (var _i = 0; _i < arguments.length; _i++) {
10084 args[_i] = arguments[_i];
10085 }
10086 var calendar = this._getCalendar();
10087 return calendar.publiclyTrigger.apply(calendar, args);
10088 };
10089 DateComponent.prototype.hasPublicHandlers = function () {
10090 var args = [];
10091 for (var _i = 0; _i < arguments.length; _i++) {
10092 args[_i] = arguments[_i];
10093 }
10094 var calendar = this._getCalendar();
10095 return calendar.hasPublicHandlers.apply(calendar, args);
10096 };
10097 // Date
10098 // -----------------------------------------------------------------------------------------------------------------
10099 DateComponent.prototype.executeDateRender = function (dateProfile) {
10100 this.dateProfile = dateProfile; // for rendering
10101 this.renderDates(dateProfile);
10102 this.isDatesRendered = true;
10103 this.callChildren('executeDateRender', arguments);
10104 };
10105 DateComponent.prototype.executeDateUnrender = function () {
10106 this.callChildren('executeDateUnrender', arguments);
10107 this.dateProfile = null;
10108 this.unrenderDates();
10109 this.isDatesRendered = false;
10110 };
10111 // date-cell content only
10112 DateComponent.prototype.renderDates = function (dateProfile) {
10113 // subclasses should implement
10114 };
10115 // date-cell content only
10116 DateComponent.prototype.unrenderDates = function () {
10117 // subclasses should override
10118 };
10119 // Now-Indicator
10120 // -----------------------------------------------------------------------------------------------------------------
10121 // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator
10122 // should be refreshed. If something falsy is returned, no time indicator is rendered at all.
10123 DateComponent.prototype.getNowIndicatorUnit = function () {
10124 // subclasses should implement
10125 };
10126 // Renders a current time indicator at the given datetime
10127 DateComponent.prototype.renderNowIndicator = function (date) {
10128 this.callChildren('renderNowIndicator', arguments);
10129 };
10130 // Undoes the rendering actions from renderNowIndicator
10131 DateComponent.prototype.unrenderNowIndicator = function () {
10132 this.callChildren('unrenderNowIndicator', arguments);
10133 };
10134 // Business Hours
10135 // ---------------------------------------------------------------------------------------------------------------
10136 DateComponent.prototype.renderBusinessHours = function (businessHourGenerator) {
10137 if (this.businessHourRenderer) {
10138 this.businessHourRenderer.render(businessHourGenerator);
10139 }
10140 this.callChildren('renderBusinessHours', arguments);
10141 };
10142 // Unrenders previously-rendered business-hours
10143 DateComponent.prototype.unrenderBusinessHours = function () {
10144 this.callChildren('unrenderBusinessHours', arguments);
10145 if (this.businessHourRenderer) {
10146 this.businessHourRenderer.unrender();
10147 }
10148 };
10149 // Event Displaying
10150 // -----------------------------------------------------------------------------------------------------------------
10151 DateComponent.prototype.executeEventRender = function (eventsPayload) {
10152 if (this.eventRenderer) {
10153 this.eventRenderer.rangeUpdated(); // poorly named now
10154 this.eventRenderer.render(eventsPayload);
10155 }
10156 else if (this['renderEvents']) { // legacy
10157 this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload));
10158 }
10159 this.callChildren('executeEventRender', arguments);
10160 };
10161 DateComponent.prototype.executeEventUnrender = function () {
10162 this.callChildren('executeEventUnrender', arguments);
10163 if (this.eventRenderer) {
10164 this.eventRenderer.unrender();
10165 }
10166 else if (this['destroyEvents']) { // legacy
10167 this['destroyEvents']();
10168 }
10169 };
10170 DateComponent.prototype.getBusinessHourSegs = function () {
10171 var segs = this.getOwnBusinessHourSegs();
10172 this.iterChildren(function (child) {
10173 segs.push.apply(segs, child.getBusinessHourSegs());
10174 });
10175 return segs;
10176 };
10177 DateComponent.prototype.getOwnBusinessHourSegs = function () {
10178 if (this.businessHourRenderer) {
10179 return this.businessHourRenderer.getSegs();
10180 }
10181 return [];
10182 };
10183 DateComponent.prototype.getEventSegs = function () {
10184 var segs = this.getOwnEventSegs();
10185 this.iterChildren(function (child) {
10186 segs.push.apply(segs, child.getEventSegs());
10187 });
10188 return segs;
10189 };
10190 DateComponent.prototype.getOwnEventSegs = function () {
10191 if (this.eventRenderer) {
10192 return this.eventRenderer.getSegs();
10193 }
10194 return [];
10195 };
10196 // Event Rendering Triggering
10197 // -----------------------------------------------------------------------------------------------------------------
10198 DateComponent.prototype.triggerAfterEventsRendered = function () {
10199 this.triggerAfterEventSegsRendered(this.getEventSegs());
10200 this.publiclyTrigger('eventAfterAllRender', {
10201 context: this,
10202 args: [this]
10203 });
10204 };
10205 DateComponent.prototype.triggerAfterEventSegsRendered = function (segs) {
10206 var _this = this;
10207 // an optimization, because getEventLegacy is expensive
10208 if (this.hasPublicHandlers('eventAfterRender')) {
10209 segs.forEach(function (seg) {
10210 var legacy;
10211 if (seg.el) { // necessary?
10212 legacy = seg.footprint.getEventLegacy();
10213 _this.publiclyTrigger('eventAfterRender', {
10214 context: legacy,
10215 args: [legacy, seg.el, _this]
10216 });
10217 }
10218 });
10219 }
10220 };
10221 DateComponent.prototype.triggerBeforeEventsDestroyed = function () {
10222 this.triggerBeforeEventSegsDestroyed(this.getEventSegs());
10223 };
10224 DateComponent.prototype.triggerBeforeEventSegsDestroyed = function (segs) {
10225 var _this = this;
10226 if (this.hasPublicHandlers('eventDestroy')) {
10227 segs.forEach(function (seg) {
10228 var legacy;
10229 if (seg.el) { // necessary?
10230 legacy = seg.footprint.getEventLegacy();
10231 _this.publiclyTrigger('eventDestroy', {
10232 context: legacy,
10233 args: [legacy, seg.el, _this]
10234 });
10235 }
10236 });
10237 }
10238 };
10239 // Event Rendering Utils
10240 // -----------------------------------------------------------------------------------------------------------------
10241 // Hides all rendered event segments linked to the given event
10242 // RECURSIVE with subcomponents
10243 DateComponent.prototype.showEventsWithId = function (eventDefId) {
10244 this.getEventSegs().forEach(function (seg) {
10245 if (seg.footprint.eventDef.id === eventDefId &&
10246 seg.el // necessary?
10247 ) {
10248 seg.el.css('visibility', '');
10249 }
10250 });
10251 this.callChildren('showEventsWithId', arguments);
10252 };
10253 // Shows all rendered event segments linked to the given event
10254 // RECURSIVE with subcomponents
10255 DateComponent.prototype.hideEventsWithId = function (eventDefId) {
10256 this.getEventSegs().forEach(function (seg) {
10257 if (seg.footprint.eventDef.id === eventDefId &&
10258 seg.el // necessary?
10259 ) {
10260 seg.el.css('visibility', 'hidden');
10261 }
10262 });
10263 this.callChildren('hideEventsWithId', arguments);
10264 };
10265 // Drag-n-Drop Rendering (for both events and external elements)
10266 // ---------------------------------------------------------------------------------------------------------------
10267 // Renders a visual indication of a event or external-element drag over the given drop zone.
10268 // If an external-element, seg will be `null`.
10269 // Must return elements used for any mock events.
10270 DateComponent.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
10271 var renderedHelper = false;
10272 this.iterChildren(function (child) {
10273 if (child.renderDrag(eventFootprints, seg, isTouch)) {
10274 renderedHelper = true;
10275 }
10276 });
10277 return renderedHelper;
10278 };
10279 // Unrenders a visual indication of an event or external-element being dragged.
10280 DateComponent.prototype.unrenderDrag = function () {
10281 this.callChildren('unrenderDrag', arguments);
10282 };
10283 // Event Resizing
10284 // ---------------------------------------------------------------------------------------------------------------
10285 // Renders a visual indication of an event being resized.
10286 DateComponent.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
10287 this.callChildren('renderEventResize', arguments);
10288 };
10289 // Unrenders a visual indication of an event being resized.
10290 DateComponent.prototype.unrenderEventResize = function () {
10291 this.callChildren('unrenderEventResize', arguments);
10292 };
10293 // Selection
10294 // ---------------------------------------------------------------------------------------------------------------
10295 // Renders a visual indication of the selection
10296 // TODO: rename to `renderSelection` after legacy is gone
10297 DateComponent.prototype.renderSelectionFootprint = function (componentFootprint) {
10298 this.renderHighlight(componentFootprint);
10299 this.callChildren('renderSelectionFootprint', arguments);
10300 };
10301 // Unrenders a visual indication of selection
10302 DateComponent.prototype.unrenderSelection = function () {
10303 this.unrenderHighlight();
10304 this.callChildren('unrenderSelection', arguments);
10305 };
10306 // Highlight
10307 // ---------------------------------------------------------------------------------------------------------------
10308 // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data)
10309 DateComponent.prototype.renderHighlight = function (componentFootprint) {
10310 if (this.fillRenderer) {
10311 this.fillRenderer.renderFootprint('highlight', componentFootprint, {
10312 getClasses: function () {
10313 return ['fc-highlight'];
10314 }
10315 });
10316 }
10317 this.callChildren('renderHighlight', arguments);
10318 };
10319 // Unrenders the emphasis on a date range
10320 DateComponent.prototype.unrenderHighlight = function () {
10321 if (this.fillRenderer) {
10322 this.fillRenderer.unrender('highlight');
10323 }
10324 this.callChildren('unrenderHighlight', arguments);
10325 };
10326 // Hit Areas
10327 // ---------------------------------------------------------------------------------------------------------------
10328 // just because all DateComponents support this interface
10329 // doesn't mean they need to have their own internal coord system. they can defer to sub-components.
10330 DateComponent.prototype.hitsNeeded = function () {
10331 if (!(this.hitsNeededDepth++)) {
10332 this.prepareHits();
10333 }
10334 this.callChildren('hitsNeeded', arguments);
10335 };
10336 DateComponent.prototype.hitsNotNeeded = function () {
10337 if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) {
10338 this.releaseHits();
10339 }
10340 this.callChildren('hitsNotNeeded', arguments);
10341 };
10342 DateComponent.prototype.prepareHits = function () {
10343 // subclasses can implement
10344 };
10345 DateComponent.prototype.releaseHits = function () {
10346 // subclasses can implement
10347 };
10348 // Given coordinates from the topleft of the document, return data about the date-related area underneath.
10349 // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged).
10350 // Must have a `grid` property, a reference to this current grid. TODO: avoid this
10351 // The returned object will be processed by getHitFootprint and getHitEl.
10352 DateComponent.prototype.queryHit = function (leftOffset, topOffset) {
10353 var childrenByUid = this.childrenByUid;
10354 var uid;
10355 var hit;
10356 for (uid in childrenByUid) {
10357 hit = childrenByUid[uid].queryHit(leftOffset, topOffset);
10358 if (hit) {
10359 break;
10360 }
10361 }
10362 return hit;
10363 };
10364 DateComponent.prototype.getSafeHitFootprint = function (hit) {
10365 var footprint = this.getHitFootprint(hit);
10366 if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) {
10367 return null;
10368 }
10369 return footprint;
10370 };
10371 DateComponent.prototype.getHitFootprint = function (hit) {
10372 // what about being abstract!?
10373 };
10374 // Given position-level information about a date-related area within the grid,
10375 // should return a jQuery element that best represents it. passed to dayClick callback.
10376 DateComponent.prototype.getHitEl = function (hit) {
10377 // what about being abstract!?
10378 };
10379 /* Converting eventRange -> eventFootprint
10380 ------------------------------------------------------------------------------------------------------------------*/
10381 DateComponent.prototype.eventRangesToEventFootprints = function (eventRanges) {
10382 var eventFootprints = [];
10383 var i;
10384 for (i = 0; i < eventRanges.length; i++) {
10385 eventFootprints.push.apply(// append
10386 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i]));
10387 }
10388 return eventFootprints;
10389 };
10390 DateComponent.prototype.eventRangeToEventFootprints = function (eventRange) {
10391 return [util_2.eventRangeToEventFootprint(eventRange)];
10392 };
10393 /* Converting componentFootprint/eventFootprint -> segs
10394 ------------------------------------------------------------------------------------------------------------------*/
10395 DateComponent.prototype.eventFootprintsToSegs = function (eventFootprints) {
10396 var segs = [];
10397 var i;
10398 for (i = 0; i < eventFootprints.length; i++) {
10399 segs.push.apply(segs, this.eventFootprintToSegs(eventFootprints[i]));
10400 }
10401 return segs;
10402 };
10403 // Given an event's span (unzoned start/end and other misc data), and the event itself,
10404 // slices into segments and attaches event-derived properties to them.
10405 // eventSpan - { start, end, isStart, isEnd, otherthings... }
10406 DateComponent.prototype.eventFootprintToSegs = function (eventFootprint) {
10407 var unzonedRange = eventFootprint.componentFootprint.unzonedRange;
10408 var segs;
10409 var i;
10410 var seg;
10411 segs = this.componentFootprintToSegs(eventFootprint.componentFootprint);
10412 for (i = 0; i < segs.length; i++) {
10413 seg = segs[i];
10414 if (!unzonedRange.isStart) {
10415 seg.isStart = false;
10416 }
10417 if (!unzonedRange.isEnd) {
10418 seg.isEnd = false;
10419 }
10420 seg.footprint = eventFootprint;
10421 // TODO: rename to seg.eventFootprint
10422 }
10423 return segs;
10424 };
10425 DateComponent.prototype.componentFootprintToSegs = function (componentFootprint) {
10426 return [];
10427 };
10428 // Utils
10429 // ---------------------------------------------------------------------------------------------------------------
10430 DateComponent.prototype.callChildren = function (methodName, args) {
10431 this.iterChildren(function (child) {
10432 child[methodName].apply(child, args);
10433 });
10434 };
10435 DateComponent.prototype.iterChildren = function (func) {
10436 var childrenByUid = this.childrenByUid;
10437 var uid;
10438 for (uid in childrenByUid) {
10439 func(childrenByUid[uid]);
10440 }
10441 };
10442 DateComponent.prototype._getCalendar = function () {
10443 var t = this;
10444 return t.calendar || t.view.calendar;
10445 };
10446 DateComponent.prototype._getView = function () {
10447 return this.view;
10448 };
10449 DateComponent.prototype._getDateProfile = function () {
10450 return this._getView().get('dateProfile');
10451 };
10452 // Generates HTML for an anchor to another view into the calendar.
10453 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
10454 // `gotoOptions` can either be a moment input, or an object with the form:
10455 // { date, type, forceOff }
10456 // `type` is a view-type like "day" or "week". default value is "day".
10457 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
10458 DateComponent.prototype.buildGotoAnchorHtml = function (gotoOptions, attrs, innerHtml) {
10459 var date;
10460 var type;
10461 var forceOff;
10462 var finalOptions;
10463 if ($.isPlainObject(gotoOptions)) {
10464 date = gotoOptions.date;
10465 type = gotoOptions.type;
10466 forceOff = gotoOptions.forceOff;
10467 }
10468 else {
10469 date = gotoOptions; // a single moment input
10470 }
10471 date = moment_ext_1.default(date); // if a string, parse it
10472 finalOptions = {
10473 date: date.format('YYYY-MM-DD'),
10474 type: type || 'day'
10475 };
10476 if (typeof attrs === 'string') {
10477 innerHtml = attrs;
10478 attrs = null;
10479 }
10480 attrs = attrs ? ' ' + util_1.attrsToStr(attrs) : ''; // will have a leading space
10481 innerHtml = innerHtml || '';
10482 if (!forceOff && this.opt('navLinks')) {
10483 return '<a' + attrs +
10484 ' data-goto="' + util_1.htmlEscape(JSON.stringify(finalOptions)) + '">' +
10485 innerHtml +
10486 '</a>';
10487 }
10488 else {
10489 return '<span' + attrs + '>' +
10490 innerHtml +
10491 '</span>';
10492 }
10493 };
10494 DateComponent.prototype.getAllDayHtml = function () {
10495 return this.opt('allDayHtml') || util_1.htmlEscape(this.opt('allDayText'));
10496 };
10497 // Computes HTML classNames for a single-day element
10498 DateComponent.prototype.getDayClasses = function (date, noThemeHighlight) {
10499 var view = this._getView();
10500 var classes = [];
10501 var today;
10502 if (!this.dateProfile.activeUnzonedRange.containsDate(date)) {
10503 classes.push('fc-disabled-day'); // TODO: jQuery UI theme?
10504 }
10505 else {
10506 classes.push('fc-' + util_1.dayIDs[date.day()]);
10507 if (view.isDateInOtherMonth(date, this.dateProfile)) { // TODO: use DateComponent subclass somehow
10508 classes.push('fc-other-month');
10509 }
10510 today = view.calendar.getNow();
10511 if (date.isSame(today, 'day')) {
10512 classes.push('fc-today');
10513 if (noThemeHighlight !== true) {
10514 classes.push(view.calendar.theme.getClass('today'));
10515 }
10516 }
10517 else if (date < today) {
10518 classes.push('fc-past');
10519 }
10520 else {
10521 classes.push('fc-future');
10522 }
10523 }
10524 return classes;
10525 };
10526 // Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
10527 // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
10528 // The timezones of the dates within `range` will be respected.
10529 DateComponent.prototype.formatRange = function (range, isAllDay, formatStr, separator) {
10530 var end = range.end;
10531 if (isAllDay) {
10532 end = end.clone().subtract(1); // convert to inclusive. last ms of previous day
10533 }
10534 return date_formatting_1.formatRange(range.start, end, formatStr, separator, this.isRTL);
10535 };
10536 // Compute the number of the give units in the "current" range.
10537 // Will return a floating-point number. Won't round.
10538 DateComponent.prototype.currentRangeAs = function (unit) {
10539 return this._getDateProfile().currentUnzonedRange.as(unit);
10540 };
10541 // Returns the date range of the full days the given range visually appears to occupy.
10542 // Returns a plain object with start/end, NOT an UnzonedRange!
10543 DateComponent.prototype.computeDayRange = function (unzonedRange) {
10544 var calendar = this._getCalendar();
10545 var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts
10546 var end = calendar.msToUtcMoment(unzonedRange.endMs);
10547 var endTimeMS = +end.time(); // # of milliseconds into `endDay`
10548 var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends
10549 // If the end time is actually inclusively part of the next day and is equal to or
10550 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
10551 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
10552 if (endTimeMS && endTimeMS >= this.nextDayThreshold) {
10553 endDay.add(1, 'days');
10554 }
10555 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
10556 if (endDay <= startDay) {
10557 endDay = startDay.clone().add(1, 'days');
10558 }
10559 return { start: startDay, end: endDay };
10560 };
10561 // Does the given range visually appear to occupy more than one day?
10562 DateComponent.prototype.isMultiDayRange = function (unzonedRange) {
10563 var dayRange = this.computeDayRange(unzonedRange);
10564 return dayRange.end.diff(dayRange.start, 'days') > 1;
10565 };
10566 DateComponent.guid = 0; // TODO: better system for this?
10567 return DateComponent;
10568 }(Component_1.default));
10569 exports.default = DateComponent;
10570 // legacy
10571 function convertEventsPayloadToLegacyArray(eventsPayload) {
10572 var eventDefId;
10573 var eventInstances;
10574 var legacyEvents = [];
10575 var i;
10576 for (eventDefId in eventsPayload) {
10577 eventInstances = eventsPayload[eventDefId].eventInstances;
10578 for (i = 0; i < eventInstances.length; i++) {
10579 legacyEvents.push(eventInstances[i].toLegacy());
10580 }
10581 }
10582 return legacyEvents;
10583 }
10584
10585
10586 /***/ }),
10587 /* 232 */
10588 /***/ (function(module, exports, __webpack_require__) {
10589
10590 Object.defineProperty(exports, "__esModule", { value: true });
10591 var $ = __webpack_require__(3);
10592 var moment = __webpack_require__(0);
10593 var util_1 = __webpack_require__(4);
10594 var options_1 = __webpack_require__(33);
10595 var Iterator_1 = __webpack_require__(225);
10596 var GlobalEmitter_1 = __webpack_require__(23);
10597 var EmitterMixin_1 = __webpack_require__(13);
10598 var ListenerMixin_1 = __webpack_require__(7);
10599 var Toolbar_1 = __webpack_require__(257);
10600 var OptionsManager_1 = __webpack_require__(258);
10601 var ViewSpecManager_1 = __webpack_require__(259);
10602 var Constraints_1 = __webpack_require__(217);
10603 var locale_1 = __webpack_require__(32);
10604 var moment_ext_1 = __webpack_require__(11);
10605 var UnzonedRange_1 = __webpack_require__(5);
10606 var ComponentFootprint_1 = __webpack_require__(12);
10607 var EventDateProfile_1 = __webpack_require__(16);
10608 var EventManager_1 = __webpack_require__(220);
10609 var BusinessHourGenerator_1 = __webpack_require__(218);
10610 var EventSourceParser_1 = __webpack_require__(38);
10611 var EventDefParser_1 = __webpack_require__(36);
10612 var SingleEventDef_1 = __webpack_require__(9);
10613 var EventDefMutation_1 = __webpack_require__(39);
10614 var EventSource_1 = __webpack_require__(6);
10615 var ThemeRegistry_1 = __webpack_require__(57);
10616 var Calendar = /** @class */ (function () {
10617 function Calendar(el, overrides) {
10618 this.loadingLevel = 0; // number of simultaneous loading tasks
10619 this.ignoreUpdateViewSize = 0;
10620 this.freezeContentHeightDepth = 0;
10621 // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection.
10622 // unneeded() is called in destroy.
10623 GlobalEmitter_1.default.needed();
10624 this.el = el;
10625 this.viewsByType = {};
10626 this.optionsManager = new OptionsManager_1.default(this, overrides);
10627 this.viewSpecManager = new ViewSpecManager_1.default(this.optionsManager, this);
10628 this.initMomentInternals(); // needs to happen after options hash initialized
10629 this.initCurrentDate();
10630 this.initEventManager();
10631 this.constraints = new Constraints_1.default(this.eventManager, this);
10632 this.constructed();
10633 }
10634 Calendar.prototype.constructed = function () {
10635 // useful for monkeypatching. used?
10636 };
10637 Calendar.prototype.getView = function () {
10638 return this.view;
10639 };
10640 Calendar.prototype.publiclyTrigger = function (name, triggerInfo) {
10641 var optHandler = this.opt(name);
10642 var context;
10643 var args;
10644 if ($.isPlainObject(triggerInfo)) {
10645 context = triggerInfo.context;
10646 args = triggerInfo.args;
10647 }
10648 else if ($.isArray(triggerInfo)) {
10649 args = triggerInfo;
10650 }
10651 if (context == null) {
10652 context = this.el[0]; // fallback context
10653 }
10654 if (!args) {
10655 args = [];
10656 }
10657 this.triggerWith(name, context, args); // Emitter's method
10658 if (optHandler) {
10659 return optHandler.apply(context, args);
10660 }
10661 };
10662 Calendar.prototype.hasPublicHandlers = function (name) {
10663 return this.hasHandlers(name) ||
10664 this.opt(name); // handler specified in options
10665 };
10666 // Options Public API
10667 // -----------------------------------------------------------------------------------------------------------------
10668 // public getter/setter
10669 Calendar.prototype.option = function (name, value) {
10670 var newOptionHash;
10671 if (typeof name === 'string') {
10672 if (value === undefined) { // getter
10673 return this.optionsManager.get(name);
10674 }
10675 else { // setter for individual option
10676 newOptionHash = {};
10677 newOptionHash[name] = value;
10678 this.optionsManager.add(newOptionHash);
10679 }
10680 }
10681 else if (typeof name === 'object') { // compound setter with object input
10682 this.optionsManager.add(name);
10683 }
10684 };
10685 // private getter
10686 Calendar.prototype.opt = function (name) {
10687 return this.optionsManager.get(name);
10688 };
10689 // View
10690 // -----------------------------------------------------------------------------------------------------------------
10691 // Given a view name for a custom view or a standard view, creates a ready-to-go View object
10692 Calendar.prototype.instantiateView = function (viewType) {
10693 var spec = this.viewSpecManager.getViewSpec(viewType);
10694 if (!spec) {
10695 throw new Error("View type \"" + viewType + "\" is not valid");
10696 }
10697 return new spec['class'](this, spec);
10698 };
10699 // Returns a boolean about whether the view is okay to instantiate at some point
10700 Calendar.prototype.isValidViewType = function (viewType) {
10701 return Boolean(this.viewSpecManager.getViewSpec(viewType));
10702 };
10703 Calendar.prototype.changeView = function (viewName, dateOrRange) {
10704 if (dateOrRange) {
10705 if (dateOrRange.start && dateOrRange.end) { // a range
10706 this.optionsManager.recordOverrides({
10707 visibleRange: dateOrRange
10708 });
10709 }
10710 else { // a date
10711 this.currentDate = this.moment(dateOrRange).stripZone(); // just like gotoDate
10712 }
10713 }
10714 this.renderView(viewName);
10715 };
10716 // Forces navigation to a view for the given date.
10717 // `viewType` can be a specific view name or a generic one like "week" or "day".
10718 Calendar.prototype.zoomTo = function (newDate, viewType) {
10719 var spec;
10720 viewType = viewType || 'day'; // day is default zoom
10721 spec = this.viewSpecManager.getViewSpec(viewType) ||
10722 this.viewSpecManager.getUnitViewSpec(viewType);
10723 this.currentDate = newDate.clone();
10724 this.renderView(spec ? spec.type : null);
10725 };
10726 // Current Date
10727 // -----------------------------------------------------------------------------------------------------------------
10728 Calendar.prototype.initCurrentDate = function () {
10729 var defaultDateInput = this.opt('defaultDate');
10730 // compute the initial ambig-timezone date
10731 if (defaultDateInput != null) {
10732 this.currentDate = this.moment(defaultDateInput).stripZone();
10733 }
10734 else {
10735 this.currentDate = this.getNow(); // getNow already returns unzoned
10736 }
10737 };
10738 Calendar.prototype.prev = function () {
10739 var view = this.view;
10740 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile'));
10741 if (prevInfo.isValid) {
10742 this.currentDate = prevInfo.date;
10743 this.renderView();
10744 }
10745 };
10746 Calendar.prototype.next = function () {
10747 var view = this.view;
10748 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile'));
10749 if (nextInfo.isValid) {
10750 this.currentDate = nextInfo.date;
10751 this.renderView();
10752 }
10753 };
10754 Calendar.prototype.prevYear = function () {
10755 this.currentDate.add(-1, 'years');
10756 this.renderView();
10757 };
10758 Calendar.prototype.nextYear = function () {
10759 this.currentDate.add(1, 'years');
10760 this.renderView();
10761 };
10762 Calendar.prototype.today = function () {
10763 this.currentDate = this.getNow(); // should deny like prev/next?
10764 this.renderView();
10765 };
10766 Calendar.prototype.gotoDate = function (zonedDateInput) {
10767 this.currentDate = this.moment(zonedDateInput).stripZone();
10768 this.renderView();
10769 };
10770 Calendar.prototype.incrementDate = function (delta) {
10771 this.currentDate.add(moment.duration(delta));
10772 this.renderView();
10773 };
10774 // for external API
10775 Calendar.prototype.getDate = function () {
10776 return this.applyTimezone(this.currentDate); // infuse the calendar's timezone
10777 };
10778 // Loading Triggering
10779 // -----------------------------------------------------------------------------------------------------------------
10780 // Should be called when any type of async data fetching begins
10781 Calendar.prototype.pushLoading = function () {
10782 if (!(this.loadingLevel++)) {
10783 this.publiclyTrigger('loading', [true, this.view]);
10784 }
10785 };
10786 // Should be called when any type of async data fetching completes
10787 Calendar.prototype.popLoading = function () {
10788 if (!(--this.loadingLevel)) {
10789 this.publiclyTrigger('loading', [false, this.view]);
10790 }
10791 };
10792 // High-level Rendering
10793 // -----------------------------------------------------------------------------------
10794 Calendar.prototype.render = function () {
10795 if (!this.contentEl) {
10796 this.initialRender();
10797 }
10798 else if (this.elementVisible()) {
10799 // mainly for the public API
10800 this.calcSize();
10801 this.updateViewSize();
10802 }
10803 };
10804 Calendar.prototype.initialRender = function () {
10805 var _this = this;
10806 var el = this.el;
10807 el.addClass('fc');
10808 // event delegation for nav links
10809 el.on('click.fc', 'a[data-goto]', function (ev) {
10810 var anchorEl = $(ev.currentTarget);
10811 var gotoOptions = anchorEl.data('goto'); // will automatically parse JSON
10812 var date = _this.moment(gotoOptions.date);
10813 var viewType = gotoOptions.type;
10814 // property like "navLinkDayClick". might be a string or a function
10815 var customAction = _this.view.opt('navLink' + util_1.capitaliseFirstLetter(viewType) + 'Click');
10816 if (typeof customAction === 'function') {
10817 customAction(date, ev);
10818 }
10819 else {
10820 if (typeof customAction === 'string') {
10821 viewType = customAction;
10822 }
10823 _this.zoomTo(date, viewType);
10824 }
10825 });
10826 // called immediately, and upon option change
10827 this.optionsManager.watch('settingTheme', ['?theme', '?themeSystem'], function (opts) {
10828 var themeClass = ThemeRegistry_1.getThemeSystemClass(opts.themeSystem || opts.theme);
10829 var theme = new themeClass(_this.optionsManager);
10830 var widgetClass = theme.getClass('widget');
10831 _this.theme = theme;
10832 if (widgetClass) {
10833 el.addClass(widgetClass);
10834 }
10835 }, function () {
10836 var widgetClass = _this.theme.getClass('widget');
10837 _this.theme = null;
10838 if (widgetClass) {
10839 el.removeClass(widgetClass);
10840 }
10841 });
10842 this.optionsManager.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps) {
10843 _this.businessHourGenerator = new BusinessHourGenerator_1.default(deps.businessHours, _this);
10844 if (_this.view) {
10845 _this.view.set('businessHourGenerator', _this.businessHourGenerator);
10846 }
10847 }, function () {
10848 _this.businessHourGenerator = null;
10849 });
10850 // called immediately, and upon option change.
10851 // HACK: locale often affects isRTL, so we explicitly listen to that too.
10852 this.optionsManager.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts) {
10853 el.toggleClass('fc-ltr', !opts.isRTL);
10854 el.toggleClass('fc-rtl', opts.isRTL);
10855 });
10856 this.contentEl = $("<div class='fc-view-container'>").prependTo(el);
10857 this.initToolbars();
10858 this.renderHeader();
10859 this.renderFooter();
10860 this.renderView(this.opt('defaultView'));
10861 if (this.opt('handleWindowResize')) {
10862 $(window).resize(this.windowResizeProxy = util_1.debounce(// prevents rapid calls
10863 this.windowResize.bind(this), this.opt('windowResizeDelay')));
10864 }
10865 };
10866 Calendar.prototype.destroy = function () {
10867 if (this.view) {
10868 this.clearView();
10869 }
10870 this.toolbarsManager.proxyCall('removeElement');
10871 this.contentEl.remove();
10872 this.el.removeClass('fc fc-ltr fc-rtl');
10873 // removes theme-related root className
10874 this.optionsManager.unwatch('settingTheme');
10875 this.optionsManager.unwatch('settingBusinessHourGenerator');
10876 this.el.off('.fc'); // unbind nav link handlers
10877 if (this.windowResizeProxy) {
10878 $(window).unbind('resize', this.windowResizeProxy);
10879 this.windowResizeProxy = null;
10880 }
10881 GlobalEmitter_1.default.unneeded();
10882 };
10883 Calendar.prototype.elementVisible = function () {
10884 return this.el.is(':visible');
10885 };
10886 // Render Queue
10887 // -----------------------------------------------------------------------------------------------------------------
10888 Calendar.prototype.bindViewHandlers = function (view) {
10889 var _this = this;
10890 view.watch('titleForCalendar', ['title'], function (deps) {
10891 if (view === _this.view) { // hack
10892 _this.setToolbarsTitle(deps.title);
10893 }
10894 });
10895 view.watch('dateProfileForCalendar', ['dateProfile'], function (deps) {
10896 if (view === _this.view) { // hack
10897 _this.currentDate = deps.dateProfile.date; // might have been constrained by view dates
10898 _this.updateToolbarButtons(deps.dateProfile);
10899 }
10900 });
10901 };
10902 Calendar.prototype.unbindViewHandlers = function (view) {
10903 view.unwatch('titleForCalendar');
10904 view.unwatch('dateProfileForCalendar');
10905 };
10906 // View Rendering
10907 // -----------------------------------------------------------------------------------
10908 // Renders a view because of a date change, view-type change, or for the first time.
10909 // If not given a viewType, keep the current view but render different dates.
10910 // Accepts an optional scroll state to restore to.
10911 Calendar.prototype.renderView = function (viewType) {
10912 var oldView = this.view;
10913 var newView;
10914 this.freezeContentHeight();
10915 if (oldView && viewType && oldView.type !== viewType) {
10916 this.clearView();
10917 }
10918 // if viewType changed, or the view was never created, create a fresh view
10919 if (!this.view && viewType) {
10920 newView = this.view =
10921 this.viewsByType[viewType] ||
10922 (this.viewsByType[viewType] = this.instantiateView(viewType));
10923 this.bindViewHandlers(newView);
10924 newView.startBatchRender(); // so that setElement+setDate rendering are joined
10925 newView.setElement($("<div class='fc-view fc-" + viewType + "-view'>").appendTo(this.contentEl));
10926 this.toolbarsManager.proxyCall('activateButton', viewType);
10927 }
10928 if (this.view) {
10929 // prevent unnecessary change firing
10930 if (this.view.get('businessHourGenerator') !== this.businessHourGenerator) {
10931 this.view.set('businessHourGenerator', this.businessHourGenerator);
10932 }
10933 this.view.setDate(this.currentDate);
10934 if (newView) {
10935 newView.stopBatchRender();
10936 }
10937 }
10938 this.thawContentHeight();
10939 };
10940 // Unrenders the current view and reflects this change in the Header.
10941 // Unregsiters the `view`, but does not remove from viewByType hash.
10942 Calendar.prototype.clearView = function () {
10943 var currentView = this.view;
10944 this.toolbarsManager.proxyCall('deactivateButton', currentView.type);
10945 this.unbindViewHandlers(currentView);
10946 currentView.removeElement();
10947 currentView.unsetDate(); // so bindViewHandlers doesn't fire with old values next time
10948 this.view = null;
10949 };
10950 // Destroys the view, including the view object. Then, re-instantiates it and renders it.
10951 // Maintains the same scroll state.
10952 // TODO: maintain any other user-manipulated state.
10953 Calendar.prototype.reinitView = function () {
10954 var oldView = this.view;
10955 var scroll = oldView.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll
10956 this.freezeContentHeight();
10957 this.clearView();
10958 this.calcSize();
10959 this.renderView(oldView.type); // needs the type to freshly render
10960 this.view.applyScroll(scroll);
10961 this.thawContentHeight();
10962 };
10963 // Resizing
10964 // -----------------------------------------------------------------------------------
10965 Calendar.prototype.getSuggestedViewHeight = function () {
10966 if (this.suggestedViewHeight == null) {
10967 this.calcSize();
10968 }
10969 return this.suggestedViewHeight;
10970 };
10971 Calendar.prototype.isHeightAuto = function () {
10972 return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto';
10973 };
10974 Calendar.prototype.updateViewSize = function (isResize) {
10975 if (isResize === void 0) { isResize = false; }
10976 var view = this.view;
10977 var scroll;
10978 if (!this.ignoreUpdateViewSize && view) {
10979 if (isResize) {
10980 this.calcSize();
10981 scroll = view.queryScroll();
10982 }
10983 this.ignoreUpdateViewSize++;
10984 view.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize);
10985 this.ignoreUpdateViewSize--;
10986 if (isResize) {
10987 view.applyScroll(scroll);
10988 }
10989 return true; // signal success
10990 }
10991 };
10992 Calendar.prototype.calcSize = function () {
10993 if (this.elementVisible()) {
10994 this._calcSize();
10995 }
10996 };
10997 Calendar.prototype._calcSize = function () {
10998 var contentHeightInput = this.opt('contentHeight');
10999 var heightInput = this.opt('height');
11000 if (typeof contentHeightInput === 'number') { // exists and not 'auto'
11001 this.suggestedViewHeight = contentHeightInput;
11002 }
11003 else if (typeof contentHeightInput === 'function') { // exists and is a function
11004 this.suggestedViewHeight = contentHeightInput();
11005 }
11006 else if (typeof heightInput === 'number') { // exists and not 'auto'
11007 this.suggestedViewHeight = heightInput - this.queryToolbarsHeight();
11008 }
11009 else if (typeof heightInput === 'function') { // exists and is a function
11010 this.suggestedViewHeight = heightInput() - this.queryToolbarsHeight();
11011 }
11012 else if (heightInput === 'parent') { // set to height of parent element
11013 this.suggestedViewHeight = this.el.parent().height() - this.queryToolbarsHeight();
11014 }
11015 else {
11016 this.suggestedViewHeight = Math.round(this.contentEl.width() /
11017 Math.max(this.opt('aspectRatio'), .5));
11018 }
11019 };
11020 Calendar.prototype.windowResize = function (ev) {
11021 if (
11022 // the purpose: so we don't process jqui "resize" events that have bubbled up
11023 // cast to any because .target, which is Element, can't be compared to window for some reason.
11024 ev.target === window &&
11025 this.view &&
11026 this.view.isDatesRendered) {
11027 if (this.updateViewSize(true)) { // isResize=true, returns true on success
11028 this.publiclyTrigger('windowResize', [this.view]);
11029 }
11030 }
11031 };
11032 /* Height "Freezing"
11033 -----------------------------------------------------------------------------*/
11034 Calendar.prototype.freezeContentHeight = function () {
11035 if (!(this.freezeContentHeightDepth++)) {
11036 this.forceFreezeContentHeight();
11037 }
11038 };
11039 Calendar.prototype.forceFreezeContentHeight = function () {
11040 this.contentEl.css({
11041 width: '100%',
11042 height: this.contentEl.height(),
11043 overflow: 'hidden'
11044 });
11045 };
11046 Calendar.prototype.thawContentHeight = function () {
11047 this.freezeContentHeightDepth--;
11048 // always bring back to natural height
11049 this.contentEl.css({
11050 width: '',
11051 height: '',
11052 overflow: ''
11053 });
11054 // but if there are future thaws, re-freeze
11055 if (this.freezeContentHeightDepth) {
11056 this.forceFreezeContentHeight();
11057 }
11058 };
11059 // Toolbar
11060 // -----------------------------------------------------------------------------------------------------------------
11061 Calendar.prototype.initToolbars = function () {
11062 this.header = new Toolbar_1.default(this, this.computeHeaderOptions());
11063 this.footer = new Toolbar_1.default(this, this.computeFooterOptions());
11064 this.toolbarsManager = new Iterator_1.default([this.header, this.footer]);
11065 };
11066 Calendar.prototype.computeHeaderOptions = function () {
11067 return {
11068 extraClasses: 'fc-header-toolbar',
11069 layout: this.opt('header')
11070 };
11071 };
11072 Calendar.prototype.computeFooterOptions = function () {
11073 return {
11074 extraClasses: 'fc-footer-toolbar',
11075 layout: this.opt('footer')
11076 };
11077 };
11078 // can be called repeatedly and Header will rerender
11079 Calendar.prototype.renderHeader = function () {
11080 var header = this.header;
11081 header.setToolbarOptions(this.computeHeaderOptions());
11082 header.render();
11083 if (header.el) {
11084 this.el.prepend(header.el);
11085 }
11086 };
11087 // can be called repeatedly and Footer will rerender
11088 Calendar.prototype.renderFooter = function () {
11089 var footer = this.footer;
11090 footer.setToolbarOptions(this.computeFooterOptions());
11091 footer.render();
11092 if (footer.el) {
11093 this.el.append(footer.el);
11094 }
11095 };
11096 Calendar.prototype.setToolbarsTitle = function (title) {
11097 this.toolbarsManager.proxyCall('updateTitle', title);
11098 };
11099 Calendar.prototype.updateToolbarButtons = function (dateProfile) {
11100 var now = this.getNow();
11101 var view = this.view;
11102 var todayInfo = view.dateProfileGenerator.build(now);
11103 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile'));
11104 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile'));
11105 this.toolbarsManager.proxyCall((todayInfo.isValid && !dateProfile.currentUnzonedRange.containsDate(now)) ?
11106 'enableButton' :
11107 'disableButton', 'today');
11108 this.toolbarsManager.proxyCall(prevInfo.isValid ?
11109 'enableButton' :
11110 'disableButton', 'prev');
11111 this.toolbarsManager.proxyCall(nextInfo.isValid ?
11112 'enableButton' :
11113 'disableButton', 'next');
11114 };
11115 Calendar.prototype.queryToolbarsHeight = function () {
11116 return this.toolbarsManager.items.reduce(function (accumulator, toolbar) {
11117 var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin
11118 return accumulator + toolbarHeight;
11119 }, 0);
11120 };
11121 // Selection
11122 // -----------------------------------------------------------------------------------------------------------------
11123 // this public method receives start/end dates in any format, with any timezone
11124 Calendar.prototype.select = function (zonedStartInput, zonedEndInput) {
11125 this.view.select(this.buildSelectFootprint.apply(this, arguments));
11126 };
11127 Calendar.prototype.unselect = function () {
11128 if (this.view) {
11129 this.view.unselect();
11130 }
11131 };
11132 // Given arguments to the select method in the API, returns a span (unzoned start/end and other info)
11133 Calendar.prototype.buildSelectFootprint = function (zonedStartInput, zonedEndInput) {
11134 var start = this.moment(zonedStartInput).stripZone();
11135 var end;
11136 if (zonedEndInput) {
11137 end = this.moment(zonedEndInput).stripZone();
11138 }
11139 else if (start.hasTime()) {
11140 end = start.clone().add(this.defaultTimedEventDuration);
11141 }
11142 else {
11143 end = start.clone().add(this.defaultAllDayEventDuration);
11144 }
11145 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), !start.hasTime());
11146 };
11147 // Date Utils
11148 // -----------------------------------------------------------------------------------------------------------------
11149 Calendar.prototype.initMomentInternals = function () {
11150 var _this = this;
11151 this.defaultAllDayEventDuration = moment.duration(this.opt('defaultAllDayEventDuration'));
11152 this.defaultTimedEventDuration = moment.duration(this.opt('defaultTimedEventDuration'));
11153 // Called immediately, and when any of the options change.
11154 // Happens before any internal objects rebuild or rerender, because this is very core.
11155 this.optionsManager.watch('buildingMomentLocale', [
11156 '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort',
11157 '?firstDay', '?weekNumberCalculation'
11158 ], function (opts) {
11159 var weekNumberCalculation = opts.weekNumberCalculation;
11160 var firstDay = opts.firstDay;
11161 var _week;
11162 // normalize
11163 if (weekNumberCalculation === 'iso') {
11164 weekNumberCalculation = 'ISO'; // normalize
11165 }
11166 var localeData = Object.create(// make a cheap copy
11167 locale_1.getMomentLocaleData(opts.locale) // will fall back to en
11168 );
11169 if (opts.monthNames) {
11170 localeData._months = opts.monthNames;
11171 }
11172 if (opts.monthNamesShort) {
11173 localeData._monthsShort = opts.monthNamesShort;
11174 }
11175 if (opts.dayNames) {
11176 localeData._weekdays = opts.dayNames;
11177 }
11178 if (opts.dayNamesShort) {
11179 localeData._weekdaysShort = opts.dayNamesShort;
11180 }
11181 if (firstDay == null && weekNumberCalculation === 'ISO') {
11182 firstDay = 1;
11183 }
11184 if (firstDay != null) {
11185 _week = Object.create(localeData._week); // _week: { dow: # }
11186 _week.dow = firstDay;
11187 localeData._week = _week;
11188 }
11189 if ( // whitelist certain kinds of input
11190 weekNumberCalculation === 'ISO' ||
11191 weekNumberCalculation === 'local' ||
11192 typeof weekNumberCalculation === 'function') {
11193 localeData._fullCalendar_weekCalc = weekNumberCalculation; // moment-ext will know what to do with it
11194 }
11195 _this.localeData = localeData;
11196 // If the internal current date object already exists, move to new locale.
11197 // We do NOT need to do this technique for event dates, because this happens when converting to "segments".
11198 if (_this.currentDate) {
11199 _this.localizeMoment(_this.currentDate); // sets to localeData
11200 }
11201 });
11202 };
11203 // Builds a moment using the settings of the current calendar: timezone and locale.
11204 // Accepts anything the vanilla moment() constructor accepts.
11205 Calendar.prototype.moment = function () {
11206 var args = [];
11207 for (var _i = 0; _i < arguments.length; _i++) {
11208 args[_i] = arguments[_i];
11209 }
11210 var mom;
11211 if (this.opt('timezone') === 'local') {
11212 mom = moment_ext_1.default.apply(null, args);
11213 // Force the moment to be local, because momentExt doesn't guarantee it.
11214 if (mom.hasTime()) { // don't give ambiguously-timed moments a local zone
11215 mom.local();
11216 }
11217 }
11218 else if (this.opt('timezone') === 'UTC') {
11219 mom = moment_ext_1.default.utc.apply(null, args); // process as UTC
11220 }
11221 else {
11222 mom = moment_ext_1.default.parseZone.apply(null, args); // let the input decide the zone
11223 }
11224 this.localizeMoment(mom); // TODO
11225 return mom;
11226 };
11227 Calendar.prototype.msToMoment = function (ms, forceAllDay) {
11228 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC
11229 if (forceAllDay) {
11230 mom.stripTime();
11231 }
11232 else {
11233 mom = this.applyTimezone(mom); // may or may not apply locale
11234 }
11235 this.localizeMoment(mom);
11236 return mom;
11237 };
11238 Calendar.prototype.msToUtcMoment = function (ms, forceAllDay) {
11239 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC
11240 if (forceAllDay) {
11241 mom.stripTime();
11242 }
11243 this.localizeMoment(mom);
11244 return mom;
11245 };
11246 // Updates the given moment's locale settings to the current calendar locale settings.
11247 Calendar.prototype.localizeMoment = function (mom) {
11248 mom._locale = this.localeData;
11249 };
11250 // Returns a boolean about whether or not the calendar knows how to calculate
11251 // the timezone offset of arbitrary dates in the current timezone.
11252 Calendar.prototype.getIsAmbigTimezone = function () {
11253 return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC';
11254 };
11255 // Returns a copy of the given date in the current timezone. Has no effect on dates without times.
11256 Calendar.prototype.applyTimezone = function (date) {
11257 if (!date.hasTime()) {
11258 return date.clone();
11259 }
11260 var zonedDate = this.moment(date.toArray());
11261 var timeAdjust = date.time().asMilliseconds() - zonedDate.time().asMilliseconds();
11262 var adjustedZonedDate;
11263 // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396)
11264 if (timeAdjust) { // is the time result different than expected?
11265 adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds
11266 if (date.time().asMilliseconds() - adjustedZonedDate.time().asMilliseconds() === 0) { // does it match perfectly now?
11267 zonedDate = adjustedZonedDate;
11268 }
11269 }
11270 return zonedDate;
11271 };
11272 /*
11273 Assumes the footprint is non-open-ended.
11274 */
11275 Calendar.prototype.footprintToDateProfile = function (componentFootprint, ignoreEnd) {
11276 if (ignoreEnd === void 0) { ignoreEnd = false; }
11277 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs);
11278 var end;
11279 if (!ignoreEnd) {
11280 end = moment_ext_1.default.utc(componentFootprint.unzonedRange.endMs);
11281 }
11282 if (componentFootprint.isAllDay) {
11283 start.stripTime();
11284 if (end) {
11285 end.stripTime();
11286 }
11287 }
11288 else {
11289 start = this.applyTimezone(start);
11290 if (end) {
11291 end = this.applyTimezone(end);
11292 }
11293 }
11294 this.localizeMoment(start);
11295 if (end) {
11296 this.localizeMoment(end);
11297 }
11298 return new EventDateProfile_1.default(start, end, this);
11299 };
11300 // Returns a moment for the current date, as defined by the client's computer or from the `now` option.
11301 // Will return an moment with an ambiguous timezone.
11302 Calendar.prototype.getNow = function () {
11303 var now = this.opt('now');
11304 if (typeof now === 'function') {
11305 now = now();
11306 }
11307 return this.moment(now).stripZone();
11308 };
11309 // Produces a human-readable string for the given duration.
11310 // Side-effect: changes the locale of the given duration.
11311 Calendar.prototype.humanizeDuration = function (duration) {
11312 return duration.locale(this.opt('locale')).humanize();
11313 };
11314 // will return `null` if invalid range
11315 Calendar.prototype.parseUnzonedRange = function (rangeInput) {
11316 var start = null;
11317 var end = null;
11318 if (rangeInput.start) {
11319 start = this.moment(rangeInput.start).stripZone();
11320 }
11321 if (rangeInput.end) {
11322 end = this.moment(rangeInput.end).stripZone();
11323 }
11324 if (!start && !end) {
11325 return null;
11326 }
11327 if (start && end && end.isBefore(start)) {
11328 return null;
11329 }
11330 return new UnzonedRange_1.default(start, end);
11331 };
11332 // Event-Date Utilities
11333 // -----------------------------------------------------------------------------------------------------------------
11334 Calendar.prototype.initEventManager = function () {
11335 var _this = this;
11336 var eventManager = new EventManager_1.default(this);
11337 var rawSources = this.opt('eventSources') || [];
11338 var singleRawSource = this.opt('events');
11339 this.eventManager = eventManager;
11340 if (singleRawSource) {
11341 rawSources.unshift(singleRawSource);
11342 }
11343 eventManager.on('release', function (eventsPayload) {
11344 _this.trigger('eventsReset', eventsPayload);
11345 });
11346 eventManager.freeze();
11347 rawSources.forEach(function (rawSource) {
11348 var source = EventSourceParser_1.default.parse(rawSource, _this);
11349 if (source) {
11350 eventManager.addSource(source);
11351 }
11352 });
11353 eventManager.thaw();
11354 };
11355 Calendar.prototype.requestEvents = function (start, end) {
11356 return this.eventManager.requestEvents(start, end, this.opt('timezone'), !this.opt('lazyFetching'));
11357 };
11358 // Get an event's normalized end date. If not present, calculate it from the defaults.
11359 Calendar.prototype.getEventEnd = function (event) {
11360 if (event.end) {
11361 return event.end.clone();
11362 }
11363 else {
11364 return this.getDefaultEventEnd(event.allDay, event.start);
11365 }
11366 };
11367 // Given an event's allDay status and start date, return what its fallback end date should be.
11368 // TODO: rename to computeDefaultEventEnd
11369 Calendar.prototype.getDefaultEventEnd = function (allDay, zonedStart) {
11370 var end = zonedStart.clone();
11371 if (allDay) {
11372 end.stripTime().add(this.defaultAllDayEventDuration);
11373 }
11374 else {
11375 end.add(this.defaultTimedEventDuration);
11376 }
11377 if (this.getIsAmbigTimezone()) {
11378 end.stripZone(); // we don't know what the tzo should be
11379 }
11380 return end;
11381 };
11382 // Public Events API
11383 // -----------------------------------------------------------------------------------------------------------------
11384 Calendar.prototype.rerenderEvents = function () {
11385 this.view.flash('displayingEvents');
11386 };
11387 Calendar.prototype.refetchEvents = function () {
11388 this.eventManager.refetchAllSources();
11389 };
11390 Calendar.prototype.renderEvents = function (eventInputs, isSticky) {
11391 this.eventManager.freeze();
11392 for (var i = 0; i < eventInputs.length; i++) {
11393 this.renderEvent(eventInputs[i], isSticky);
11394 }
11395 this.eventManager.thaw();
11396 };
11397 Calendar.prototype.renderEvent = function (eventInput, isSticky) {
11398 if (isSticky === void 0) { isSticky = false; }
11399 var eventManager = this.eventManager;
11400 var eventDef = EventDefParser_1.default.parse(eventInput, eventInput.source || eventManager.stickySource);
11401 if (eventDef) {
11402 eventManager.addEventDef(eventDef, isSticky);
11403 }
11404 };
11405 // legacyQuery operates on legacy event instance objects
11406 Calendar.prototype.removeEvents = function (legacyQuery) {
11407 var eventManager = this.eventManager;
11408 var legacyInstances = [];
11409 var idMap = {};
11410 var eventDef;
11411 var i;
11412 if (legacyQuery == null) { // shortcut for removing all
11413 eventManager.removeAllEventDefs(); // persist=true
11414 }
11415 else {
11416 eventManager.getEventInstances().forEach(function (eventInstance) {
11417 legacyInstances.push(eventInstance.toLegacy());
11418 });
11419 legacyInstances = filterLegacyEventInstances(legacyInstances, legacyQuery);
11420 // compute unique IDs
11421 for (i = 0; i < legacyInstances.length; i++) {
11422 eventDef = this.eventManager.getEventDefByUid(legacyInstances[i]._id);
11423 idMap[eventDef.id] = true;
11424 }
11425 eventManager.freeze();
11426 for (i in idMap) { // reuse `i` as an "id"
11427 eventManager.removeEventDefsById(i); // persist=true
11428 }
11429 eventManager.thaw();
11430 }
11431 };
11432 // legacyQuery operates on legacy event instance objects
11433 Calendar.prototype.clientEvents = function (legacyQuery) {
11434 var legacyEventInstances = [];
11435 this.eventManager.getEventInstances().forEach(function (eventInstance) {
11436 legacyEventInstances.push(eventInstance.toLegacy());
11437 });
11438 return filterLegacyEventInstances(legacyEventInstances, legacyQuery);
11439 };
11440 Calendar.prototype.updateEvents = function (eventPropsArray) {
11441 this.eventManager.freeze();
11442 for (var i = 0; i < eventPropsArray.length; i++) {
11443 this.updateEvent(eventPropsArray[i]);
11444 }
11445 this.eventManager.thaw();
11446 };
11447 Calendar.prototype.updateEvent = function (eventProps) {
11448 var eventDef = this.eventManager.getEventDefByUid(eventProps._id);
11449 var eventInstance;
11450 var eventDefMutation;
11451 if (eventDef instanceof SingleEventDef_1.default) {
11452 eventInstance = eventDef.buildInstance();
11453 eventDefMutation = EventDefMutation_1.default.createFromRawProps(eventInstance, eventProps, // raw props
11454 null // largeUnit -- who uses it?
11455 );
11456 this.eventManager.mutateEventsWithId(eventDef.id, eventDefMutation); // will release
11457 }
11458 };
11459 // Public Event Sources API
11460 // ------------------------------------------------------------------------------------
11461 Calendar.prototype.getEventSources = function () {
11462 return this.eventManager.otherSources.slice(); // clone
11463 };
11464 Calendar.prototype.getEventSourceById = function (id) {
11465 return this.eventManager.getSourceById(EventSource_1.default.normalizeId(id));
11466 };
11467 Calendar.prototype.addEventSource = function (sourceInput) {
11468 var source = EventSourceParser_1.default.parse(sourceInput, this);
11469 if (source) {
11470 this.eventManager.addSource(source);
11471 }
11472 };
11473 Calendar.prototype.removeEventSources = function (sourceMultiQuery) {
11474 var eventManager = this.eventManager;
11475 var sources;
11476 var i;
11477 if (sourceMultiQuery == null) {
11478 this.eventManager.removeAllSources();
11479 }
11480 else {
11481 sources = eventManager.multiQuerySources(sourceMultiQuery);
11482 eventManager.freeze();
11483 for (i = 0; i < sources.length; i++) {
11484 eventManager.removeSource(sources[i]);
11485 }
11486 eventManager.thaw();
11487 }
11488 };
11489 Calendar.prototype.removeEventSource = function (sourceQuery) {
11490 var eventManager = this.eventManager;
11491 var sources = eventManager.querySources(sourceQuery);
11492 var i;
11493 eventManager.freeze();
11494 for (i = 0; i < sources.length; i++) {
11495 eventManager.removeSource(sources[i]);
11496 }
11497 eventManager.thaw();
11498 };
11499 Calendar.prototype.refetchEventSources = function (sourceMultiQuery) {
11500 var eventManager = this.eventManager;
11501 var sources = eventManager.multiQuerySources(sourceMultiQuery);
11502 var i;
11503 eventManager.freeze();
11504 for (i = 0; i < sources.length; i++) {
11505 eventManager.refetchSource(sources[i]);
11506 }
11507 eventManager.thaw();
11508 };
11509 // not for internal use. use options module directly instead.
11510 Calendar.defaults = options_1.globalDefaults;
11511 Calendar.englishDefaults = options_1.englishDefaults;
11512 Calendar.rtlDefaults = options_1.rtlDefaults;
11513 return Calendar;
11514 }());
11515 exports.default = Calendar;
11516 EmitterMixin_1.default.mixInto(Calendar);
11517 ListenerMixin_1.default.mixInto(Calendar);
11518 function filterLegacyEventInstances(legacyEventInstances, legacyQuery) {
11519 if (legacyQuery == null) {
11520 return legacyEventInstances;
11521 }
11522 else if ($.isFunction(legacyQuery)) {
11523 return legacyEventInstances.filter(legacyQuery);
11524 }
11525 else { // an event ID
11526 legacyQuery += ''; // normalize to string
11527 return legacyEventInstances.filter(function (legacyEventInstance) {
11528 // soft comparison because id not be normalized to string
11529 // tslint:disable-next-line
11530 return legacyEventInstance.id == legacyQuery ||
11531 legacyEventInstance._id === legacyQuery; // can specify internal id, but must exactly match
11532 });
11533 }
11534 }
11535
11536
11537 /***/ }),
11538 /* 233 */
11539 /***/ (function(module, exports, __webpack_require__) {
11540
11541 Object.defineProperty(exports, "__esModule", { value: true });
11542 var tslib_1 = __webpack_require__(2);
11543 var $ = __webpack_require__(3);
11544 var moment = __webpack_require__(0);
11545 var exportHooks = __webpack_require__(18);
11546 var util_1 = __webpack_require__(4);
11547 var moment_ext_1 = __webpack_require__(11);
11548 var ListenerMixin_1 = __webpack_require__(7);
11549 var HitDragListener_1 = __webpack_require__(17);
11550 var SingleEventDef_1 = __webpack_require__(9);
11551 var EventInstanceGroup_1 = __webpack_require__(20);
11552 var EventSource_1 = __webpack_require__(6);
11553 var Interaction_1 = __webpack_require__(14);
11554 var ExternalDropping = /** @class */ (function (_super) {
11555 tslib_1.__extends(ExternalDropping, _super);
11556 function ExternalDropping() {
11557 var _this = _super !== null && _super.apply(this, arguments) || this;
11558 _this.isDragging = false; // jqui-dragging an external element? boolean
11559 return _this;
11560 }
11561 /*
11562 component impements:
11563 - eventRangesToEventFootprints
11564 - isEventInstanceGroupAllowed
11565 - isExternalInstanceGroupAllowed
11566 - renderDrag
11567 - unrenderDrag
11568 */
11569 ExternalDropping.prototype.end = function () {
11570 if (this.dragListener) {
11571 this.dragListener.endInteraction();
11572 }
11573 };
11574 ExternalDropping.prototype.bindToDocument = function () {
11575 this.listenTo($(document), {
11576 dragstart: this.handleDragStart,
11577 sortstart: this.handleDragStart // jqui
11578 });
11579 };
11580 ExternalDropping.prototype.unbindFromDocument = function () {
11581 this.stopListeningTo($(document));
11582 };
11583 // Called when a jQuery UI drag is initiated anywhere in the DOM
11584 ExternalDropping.prototype.handleDragStart = function (ev, ui) {
11585 var el;
11586 var accept;
11587 if (this.opt('droppable')) { // only listen if this setting is on
11588 el = $((ui ? ui.item : null) || ev.target);
11589 // Test that the dragged element passes the dropAccept selector or filter function.
11590 // FYI, the default is "*" (matches all)
11591 accept = this.opt('dropAccept');
11592 if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {
11593 if (!this.isDragging) { // prevent double-listening if fired twice
11594 this.listenToExternalDrag(el, ev, ui);
11595 }
11596 }
11597 }
11598 };
11599 // Called when a jQuery UI drag starts and it needs to be monitored for dropping
11600 ExternalDropping.prototype.listenToExternalDrag = function (el, ev, ui) {
11601 var _this = this;
11602 var component = this.component;
11603 var view = this.view;
11604 var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create
11605 var singleEventDef; // a null value signals an unsuccessful drag
11606 // listener that tracks mouse movement over date-associated pixel regions
11607 var dragListener = this.dragListener = new HitDragListener_1.default(component, {
11608 interactionStart: function () {
11609 _this.isDragging = true;
11610 },
11611 hitOver: function (hit) {
11612 var isAllowed = true;
11613 var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid
11614 var mutatedEventInstanceGroup;
11615 if (hitFootprint) {
11616 singleEventDef = _this.computeExternalDrop(hitFootprint, meta);
11617 if (singleEventDef) {
11618 mutatedEventInstanceGroup = new EventInstanceGroup_1.default(singleEventDef.buildInstances());
11619 isAllowed = meta.eventProps ? // isEvent?
11620 component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) :
11621 component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup);
11622 }
11623 else {
11624 isAllowed = false;
11625 }
11626 }
11627 else {
11628 isAllowed = false;
11629 }
11630 if (!isAllowed) {
11631 singleEventDef = null;
11632 util_1.disableCursor();
11633 }
11634 if (singleEventDef) {
11635 component.renderDrag(// called without a seg parameter
11636 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar)));
11637 }
11638 },
11639 hitOut: function () {
11640 singleEventDef = null; // signal unsuccessful
11641 },
11642 hitDone: function () {
11643 util_1.enableCursor();
11644 component.unrenderDrag();
11645 },
11646 interactionEnd: function (ev) {
11647 if (singleEventDef) { // element was dropped on a valid hit
11648 view.reportExternalDrop(singleEventDef, Boolean(meta.eventProps), // isEvent
11649 Boolean(meta.stick), // isSticky
11650 el, ev, ui);
11651 }
11652 _this.isDragging = false;
11653 _this.dragListener = null;
11654 }
11655 });
11656 dragListener.startDrag(ev); // start listening immediately
11657 };
11658 // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),
11659 // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null.
11660 // Returning a null value signals an invalid drop hit.
11661 // DOES NOT consider overlap/constraint.
11662 // Assumes both footprints are non-open-ended.
11663 ExternalDropping.prototype.computeExternalDrop = function (componentFootprint, meta) {
11664 var calendar = this.view.calendar;
11665 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs).stripZone();
11666 var end;
11667 var eventDef;
11668 if (componentFootprint.isAllDay) {
11669 // if dropped on an all-day span, and element's metadata specified a time, set it
11670 if (meta.startTime) {
11671 start.time(meta.startTime);
11672 }
11673 else {
11674 start.stripTime();
11675 }
11676 }
11677 if (meta.duration) {
11678 end = start.clone().add(meta.duration);
11679 }
11680 start = calendar.applyTimezone(start);
11681 if (end) {
11682 end = calendar.applyTimezone(end);
11683 }
11684 eventDef = SingleEventDef_1.default.parse($.extend({}, meta.eventProps, {
11685 start: start,
11686 end: end
11687 }), new EventSource_1.default(calendar));
11688 return eventDef;
11689 };
11690 return ExternalDropping;
11691 }(Interaction_1.default));
11692 exports.default = ExternalDropping;
11693 ListenerMixin_1.default.mixInto(ExternalDropping);
11694 /* External-Dragging-Element Data
11695 ----------------------------------------------------------------------------------------------------------------------*/
11696 // Require all HTML5 data-* attributes used by FullCalendar to have this prefix.
11697 // A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.
11698 exportHooks.dataAttrPrefix = '';
11699 // Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure
11700 // to be used for Event Object creation.
11701 // A defined `.eventProps`, even when empty, indicates that an event should be created.
11702 function getDraggedElMeta(el) {
11703 var prefix = exportHooks.dataAttrPrefix;
11704 var eventProps; // properties for creating the event, not related to date/time
11705 var startTime; // a Duration
11706 var duration;
11707 var stick;
11708 if (prefix) {
11709 prefix += '-';
11710 }
11711 eventProps = el.data(prefix + 'event') || null;
11712 if (eventProps) {
11713 if (typeof eventProps === 'object') {
11714 eventProps = $.extend({}, eventProps); // make a copy
11715 }
11716 else { // something like 1 or true. still signal event creation
11717 eventProps = {};
11718 }
11719 // pluck special-cased date/time properties
11720 startTime = eventProps.start;
11721 if (startTime == null) {
11722 startTime = eventProps.time;
11723 } // accept 'time' as well
11724 duration = eventProps.duration;
11725 stick = eventProps.stick;
11726 delete eventProps.start;
11727 delete eventProps.time;
11728 delete eventProps.duration;
11729 delete eventProps.stick;
11730 }
11731 // fallback to standalone attribute values for each of the date/time properties
11732 if (startTime == null) {
11733 startTime = el.data(prefix + 'start');
11734 }
11735 if (startTime == null) {
11736 startTime = el.data(prefix + 'time');
11737 } // accept 'time' as well
11738 if (duration == null) {
11739 duration = el.data(prefix + 'duration');
11740 }
11741 if (stick == null) {
11742 stick = el.data(prefix + 'stick');
11743 }
11744 // massage into correct data types
11745 startTime = startTime != null ? moment.duration(startTime) : null;
11746 duration = duration != null ? moment.duration(duration) : null;
11747 stick = Boolean(stick);
11748 return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };
11749 }
11750
11751
11752 /***/ }),
11753 /* 234 */
11754 /***/ (function(module, exports, __webpack_require__) {
11755
11756 Object.defineProperty(exports, "__esModule", { value: true });
11757 var tslib_1 = __webpack_require__(2);
11758 var $ = __webpack_require__(3);
11759 var util_1 = __webpack_require__(4);
11760 var EventDefMutation_1 = __webpack_require__(39);
11761 var EventDefDateMutation_1 = __webpack_require__(40);
11762 var HitDragListener_1 = __webpack_require__(17);
11763 var Interaction_1 = __webpack_require__(14);
11764 var EventResizing = /** @class */ (function (_super) {
11765 tslib_1.__extends(EventResizing, _super);
11766 /*
11767 component impements:
11768 - bindSegHandlerToEl
11769 - publiclyTrigger
11770 - diffDates
11771 - eventRangesToEventFootprints
11772 - isEventInstanceGroupAllowed
11773 - getSafeHitFootprint
11774 */
11775 function EventResizing(component, eventPointing) {
11776 var _this = _super.call(this, component) || this;
11777 _this.isResizing = false;
11778 _this.eventPointing = eventPointing;
11779 return _this;
11780 }
11781 EventResizing.prototype.end = function () {
11782 if (this.dragListener) {
11783 this.dragListener.endInteraction();
11784 }
11785 };
11786 EventResizing.prototype.bindToEl = function (el) {
11787 var component = this.component;
11788 component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this));
11789 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
11790 };
11791 EventResizing.prototype.handleMouseDown = function (seg, ev) {
11792 if (this.component.canStartResize(seg, ev)) {
11793 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
11794 .startInteraction(ev, { distance: 5 });
11795 }
11796 };
11797 EventResizing.prototype.handleTouchStart = function (seg, ev) {
11798 if (this.component.canStartResize(seg, ev)) {
11799 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
11800 .startInteraction(ev);
11801 }
11802 };
11803 // Creates a listener that tracks the user as they resize an event segment.
11804 // Generic enough to work with any type of Grid.
11805 EventResizing.prototype.buildDragListener = function (seg, isStart) {
11806 var _this = this;
11807 var component = this.component;
11808 var view = this.view;
11809 var calendar = view.calendar;
11810 var eventManager = calendar.eventManager;
11811 var el = seg.el;
11812 var eventDef = seg.footprint.eventDef;
11813 var eventInstance = seg.footprint.eventInstance;
11814 var isDragging;
11815 var resizeMutation; // zoned event date properties. falsy if invalid resize
11816 // Tracks mouse movement over the *grid's* coordinate map
11817 var dragListener = this.dragListener = new HitDragListener_1.default(component, {
11818 scroll: this.opt('dragScroll'),
11819 subjectEl: el,
11820 interactionStart: function () {
11821 isDragging = false;
11822 },
11823 dragStart: function (ev) {
11824 isDragging = true;
11825 // ensure a mouseout on the manipulated event has been reported
11826 _this.eventPointing.handleMouseout(seg, ev);
11827 _this.segResizeStart(seg, ev);
11828 },
11829 hitOver: function (hit, isOrig, origHit) {
11830 var isAllowed = true;
11831 var origHitFootprint = component.getSafeHitFootprint(origHit);
11832 var hitFootprint = component.getSafeHitFootprint(hit);
11833 var mutatedEventInstanceGroup;
11834 if (origHitFootprint && hitFootprint) {
11835 resizeMutation = isStart ?
11836 _this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) :
11837 _this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint);
11838 if (resizeMutation) {
11839 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, resizeMutation);
11840 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
11841 }
11842 else {
11843 isAllowed = false;
11844 }
11845 }
11846 else {
11847 isAllowed = false;
11848 }
11849 if (!isAllowed) {
11850 resizeMutation = null;
11851 util_1.disableCursor();
11852 }
11853 else if (resizeMutation.isEmpty()) {
11854 // no change. (FYI, event dates might have zones)
11855 resizeMutation = null;
11856 }
11857 if (resizeMutation) {
11858 view.hideEventsWithId(seg.footprint.eventDef.id);
11859 view.renderEventResize(component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg);
11860 }
11861 },
11862 hitOut: function () {
11863 resizeMutation = null;
11864 },
11865 hitDone: function () {
11866 view.unrenderEventResize(seg);
11867 view.showEventsWithId(seg.footprint.eventDef.id);
11868 util_1.enableCursor();
11869 },
11870 interactionEnd: function (ev) {
11871 if (isDragging) {
11872 _this.segResizeStop(seg, ev);
11873 }
11874 if (resizeMutation) { // valid date to resize to?
11875 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
11876 view.reportEventResize(eventInstance, resizeMutation, el, ev);
11877 }
11878 _this.dragListener = null;
11879 }
11880 });
11881 return dragListener;
11882 };
11883 // Called before event segment resizing starts
11884 EventResizing.prototype.segResizeStart = function (seg, ev) {
11885 this.isResizing = true;
11886 this.component.publiclyTrigger('eventResizeStart', {
11887 context: seg.el[0],
11888 args: [
11889 seg.footprint.getEventLegacy(),
11890 ev,
11891 {},
11892 this.view
11893 ]
11894 });
11895 };
11896 // Called after event segment resizing stops
11897 EventResizing.prototype.segResizeStop = function (seg, ev) {
11898 this.isResizing = false;
11899 this.component.publiclyTrigger('eventResizeStop', {
11900 context: seg.el[0],
11901 args: [
11902 seg.footprint.getEventLegacy(),
11903 ev,
11904 {},
11905 this.view
11906 ]
11907 });
11908 };
11909 // Returns new date-information for an event segment being resized from its start
11910 EventResizing.prototype.computeEventStartResizeMutation = function (startFootprint, endFootprint, origEventFootprint) {
11911 var origRange = origEventFootprint.componentFootprint.unzonedRange;
11912 var startDelta = this.component.diffDates(endFootprint.unzonedRange.getStart(), startFootprint.unzonedRange.getStart());
11913 var dateMutation;
11914 var eventDefMutation;
11915 if (origRange.getStart().add(startDelta) < origRange.getEnd()) {
11916 dateMutation = new EventDefDateMutation_1.default();
11917 dateMutation.setStartDelta(startDelta);
11918 eventDefMutation = new EventDefMutation_1.default();
11919 eventDefMutation.setDateMutation(dateMutation);
11920 return eventDefMutation;
11921 }
11922 return false;
11923 };
11924 // Returns new date-information for an event segment being resized from its end
11925 EventResizing.prototype.computeEventEndResizeMutation = function (startFootprint, endFootprint, origEventFootprint) {
11926 var origRange = origEventFootprint.componentFootprint.unzonedRange;
11927 var endDelta = this.component.diffDates(endFootprint.unzonedRange.getEnd(), startFootprint.unzonedRange.getEnd());
11928 var dateMutation;
11929 var eventDefMutation;
11930 if (origRange.getEnd().add(endDelta) > origRange.getStart()) {
11931 dateMutation = new EventDefDateMutation_1.default();
11932 dateMutation.setEndDelta(endDelta);
11933 eventDefMutation = new EventDefMutation_1.default();
11934 eventDefMutation.setDateMutation(dateMutation);
11935 return eventDefMutation;
11936 }
11937 return false;
11938 };
11939 return EventResizing;
11940 }(Interaction_1.default));
11941 exports.default = EventResizing;
11942
11943
11944 /***/ }),
11945 /* 235 */
11946 /***/ (function(module, exports, __webpack_require__) {
11947
11948 Object.defineProperty(exports, "__esModule", { value: true });
11949 var tslib_1 = __webpack_require__(2);
11950 var util_1 = __webpack_require__(4);
11951 var EventDefMutation_1 = __webpack_require__(39);
11952 var EventDefDateMutation_1 = __webpack_require__(40);
11953 var DragListener_1 = __webpack_require__(59);
11954 var HitDragListener_1 = __webpack_require__(17);
11955 var MouseFollower_1 = __webpack_require__(226);
11956 var Interaction_1 = __webpack_require__(14);
11957 var EventDragging = /** @class */ (function (_super) {
11958 tslib_1.__extends(EventDragging, _super);
11959 /*
11960 component implements:
11961 - bindSegHandlerToEl
11962 - publiclyTrigger
11963 - diffDates
11964 - eventRangesToEventFootprints
11965 - isEventInstanceGroupAllowed
11966 */
11967 function EventDragging(component, eventPointing) {
11968 var _this = _super.call(this, component) || this;
11969 _this.isDragging = false;
11970 _this.eventPointing = eventPointing;
11971 return _this;
11972 }
11973 EventDragging.prototype.end = function () {
11974 if (this.dragListener) {
11975 this.dragListener.endInteraction();
11976 }
11977 };
11978 EventDragging.prototype.getSelectionDelay = function () {
11979 var delay = this.opt('eventLongPressDelay');
11980 if (delay == null) {
11981 delay = this.opt('longPressDelay'); // fallback
11982 }
11983 return delay;
11984 };
11985 EventDragging.prototype.bindToEl = function (el) {
11986 var component = this.component;
11987 component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this));
11988 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
11989 };
11990 EventDragging.prototype.handleMousedown = function (seg, ev) {
11991 if (!this.component.shouldIgnoreMouse() &&
11992 this.component.canStartDrag(seg, ev)) {
11993 this.buildDragListener(seg).startInteraction(ev, { distance: 5 });
11994 }
11995 };
11996 EventDragging.prototype.handleTouchStart = function (seg, ev) {
11997 var component = this.component;
11998 var settings = {
11999 delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected?
12000 0 : this.getSelectionDelay()
12001 };
12002 if (component.canStartDrag(seg, ev)) {
12003 this.buildDragListener(seg).startInteraction(ev, settings);
12004 }
12005 else if (component.canStartSelection(seg, ev)) {
12006 this.buildSelectListener(seg).startInteraction(ev, settings);
12007 }
12008 };
12009 // seg isn't draggable, but let's use a generic DragListener
12010 // simply for the delay, so it can be selected.
12011 // Has side effect of setting/unsetting `dragListener`
12012 EventDragging.prototype.buildSelectListener = function (seg) {
12013 var _this = this;
12014 var view = this.view;
12015 var eventDef = seg.footprint.eventDef;
12016 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
12017 if (this.dragListener) {
12018 return this.dragListener;
12019 }
12020 var dragListener = this.dragListener = new DragListener_1.default({
12021 dragStart: function (ev) {
12022 if (dragListener.isTouch &&
12023 !view.isEventDefSelected(eventDef) &&
12024 eventInstance) {
12025 // if not previously selected, will fire after a delay. then, select the event
12026 view.selectEventInstance(eventInstance);
12027 }
12028 },
12029 interactionEnd: function (ev) {
12030 _this.dragListener = null;
12031 }
12032 });
12033 return dragListener;
12034 };
12035 // Builds a listener that will track user-dragging on an event segment.
12036 // Generic enough to work with any type of Grid.
12037 // Has side effect of setting/unsetting `dragListener`
12038 EventDragging.prototype.buildDragListener = function (seg) {
12039 var _this = this;
12040 var component = this.component;
12041 var view = this.view;
12042 var calendar = view.calendar;
12043 var eventManager = calendar.eventManager;
12044 var el = seg.el;
12045 var eventDef = seg.footprint.eventDef;
12046 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
12047 var isDragging;
12048 var mouseFollower; // A clone of the original element that will move with the mouse
12049 var eventDefMutation;
12050 if (this.dragListener) {
12051 return this.dragListener;
12052 }
12053 // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
12054 // of the view.
12055 var dragListener = this.dragListener = new HitDragListener_1.default(view, {
12056 scroll: this.opt('dragScroll'),
12057 subjectEl: el,
12058 subjectCenter: true,
12059 interactionStart: function (ev) {
12060 seg.component = component; // for renderDrag
12061 isDragging = false;
12062 mouseFollower = new MouseFollower_1.default(seg.el, {
12063 additionalClass: 'fc-dragging',
12064 parentEl: view.el,
12065 opacity: dragListener.isTouch ? null : _this.opt('dragOpacity'),
12066 revertDuration: _this.opt('dragRevertDuration'),
12067 zIndex: 2 // one above the .fc-view
12068 });
12069 mouseFollower.hide(); // don't show until we know this is a real drag
12070 mouseFollower.start(ev);
12071 },
12072 dragStart: function (ev) {
12073 if (dragListener.isTouch &&
12074 !view.isEventDefSelected(eventDef) &&
12075 eventInstance) {
12076 // if not previously selected, will fire after a delay. then, select the event
12077 view.selectEventInstance(eventInstance);
12078 }
12079 isDragging = true;
12080 // ensure a mouseout on the manipulated event has been reported
12081 _this.eventPointing.handleMouseout(seg, ev);
12082 _this.segDragStart(seg, ev);
12083 view.hideEventsWithId(seg.footprint.eventDef.id);
12084 },
12085 hitOver: function (hit, isOrig, origHit) {
12086 var isAllowed = true;
12087 var origFootprint;
12088 var footprint;
12089 var mutatedEventInstanceGroup;
12090 // starting hit could be forced (DayGrid.limit)
12091 if (seg.hit) {
12092 origHit = seg.hit;
12093 }
12094 // hit might not belong to this grid, so query origin grid
12095 origFootprint = origHit.component.getSafeHitFootprint(origHit);
12096 footprint = hit.component.getSafeHitFootprint(hit);
12097 if (origFootprint && footprint) {
12098 eventDefMutation = _this.computeEventDropMutation(origFootprint, footprint, eventDef);
12099 if (eventDefMutation) {
12100 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, eventDefMutation);
12101 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
12102 }
12103 else {
12104 isAllowed = false;
12105 }
12106 }
12107 else {
12108 isAllowed = false;
12109 }
12110 if (!isAllowed) {
12111 eventDefMutation = null;
12112 util_1.disableCursor();
12113 }
12114 // if a valid drop location, have the subclass render a visual indication
12115 if (eventDefMutation &&
12116 view.renderDrag(// truthy if rendered something
12117 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg, dragListener.isTouch)) {
12118 mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own
12119 }
12120 else {
12121 mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)
12122 }
12123 if (isOrig) {
12124 // needs to have moved hits to be a valid drop
12125 eventDefMutation = null;
12126 }
12127 },
12128 hitOut: function () {
12129 view.unrenderDrag(seg); // unrender whatever was done in renderDrag
12130 mouseFollower.show(); // show in case we are moving out of all hits
12131 eventDefMutation = null;
12132 },
12133 hitDone: function () {
12134 util_1.enableCursor();
12135 },
12136 interactionEnd: function (ev) {
12137 delete seg.component; // prevent side effects
12138 // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
12139 mouseFollower.stop(!eventDefMutation, function () {
12140 if (isDragging) {
12141 view.unrenderDrag(seg);
12142 _this.segDragStop(seg, ev);
12143 }
12144 view.showEventsWithId(seg.footprint.eventDef.id);
12145 if (eventDefMutation) {
12146 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
12147 view.reportEventDrop(eventInstance, eventDefMutation, el, ev);
12148 }
12149 });
12150 _this.dragListener = null;
12151 }
12152 });
12153 return dragListener;
12154 };
12155 // Called before event segment dragging starts
12156 EventDragging.prototype.segDragStart = function (seg, ev) {
12157 this.isDragging = true;
12158 this.component.publiclyTrigger('eventDragStart', {
12159 context: seg.el[0],
12160 args: [
12161 seg.footprint.getEventLegacy(),
12162 ev,
12163 {},
12164 this.view
12165 ]
12166 });
12167 };
12168 // Called after event segment dragging stops
12169 EventDragging.prototype.segDragStop = function (seg, ev) {
12170 this.isDragging = false;
12171 this.component.publiclyTrigger('eventDragStop', {
12172 context: seg.el[0],
12173 args: [
12174 seg.footprint.getEventLegacy(),
12175 ev,
12176 {},
12177 this.view
12178 ]
12179 });
12180 };
12181 // DOES NOT consider overlap/constraint
12182 EventDragging.prototype.computeEventDropMutation = function (startFootprint, endFootprint, eventDef) {
12183 var eventDefMutation = new EventDefMutation_1.default();
12184 eventDefMutation.setDateMutation(this.computeEventDateMutation(startFootprint, endFootprint));
12185 return eventDefMutation;
12186 };
12187 EventDragging.prototype.computeEventDateMutation = function (startFootprint, endFootprint) {
12188 var date0 = startFootprint.unzonedRange.getStart();
12189 var date1 = endFootprint.unzonedRange.getStart();
12190 var clearEnd = false;
12191 var forceTimed = false;
12192 var forceAllDay = false;
12193 var dateDelta;
12194 var dateMutation;
12195 if (startFootprint.isAllDay !== endFootprint.isAllDay) {
12196 clearEnd = true;
12197 if (endFootprint.isAllDay) {
12198 forceAllDay = true;
12199 date0.stripTime();
12200 }
12201 else {
12202 forceTimed = true;
12203 }
12204 }
12205 dateDelta = this.component.diffDates(date1, date0);
12206 dateMutation = new EventDefDateMutation_1.default();
12207 dateMutation.clearEnd = clearEnd;
12208 dateMutation.forceTimed = forceTimed;
12209 dateMutation.forceAllDay = forceAllDay;
12210 dateMutation.setDateDelta(dateDelta);
12211 return dateMutation;
12212 };
12213 return EventDragging;
12214 }(Interaction_1.default));
12215 exports.default = EventDragging;
12216
12217
12218 /***/ }),
12219 /* 236 */
12220 /***/ (function(module, exports, __webpack_require__) {
12221
12222 Object.defineProperty(exports, "__esModule", { value: true });
12223 var tslib_1 = __webpack_require__(2);
12224 var util_1 = __webpack_require__(4);
12225 var HitDragListener_1 = __webpack_require__(17);
12226 var ComponentFootprint_1 = __webpack_require__(12);
12227 var UnzonedRange_1 = __webpack_require__(5);
12228 var Interaction_1 = __webpack_require__(14);
12229 var DateSelecting = /** @class */ (function (_super) {
12230 tslib_1.__extends(DateSelecting, _super);
12231 /*
12232 component must implement:
12233 - bindDateHandlerToEl
12234 - getSafeHitFootprint
12235 - renderHighlight
12236 - unrenderHighlight
12237 */
12238 function DateSelecting(component) {
12239 var _this = _super.call(this, component) || this;
12240 _this.dragListener = _this.buildDragListener();
12241 return _this;
12242 }
12243 DateSelecting.prototype.end = function () {
12244 this.dragListener.endInteraction();
12245 };
12246 DateSelecting.prototype.getDelay = function () {
12247 var delay = this.opt('selectLongPressDelay');
12248 if (delay == null) {
12249 delay = this.opt('longPressDelay'); // fallback
12250 }
12251 return delay;
12252 };
12253 DateSelecting.prototype.bindToEl = function (el) {
12254 var _this = this;
12255 var component = this.component;
12256 var dragListener = this.dragListener;
12257 component.bindDateHandlerToEl(el, 'mousedown', function (ev) {
12258 if (_this.opt('selectable') && !component.shouldIgnoreMouse()) {
12259 dragListener.startInteraction(ev, {
12260 distance: _this.opt('selectMinDistance')
12261 });
12262 }
12263 });
12264 component.bindDateHandlerToEl(el, 'touchstart', function (ev) {
12265 if (_this.opt('selectable') && !component.shouldIgnoreTouch()) {
12266 dragListener.startInteraction(ev, {
12267 delay: _this.getDelay()
12268 });
12269 }
12270 });
12271 util_1.preventSelection(el);
12272 };
12273 // Creates a listener that tracks the user's drag across day elements, for day selecting.
12274 DateSelecting.prototype.buildDragListener = function () {
12275 var _this = this;
12276 var component = this.component;
12277 var selectionFootprint; // null if invalid selection
12278 var dragListener = new HitDragListener_1.default(component, {
12279 scroll: this.opt('dragScroll'),
12280 interactionStart: function () {
12281 selectionFootprint = null;
12282 },
12283 dragStart: function (ev) {
12284 _this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one
12285 },
12286 hitOver: function (hit, isOrig, origHit) {
12287 var origHitFootprint;
12288 var hitFootprint;
12289 if (origHit) { // click needs to have started on a hit
12290 origHitFootprint = component.getSafeHitFootprint(origHit);
12291 hitFootprint = component.getSafeHitFootprint(hit);
12292 if (origHitFootprint && hitFootprint) {
12293 selectionFootprint = _this.computeSelection(origHitFootprint, hitFootprint);
12294 }
12295 else {
12296 selectionFootprint = null;
12297 }
12298 if (selectionFootprint) {
12299 component.renderSelectionFootprint(selectionFootprint);
12300 }
12301 else if (selectionFootprint === false) {
12302 util_1.disableCursor();
12303 }
12304 }
12305 },
12306 hitOut: function () {
12307 selectionFootprint = null;
12308 component.unrenderSelection();
12309 },
12310 hitDone: function () {
12311 util_1.enableCursor();
12312 },
12313 interactionEnd: function (ev, isCancelled) {
12314 if (!isCancelled && selectionFootprint) {
12315 // the selection will already have been rendered. just report it
12316 _this.view.reportSelection(selectionFootprint, ev);
12317 }
12318 }
12319 });
12320 return dragListener;
12321 };
12322 // Given the first and last date-spans of a selection, returns another date-span object.
12323 // Subclasses can override and provide additional data in the span object. Will be passed to renderSelectionFootprint().
12324 // Will return false if the selection is invalid and this should be indicated to the user.
12325 // Will return null/undefined if a selection invalid but no error should be reported.
12326 DateSelecting.prototype.computeSelection = function (footprint0, footprint1) {
12327 var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1);
12328 if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) {
12329 return false;
12330 }
12331 return wholeFootprint;
12332 };
12333 // Given two spans, must return the combination of the two.
12334 // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.
12335 // Assumes both footprints are non-open-ended.
12336 DateSelecting.prototype.computeSelectionFootprint = function (footprint0, footprint1) {
12337 var ms = [
12338 footprint0.unzonedRange.startMs,
12339 footprint0.unzonedRange.endMs,
12340 footprint1.unzonedRange.startMs,
12341 footprint1.unzonedRange.endMs
12342 ];
12343 ms.sort(util_1.compareNumbers);
12344 return new ComponentFootprint_1.default(new UnzonedRange_1.default(ms[0], ms[3]), footprint0.isAllDay);
12345 };
12346 DateSelecting.prototype.isSelectionFootprintAllowed = function (componentFootprint) {
12347 return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) &&
12348 this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint);
12349 };
12350 return DateSelecting;
12351 }(Interaction_1.default));
12352 exports.default = DateSelecting;
12353
12354
12355 /***/ }),
12356 /* 237 */
12357 /***/ (function(module, exports, __webpack_require__) {
12358
12359 Object.defineProperty(exports, "__esModule", { value: true });
12360 var tslib_1 = __webpack_require__(2);
12361 var HitDragListener_1 = __webpack_require__(17);
12362 var Interaction_1 = __webpack_require__(14);
12363 var DateClicking = /** @class */ (function (_super) {
12364 tslib_1.__extends(DateClicking, _super);
12365 /*
12366 component must implement:
12367 - bindDateHandlerToEl
12368 - getSafeHitFootprint
12369 - getHitEl
12370 */
12371 function DateClicking(component) {
12372 var _this = _super.call(this, component) || this;
12373 _this.dragListener = _this.buildDragListener();
12374 return _this;
12375 }
12376 DateClicking.prototype.end = function () {
12377 this.dragListener.endInteraction();
12378 };
12379 DateClicking.prototype.bindToEl = function (el) {
12380 var component = this.component;
12381 var dragListener = this.dragListener;
12382 component.bindDateHandlerToEl(el, 'mousedown', function (ev) {
12383 if (!component.shouldIgnoreMouse()) {
12384 dragListener.startInteraction(ev);
12385 }
12386 });
12387 component.bindDateHandlerToEl(el, 'touchstart', function (ev) {
12388 if (!component.shouldIgnoreTouch()) {
12389 dragListener.startInteraction(ev);
12390 }
12391 });
12392 };
12393 // Creates a listener that tracks the user's drag across day elements, for day clicking.
12394 DateClicking.prototype.buildDragListener = function () {
12395 var _this = this;
12396 var component = this.component;
12397 var dayClickHit; // null if invalid dayClick
12398 var dragListener = new HitDragListener_1.default(component, {
12399 scroll: this.opt('dragScroll'),
12400 interactionStart: function () {
12401 dayClickHit = dragListener.origHit;
12402 },
12403 hitOver: function (hit, isOrig, origHit) {
12404 // if user dragged to another cell at any point, it can no longer be a dayClick
12405 if (!isOrig) {
12406 dayClickHit = null;
12407 }
12408 },
12409 hitOut: function () {
12410 dayClickHit = null;
12411 },
12412 interactionEnd: function (ev, isCancelled) {
12413 var componentFootprint;
12414 if (!isCancelled && dayClickHit) {
12415 componentFootprint = component.getSafeHitFootprint(dayClickHit);
12416 if (componentFootprint) {
12417 _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev);
12418 }
12419 }
12420 }
12421 });
12422 // because dragListener won't be called with any time delay, "dragging" will begin immediately,
12423 // which will kill any touchmoving/scrolling. Prevent this.
12424 dragListener.shouldCancelTouchScroll = false;
12425 dragListener.scrollAlwaysKills = true;
12426 return dragListener;
12427 };
12428 return DateClicking;
12429 }(Interaction_1.default));
12430 exports.default = DateClicking;
12431
12432
12433 /***/ }),
12434 /* 238 */
12435 /***/ (function(module, exports, __webpack_require__) {
12436
12437 Object.defineProperty(exports, "__esModule", { value: true });
12438 var tslib_1 = __webpack_require__(2);
12439 var moment = __webpack_require__(0);
12440 var $ = __webpack_require__(3);
12441 var util_1 = __webpack_require__(4);
12442 var Scroller_1 = __webpack_require__(41);
12443 var View_1 = __webpack_require__(43);
12444 var TimeGrid_1 = __webpack_require__(239);
12445 var DayGrid_1 = __webpack_require__(66);
12446 var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
12447 var agendaTimeGridMethods;
12448 var agendaDayGridMethods;
12449 /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
12450 ----------------------------------------------------------------------------------------------------------------------*/
12451 // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
12452 // Responsible for managing width/height.
12453 var AgendaView = /** @class */ (function (_super) {
12454 tslib_1.__extends(AgendaView, _super);
12455 function AgendaView(calendar, viewSpec) {
12456 var _this = _super.call(this, calendar, viewSpec) || this;
12457 _this.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
12458 _this.timeGrid = _this.instantiateTimeGrid();
12459 _this.addChild(_this.timeGrid);
12460 if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
12461 _this.dayGrid = _this.instantiateDayGrid(); // the all-day subcomponent of this view
12462 _this.addChild(_this.dayGrid);
12463 }
12464 _this.scroller = new Scroller_1.default({
12465 overflowX: 'hidden',
12466 overflowY: 'auto'
12467 });
12468 return _this;
12469 }
12470 // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
12471 AgendaView.prototype.instantiateTimeGrid = function () {
12472 var timeGrid = new this.timeGridClass(this);
12473 util_1.copyOwnProps(agendaTimeGridMethods, timeGrid);
12474 return timeGrid;
12475 };
12476 // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
12477 AgendaView.prototype.instantiateDayGrid = function () {
12478 var dayGrid = new this.dayGridClass(this);
12479 util_1.copyOwnProps(agendaDayGridMethods, dayGrid);
12480 return dayGrid;
12481 };
12482 /* Rendering
12483 ------------------------------------------------------------------------------------------------------------------*/
12484 AgendaView.prototype.renderSkeleton = function () {
12485 var timeGridWrapEl;
12486 var timeGridEl;
12487 this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml());
12488 this.scroller.render();
12489 timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container');
12490 timeGridEl = $('<div class="fc-time-grid">').appendTo(timeGridWrapEl);
12491 this.el.find('.fc-body > tr > td').append(timeGridWrapEl);
12492 this.timeGrid.headContainerEl = this.el.find('.fc-head-container');
12493 this.timeGrid.setElement(timeGridEl);
12494 if (this.dayGrid) {
12495 this.dayGrid.setElement(this.el.find('.fc-day-grid'));
12496 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
12497 this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();
12498 }
12499 };
12500 AgendaView.prototype.unrenderSkeleton = function () {
12501 this.timeGrid.removeElement();
12502 if (this.dayGrid) {
12503 this.dayGrid.removeElement();
12504 }
12505 this.scroller.destroy();
12506 };
12507 // Builds the HTML skeleton for the view.
12508 // The day-grid and time-grid components will render inside containers defined by this HTML.
12509 AgendaView.prototype.renderSkeletonHtml = function () {
12510 var theme = this.calendar.theme;
12511 return '' +
12512 '<table class="' + theme.getClass('tableGrid') + '">' +
12513 (this.opt('columnHeader') ?
12514 '<thead class="fc-head">' +
12515 '<tr>' +
12516 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
12517 '</tr>' +
12518 '</thead>' :
12519 '') +
12520 '<tbody class="fc-body">' +
12521 '<tr>' +
12522 '<td class="' + theme.getClass('widgetContent') + '">' +
12523 (this.dayGrid ?
12524 '<div class="fc-day-grid"></div>' +
12525 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '"></hr>' :
12526 '') +
12527 '</td>' +
12528 '</tr>' +
12529 '</tbody>' +
12530 '</table>';
12531 };
12532 // Generates an HTML attribute string for setting the width of the axis, if it is known
12533 AgendaView.prototype.axisStyleAttr = function () {
12534 if (this.axisWidth != null) {
12535 return 'style="width:' + this.axisWidth + 'px"';
12536 }
12537 return '';
12538 };
12539 /* Now Indicator
12540 ------------------------------------------------------------------------------------------------------------------*/
12541 AgendaView.prototype.getNowIndicatorUnit = function () {
12542 return this.timeGrid.getNowIndicatorUnit();
12543 };
12544 /* Dimensions
12545 ------------------------------------------------------------------------------------------------------------------*/
12546 // Adjusts the vertical dimensions of the view to the specified values
12547 AgendaView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
12548 var eventLimit;
12549 var scrollerHeight;
12550 var scrollbarWidths;
12551 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
12552 // make all axis cells line up, and record the width so newly created axis cells will have it
12553 this.axisWidth = util_1.matchCellWidths(this.el.find('.fc-axis'));
12554 // hack to give the view some height prior to timeGrid's columns being rendered
12555 // TODO: separate setting height from scroller VS timeGrid.
12556 if (!this.timeGrid.colEls) {
12557 if (!isAuto) {
12558 scrollerHeight = this.computeScrollerHeight(totalHeight);
12559 this.scroller.setHeight(scrollerHeight);
12560 }
12561 return;
12562 }
12563 // set of fake row elements that must compensate when scroller has scrollbars
12564 var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)');
12565 // reset all dimensions back to the original state
12566 this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary
12567 this.scroller.clear(); // sets height to 'auto' and clears overflow
12568 util_1.uncompensateScroll(noScrollRowEls);
12569 // limit number of events in the all-day area
12570 if (this.dayGrid) {
12571 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
12572 eventLimit = this.opt('eventLimit');
12573 if (eventLimit && typeof eventLimit !== 'number') {
12574 eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
12575 }
12576 if (eventLimit) {
12577 this.dayGrid.limitRows(eventLimit);
12578 }
12579 }
12580 if (!isAuto) { // should we force dimensions of the scroll container?
12581 scrollerHeight = this.computeScrollerHeight(totalHeight);
12582 this.scroller.setHeight(scrollerHeight);
12583 scrollbarWidths = this.scroller.getScrollbarWidths();
12584 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
12585 // make the all-day and header rows lines up
12586 util_1.compensateScroll(noScrollRowEls, scrollbarWidths);
12587 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
12588 // and reapply the desired height to the scroller.
12589 scrollerHeight = this.computeScrollerHeight(totalHeight);
12590 this.scroller.setHeight(scrollerHeight);
12591 }
12592 // guarantees the same scrollbar widths
12593 this.scroller.lockOverflow(scrollbarWidths);
12594 // if there's any space below the slats, show the horizontal rule.
12595 // this won't cause any new overflow, because lockOverflow already called.
12596 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
12597 this.timeGrid.bottomRuleEl.show();
12598 }
12599 }
12600 };
12601 // given a desired total height of the view, returns what the height of the scroller should be
12602 AgendaView.prototype.computeScrollerHeight = function (totalHeight) {
12603 return totalHeight -
12604 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
12605 };
12606 /* Scroll
12607 ------------------------------------------------------------------------------------------------------------------*/
12608 // Computes the initial pre-configured scroll state prior to allowing the user to change it
12609 AgendaView.prototype.computeInitialDateScroll = function () {
12610 var scrollTime = moment.duration(this.opt('scrollTime'));
12611 var top = this.timeGrid.computeTimeTop(scrollTime);
12612 // zoom can give weird floating-point values. rather scroll a little bit further
12613 top = Math.ceil(top);
12614 if (top) {
12615 top++; // to overcome top border that slots beyond the first have. looks better
12616 }
12617 return { top: top };
12618 };
12619 AgendaView.prototype.queryDateScroll = function () {
12620 return { top: this.scroller.getScrollTop() };
12621 };
12622 AgendaView.prototype.applyDateScroll = function (scroll) {
12623 if (scroll.top !== undefined) {
12624 this.scroller.setScrollTop(scroll.top);
12625 }
12626 };
12627 /* Hit Areas
12628 ------------------------------------------------------------------------------------------------------------------*/
12629 // forward all hit-related method calls to the grids (dayGrid might not be defined)
12630 AgendaView.prototype.getHitFootprint = function (hit) {
12631 // TODO: hit.component is set as a hack to identify where the hit came from
12632 return hit.component.getHitFootprint(hit);
12633 };
12634 AgendaView.prototype.getHitEl = function (hit) {
12635 // TODO: hit.component is set as a hack to identify where the hit came from
12636 return hit.component.getHitEl(hit);
12637 };
12638 /* Event Rendering
12639 ------------------------------------------------------------------------------------------------------------------*/
12640 AgendaView.prototype.executeEventRender = function (eventsPayload) {
12641 var dayEventsPayload = {};
12642 var timedEventsPayload = {};
12643 var id;
12644 var eventInstanceGroup;
12645 // separate the events into all-day and timed
12646 for (id in eventsPayload) {
12647 eventInstanceGroup = eventsPayload[id];
12648 if (eventInstanceGroup.getEventDef().isAllDay()) {
12649 dayEventsPayload[id] = eventInstanceGroup;
12650 }
12651 else {
12652 timedEventsPayload[id] = eventInstanceGroup;
12653 }
12654 }
12655 this.timeGrid.executeEventRender(timedEventsPayload);
12656 if (this.dayGrid) {
12657 this.dayGrid.executeEventRender(dayEventsPayload);
12658 }
12659 };
12660 /* Dragging/Resizing Routing
12661 ------------------------------------------------------------------------------------------------------------------*/
12662 // A returned value of `true` signals that a mock "helper" event has been rendered.
12663 AgendaView.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
12664 var groups = groupEventFootprintsByAllDay(eventFootprints);
12665 var renderedHelper = false;
12666 renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch);
12667 if (this.dayGrid) {
12668 renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper;
12669 }
12670 return renderedHelper;
12671 };
12672 AgendaView.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
12673 var groups = groupEventFootprintsByAllDay(eventFootprints);
12674 this.timeGrid.renderEventResize(groups.timed, seg, isTouch);
12675 if (this.dayGrid) {
12676 this.dayGrid.renderEventResize(groups.allDay, seg, isTouch);
12677 }
12678 };
12679 /* Selection
12680 ------------------------------------------------------------------------------------------------------------------*/
12681 // Renders a visual indication of a selection
12682 AgendaView.prototype.renderSelectionFootprint = function (componentFootprint) {
12683 if (!componentFootprint.isAllDay) {
12684 this.timeGrid.renderSelectionFootprint(componentFootprint);
12685 }
12686 else if (this.dayGrid) {
12687 this.dayGrid.renderSelectionFootprint(componentFootprint);
12688 }
12689 };
12690 return AgendaView;
12691 }(View_1.default));
12692 exports.default = AgendaView;
12693 AgendaView.prototype.timeGridClass = TimeGrid_1.default;
12694 AgendaView.prototype.dayGridClass = DayGrid_1.default;
12695 // Will customize the rendering behavior of the AgendaView's timeGrid
12696 agendaTimeGridMethods = {
12697 // Generates the HTML that will go before the day-of week header cells
12698 renderHeadIntroHtml: function () {
12699 var view = this.view;
12700 var calendar = view.calendar;
12701 var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true);
12702 var weekText;
12703 if (this.opt('weekNumbers')) {
12704 weekText = weekStart.format(this.opt('smallWeekFormat'));
12705 return '' +
12706 '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' +
12707 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
12708 { date: weekStart, type: 'week', forceOff: this.colCnt > 1 }, util_1.htmlEscape(weekText) // inner HTML
12709 ) +
12710 '</th>';
12711 }
12712 else {
12713 return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>';
12714 }
12715 },
12716 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
12717 renderBgIntroHtml: function () {
12718 var view = this.view;
12719 return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>';
12720 },
12721 // Generates the HTML that goes before all other types of cells.
12722 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
12723 renderIntroHtml: function () {
12724 var view = this.view;
12725 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
12726 }
12727 };
12728 // Will customize the rendering behavior of the AgendaView's dayGrid
12729 agendaDayGridMethods = {
12730 // Generates the HTML that goes before the all-day cells
12731 renderBgIntroHtml: function () {
12732 var view = this.view;
12733 return '' +
12734 '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
12735 '<span>' + // needed for matchCellWidths
12736 view.getAllDayHtml() +
12737 '</span>' +
12738 '</td>';
12739 },
12740 // Generates the HTML that goes before all other types of cells.
12741 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
12742 renderIntroHtml: function () {
12743 var view = this.view;
12744 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
12745 }
12746 };
12747 function groupEventFootprintsByAllDay(eventFootprints) {
12748 var allDay = [];
12749 var timed = [];
12750 var i;
12751 for (i = 0; i < eventFootprints.length; i++) {
12752 if (eventFootprints[i].componentFootprint.isAllDay) {
12753 allDay.push(eventFootprints[i]);
12754 }
12755 else {
12756 timed.push(eventFootprints[i]);
12757 }
12758 }
12759 return { allDay: allDay, timed: timed };
12760 }
12761
12762
12763 /***/ }),
12764 /* 239 */
12765 /***/ (function(module, exports, __webpack_require__) {
12766
12767 Object.defineProperty(exports, "__esModule", { value: true });
12768 var tslib_1 = __webpack_require__(2);
12769 var $ = __webpack_require__(3);
12770 var moment = __webpack_require__(0);
12771 var util_1 = __webpack_require__(4);
12772 var InteractiveDateComponent_1 = __webpack_require__(42);
12773 var BusinessHourRenderer_1 = __webpack_require__(61);
12774 var StandardInteractionsMixin_1 = __webpack_require__(65);
12775 var DayTableMixin_1 = __webpack_require__(60);
12776 var CoordCache_1 = __webpack_require__(58);
12777 var UnzonedRange_1 = __webpack_require__(5);
12778 var ComponentFootprint_1 = __webpack_require__(12);
12779 var TimeGridEventRenderer_1 = __webpack_require__(240);
12780 var TimeGridHelperRenderer_1 = __webpack_require__(241);
12781 var TimeGridFillRenderer_1 = __webpack_require__(242);
12782 /* A component that renders one or more columns of vertical time slots
12783 ----------------------------------------------------------------------------------------------------------------------*/
12784 // We mixin DayTable, even though there is only a single row of days
12785 // potential nice values for the slot-duration and interval-duration
12786 // from largest to smallest
12787 var AGENDA_STOCK_SUB_DURATIONS = [
12788 { hours: 1 },
12789 { minutes: 30 },
12790 { minutes: 15 },
12791 { seconds: 30 },
12792 { seconds: 15 }
12793 ];
12794 var TimeGrid = /** @class */ (function (_super) {
12795 tslib_1.__extends(TimeGrid, _super);
12796 function TimeGrid(view) {
12797 var _this = _super.call(this, view) || this;
12798 _this.processOptions();
12799 return _this;
12800 }
12801 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
12802 TimeGrid.prototype.componentFootprintToSegs = function (componentFootprint) {
12803 var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange);
12804 var i;
12805 for (i = 0; i < segs.length; i++) {
12806 if (this.isRTL) {
12807 segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex;
12808 }
12809 else {
12810 segs[i].col = segs[i].dayIndex;
12811 }
12812 }
12813 return segs;
12814 };
12815 /* Date Handling
12816 ------------------------------------------------------------------------------------------------------------------*/
12817 TimeGrid.prototype.sliceRangeByTimes = function (unzonedRange) {
12818 var segs = [];
12819 var segRange;
12820 var dayIndex;
12821 for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) {
12822 segRange = unzonedRange.intersect(this.dayRanges[dayIndex]);
12823 if (segRange) {
12824 segs.push({
12825 startMs: segRange.startMs,
12826 endMs: segRange.endMs,
12827 isStart: segRange.isStart,
12828 isEnd: segRange.isEnd,
12829 dayIndex: dayIndex
12830 });
12831 }
12832 }
12833 return segs;
12834 };
12835 /* Options
12836 ------------------------------------------------------------------------------------------------------------------*/
12837 // Parses various options into properties of this object
12838 TimeGrid.prototype.processOptions = function () {
12839 var slotDuration = this.opt('slotDuration');
12840 var snapDuration = this.opt('snapDuration');
12841 var input;
12842 slotDuration = moment.duration(slotDuration);
12843 snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
12844 this.slotDuration = slotDuration;
12845 this.snapDuration = snapDuration;
12846 this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple?
12847 // might be an array value (for TimelineView).
12848 // if so, getting the most granular entry (the last one probably).
12849 input = this.opt('slotLabelFormat');
12850 if ($.isArray(input)) {
12851 input = input[input.length - 1];
12852 }
12853 this.labelFormat = input ||
12854 this.opt('smallTimeFormat'); // the computed default
12855 input = this.opt('slotLabelInterval');
12856 this.labelInterval = input ?
12857 moment.duration(input) :
12858 this.computeLabelInterval(slotDuration);
12859 };
12860 // Computes an automatic value for slotLabelInterval
12861 TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
12862 var i;
12863 var labelInterval;
12864 var slotsPerLabel;
12865 // find the smallest stock label interval that results in more than one slots-per-label
12866 for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
12867 labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
12868 slotsPerLabel = util_1.divideDurationByDuration(labelInterval, slotDuration);
12869 if (util_1.isInt(slotsPerLabel) && slotsPerLabel > 1) {
12870 return labelInterval;
12871 }
12872 }
12873 return moment.duration(slotDuration); // fall back. clone
12874 };
12875 /* Date Rendering
12876 ------------------------------------------------------------------------------------------------------------------*/
12877 TimeGrid.prototype.renderDates = function (dateProfile) {
12878 this.dateProfile = dateProfile;
12879 this.updateDayTable();
12880 this.renderSlats();
12881 this.renderColumns();
12882 };
12883 TimeGrid.prototype.unrenderDates = function () {
12884 // this.unrenderSlats(); // don't need this because repeated .html() calls clear
12885 this.unrenderColumns();
12886 };
12887 TimeGrid.prototype.renderSkeleton = function () {
12888 var theme = this.view.calendar.theme;
12889 this.el.html('<div class="fc-bg"></div>' +
12890 '<div class="fc-slats"></div>' +
12891 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none"></hr>');
12892 this.bottomRuleEl = this.el.find('hr');
12893 };
12894 TimeGrid.prototype.renderSlats = function () {
12895 var theme = this.view.calendar.theme;
12896 this.slatContainerEl = this.el.find('> .fc-slats')
12897 .html(// avoids needing ::unrenderSlats()
12898 '<table class="' + theme.getClass('tableGrid') + '">' +
12899 this.renderSlatRowHtml() +
12900 '</table>');
12901 this.slatEls = this.slatContainerEl.find('tr');
12902 this.slatCoordCache = new CoordCache_1.default({
12903 els: this.slatEls,
12904 isVertical: true
12905 });
12906 };
12907 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
12908 TimeGrid.prototype.renderSlatRowHtml = function () {
12909 var view = this.view;
12910 var calendar = view.calendar;
12911 var theme = calendar.theme;
12912 var isRTL = this.isRTL;
12913 var dateProfile = this.dateProfile;
12914 var html = '';
12915 var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations
12916 var slotIterator = moment.duration(0);
12917 var slotDate; // will be on the view's first day, but we only care about its time
12918 var isLabeled;
12919 var axisHtml;
12920 // Calculate the time for each slot
12921 while (slotTime < dateProfile.maxTime) {
12922 slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime);
12923 isLabeled = util_1.isInt(util_1.divideDurationByDuration(slotIterator, this.labelInterval));
12924 axisHtml =
12925 '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
12926 (isLabeled ?
12927 '<span>' + // for matchCellWidths
12928 util_1.htmlEscape(slotDate.format(this.labelFormat)) +
12929 '</span>' :
12930 '') +
12931 '</td>';
12932 html +=
12933 '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' +
12934 (isLabeled ? '' : ' class="fc-minor"') +
12935 '>' +
12936 (!isRTL ? axisHtml : '') +
12937 '<td class="' + theme.getClass('widgetContent') + '"></td>' +
12938 (isRTL ? axisHtml : '') +
12939 '</tr>';
12940 slotTime.add(this.slotDuration);
12941 slotIterator.add(this.slotDuration);
12942 }
12943 return html;
12944 };
12945 TimeGrid.prototype.renderColumns = function () {
12946 var dateProfile = this.dateProfile;
12947 var theme = this.view.calendar.theme;
12948 this.dayRanges = this.dayDates.map(function (dayDate) {
12949 return new UnzonedRange_1.default(dayDate.clone().add(dateProfile.minTime), dayDate.clone().add(dateProfile.maxTime));
12950 });
12951 if (this.headContainerEl) {
12952 this.headContainerEl.html(this.renderHeadHtml());
12953 }
12954 this.el.find('> .fc-bg').html('<table class="' + theme.getClass('tableGrid') + '">' +
12955 this.renderBgTrHtml(0) + // row=0
12956 '</table>');
12957 this.colEls = this.el.find('.fc-day, .fc-disabled-day');
12958 this.colCoordCache = new CoordCache_1.default({
12959 els: this.colEls,
12960 isHorizontal: true
12961 });
12962 this.renderContentSkeleton();
12963 };
12964 TimeGrid.prototype.unrenderColumns = function () {
12965 this.unrenderContentSkeleton();
12966 };
12967 /* Content Skeleton
12968 ------------------------------------------------------------------------------------------------------------------*/
12969 // Renders the DOM that the view's content will live in
12970 TimeGrid.prototype.renderContentSkeleton = function () {
12971 var cellHtml = '';
12972 var i;
12973 var skeletonEl;
12974 for (i = 0; i < this.colCnt; i++) {
12975 cellHtml +=
12976 '<td>' +
12977 '<div class="fc-content-col">' +
12978 '<div class="fc-event-container fc-helper-container"></div>' +
12979 '<div class="fc-event-container"></div>' +
12980 '<div class="fc-highlight-container"></div>' +
12981 '<div class="fc-bgevent-container"></div>' +
12982 '<div class="fc-business-container"></div>' +
12983 '</div>' +
12984 '</td>';
12985 }
12986 skeletonEl = this.contentSkeletonEl = $('<div class="fc-content-skeleton">' +
12987 '<table>' +
12988 '<tr>' + cellHtml + '</tr>' +
12989 '</table>' +
12990 '</div>');
12991 this.colContainerEls = skeletonEl.find('.fc-content-col');
12992 this.helperContainerEls = skeletonEl.find('.fc-helper-container');
12993 this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)');
12994 this.bgContainerEls = skeletonEl.find('.fc-bgevent-container');
12995 this.highlightContainerEls = skeletonEl.find('.fc-highlight-container');
12996 this.businessContainerEls = skeletonEl.find('.fc-business-container');
12997 this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level
12998 this.el.append(skeletonEl);
12999 };
13000 TimeGrid.prototype.unrenderContentSkeleton = function () {
13001 if (this.contentSkeletonEl) { // defensive :(
13002 this.contentSkeletonEl.remove();
13003 this.contentSkeletonEl = null;
13004 this.colContainerEls = null;
13005 this.helperContainerEls = null;
13006 this.fgContainerEls = null;
13007 this.bgContainerEls = null;
13008 this.highlightContainerEls = null;
13009 this.businessContainerEls = null;
13010 }
13011 };
13012 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
13013 TimeGrid.prototype.groupSegsByCol = function (segs) {
13014 var segsByCol = [];
13015 var i;
13016 for (i = 0; i < this.colCnt; i++) {
13017 segsByCol.push([]);
13018 }
13019 for (i = 0; i < segs.length; i++) {
13020 segsByCol[segs[i].col].push(segs[i]);
13021 }
13022 return segsByCol;
13023 };
13024 // Given segments grouped by column, insert the segments' elements into a parallel array of container
13025 // elements, each living within a column.
13026 TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
13027 var col;
13028 var segs;
13029 var i;
13030 for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
13031 segs = segsByCol[col];
13032 for (i = 0; i < segs.length; i++) {
13033 containerEls.eq(col).append(segs[i].el);
13034 }
13035 }
13036 };
13037 /* Now Indicator
13038 ------------------------------------------------------------------------------------------------------------------*/
13039 TimeGrid.prototype.getNowIndicatorUnit = function () {
13040 return 'minute'; // will refresh on the minute
13041 };
13042 TimeGrid.prototype.renderNowIndicator = function (date) {
13043 // HACK: if date columns not ready for some reason (scheduler)
13044 if (!this.colContainerEls) {
13045 return;
13046 }
13047 // seg system might be overkill, but it handles scenario where line needs to be rendered
13048 // more than once because of columns with the same date (resources columns for example)
13049 var segs = this.componentFootprintToSegs(new ComponentFootprint_1.default(new UnzonedRange_1.default(date, date.valueOf() + 1), // protect against null range
13050 false // all-day
13051 ));
13052 var top = this.computeDateTop(date, date);
13053 var nodes = [];
13054 var i;
13055 // render lines within the columns
13056 for (i = 0; i < segs.length; i++) {
13057 nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>')
13058 .css('top', top)
13059 .appendTo(this.colContainerEls.eq(segs[i].col))[0]);
13060 }
13061 // render an arrow over the axis
13062 if (segs.length > 0) { // is the current time in view?
13063 nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>')
13064 .css('top', top)
13065 .appendTo(this.el.find('.fc-content-skeleton'))[0]);
13066 }
13067 this.nowIndicatorEls = $(nodes);
13068 };
13069 TimeGrid.prototype.unrenderNowIndicator = function () {
13070 if (this.nowIndicatorEls) {
13071 this.nowIndicatorEls.remove();
13072 this.nowIndicatorEls = null;
13073 }
13074 };
13075 /* Coordinates
13076 ------------------------------------------------------------------------------------------------------------------*/
13077 TimeGrid.prototype.updateSize = function (totalHeight, isAuto, isResize) {
13078 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
13079 this.slatCoordCache.build();
13080 if (isResize) {
13081 this.updateSegVerticals([].concat(this.eventRenderer.getSegs(), this.businessSegs || []));
13082 }
13083 };
13084 TimeGrid.prototype.getTotalSlatHeight = function () {
13085 return this.slatContainerEl.outerHeight();
13086 };
13087 // Computes the top coordinate, relative to the bounds of the grid, of the given date.
13088 // `ms` can be a millisecond UTC time OR a UTC moment.
13089 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
13090 TimeGrid.prototype.computeDateTop = function (ms, startOfDayDate) {
13091 return this.computeTimeTop(moment.duration(ms - startOfDayDate.clone().stripTime()));
13092 };
13093 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
13094 TimeGrid.prototype.computeTimeTop = function (time) {
13095 var len = this.slatEls.length;
13096 var dateProfile = this.dateProfile;
13097 var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered
13098 var slatIndex;
13099 var slatRemainder;
13100 // compute a floating-point number for how many slats should be progressed through.
13101 // from 0 to number of slats (inclusive)
13102 // constrained because minTime/maxTime might be customized.
13103 slatCoverage = Math.max(0, slatCoverage);
13104 slatCoverage = Math.min(len, slatCoverage);
13105 // an integer index of the furthest whole slat
13106 // from 0 to number slats (*exclusive*, so len-1)
13107 slatIndex = Math.floor(slatCoverage);
13108 slatIndex = Math.min(slatIndex, len - 1);
13109 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
13110 // could be 1.0 if slatCoverage is covering *all* the slots
13111 slatRemainder = slatCoverage - slatIndex;
13112 return this.slatCoordCache.getTopPosition(slatIndex) +
13113 this.slatCoordCache.getHeight(slatIndex) * slatRemainder;
13114 };
13115 // Refreshes the CSS top/bottom coordinates for each segment element.
13116 // Works when called after initial render, after a window resize/zoom for example.
13117 TimeGrid.prototype.updateSegVerticals = function (segs) {
13118 this.computeSegVerticals(segs);
13119 this.assignSegVerticals(segs);
13120 };
13121 // For each segment in an array, computes and assigns its top and bottom properties
13122 TimeGrid.prototype.computeSegVerticals = function (segs) {
13123 var eventMinHeight = this.opt('agendaEventMinHeight');
13124 var i;
13125 var seg;
13126 var dayDate;
13127 for (i = 0; i < segs.length; i++) {
13128 seg = segs[i];
13129 dayDate = this.dayDates[seg.dayIndex];
13130 seg.top = this.computeDateTop(seg.startMs, dayDate);
13131 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.endMs, dayDate));
13132 }
13133 };
13134 // Given segments that already have their top/bottom properties computed, applies those values to
13135 // the segments' elements.
13136 TimeGrid.prototype.assignSegVerticals = function (segs) {
13137 var i;
13138 var seg;
13139 for (i = 0; i < segs.length; i++) {
13140 seg = segs[i];
13141 seg.el.css(this.generateSegVerticalCss(seg));
13142 }
13143 };
13144 // Generates an object with CSS properties for the top/bottom coordinates of a segment element
13145 TimeGrid.prototype.generateSegVerticalCss = function (seg) {
13146 return {
13147 top: seg.top,
13148 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
13149 };
13150 };
13151 /* Hit System
13152 ------------------------------------------------------------------------------------------------------------------*/
13153 TimeGrid.prototype.prepareHits = function () {
13154 this.colCoordCache.build();
13155 this.slatCoordCache.build();
13156 };
13157 TimeGrid.prototype.releaseHits = function () {
13158 this.colCoordCache.clear();
13159 // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop
13160 };
13161 TimeGrid.prototype.queryHit = function (leftOffset, topOffset) {
13162 var snapsPerSlot = this.snapsPerSlot;
13163 var colCoordCache = this.colCoordCache;
13164 var slatCoordCache = this.slatCoordCache;
13165 if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) {
13166 var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
13167 var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
13168 if (colIndex != null && slatIndex != null) {
13169 var slatTop = slatCoordCache.getTopOffset(slatIndex);
13170 var slatHeight = slatCoordCache.getHeight(slatIndex);
13171 var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
13172 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
13173 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
13174 var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
13175 var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
13176 return {
13177 col: colIndex,
13178 snap: snapIndex,
13179 component: this,
13180 left: colCoordCache.getLeftOffset(colIndex),
13181 right: colCoordCache.getRightOffset(colIndex),
13182 top: snapTop,
13183 bottom: snapBottom
13184 };
13185 }
13186 }
13187 };
13188 TimeGrid.prototype.getHitFootprint = function (hit) {
13189 var start = this.getCellDate(0, hit.col); // row=0
13190 var time = this.computeSnapTime(hit.snap); // pass in the snap-index
13191 var end;
13192 start.time(time);
13193 end = start.clone().add(this.snapDuration);
13194 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), false // all-day?
13195 );
13196 };
13197 // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
13198 TimeGrid.prototype.computeSnapTime = function (snapIndex) {
13199 return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex);
13200 };
13201 TimeGrid.prototype.getHitEl = function (hit) {
13202 return this.colEls.eq(hit.col);
13203 };
13204 /* Event Drag Visualization
13205 ------------------------------------------------------------------------------------------------------------------*/
13206 // Renders a visual indication of an event being dragged over the specified date(s).
13207 // A returned value of `true` signals that a mock "helper" event has been rendered.
13208 TimeGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
13209 var i;
13210 if (seg) { // if there is event information for this drag, render a helper event
13211 if (eventFootprints.length) {
13212 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
13213 // signal that a helper has been rendered
13214 return true;
13215 }
13216 }
13217 else { // otherwise, just render a highlight
13218 for (i = 0; i < eventFootprints.length; i++) {
13219 this.renderHighlight(eventFootprints[i].componentFootprint);
13220 }
13221 }
13222 };
13223 // Unrenders any visual indication of an event being dragged
13224 TimeGrid.prototype.unrenderDrag = function () {
13225 this.unrenderHighlight();
13226 this.helperRenderer.unrender();
13227 };
13228 /* Event Resize Visualization
13229 ------------------------------------------------------------------------------------------------------------------*/
13230 // Renders a visual indication of an event being resized
13231 TimeGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
13232 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
13233 };
13234 // Unrenders any visual indication of an event being resized
13235 TimeGrid.prototype.unrenderEventResize = function () {
13236 this.helperRenderer.unrender();
13237 };
13238 /* Selection
13239 ------------------------------------------------------------------------------------------------------------------*/
13240 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
13241 TimeGrid.prototype.renderSelectionFootprint = function (componentFootprint) {
13242 if (this.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered
13243 this.helperRenderer.renderComponentFootprint(componentFootprint);
13244 }
13245 else {
13246 this.renderHighlight(componentFootprint);
13247 }
13248 };
13249 // Unrenders any visual indication of a selection
13250 TimeGrid.prototype.unrenderSelection = function () {
13251 this.helperRenderer.unrender();
13252 this.unrenderHighlight();
13253 };
13254 return TimeGrid;
13255 }(InteractiveDateComponent_1.default));
13256 exports.default = TimeGrid;
13257 TimeGrid.prototype.eventRendererClass = TimeGridEventRenderer_1.default;
13258 TimeGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default;
13259 TimeGrid.prototype.helperRendererClass = TimeGridHelperRenderer_1.default;
13260 TimeGrid.prototype.fillRendererClass = TimeGridFillRenderer_1.default;
13261 StandardInteractionsMixin_1.default.mixInto(TimeGrid);
13262 DayTableMixin_1.default.mixInto(TimeGrid);
13263
13264
13265 /***/ }),
13266 /* 240 */
13267 /***/ (function(module, exports, __webpack_require__) {
13268
13269 Object.defineProperty(exports, "__esModule", { value: true });
13270 var tslib_1 = __webpack_require__(2);
13271 var util_1 = __webpack_require__(4);
13272 var EventRenderer_1 = __webpack_require__(44);
13273 /*
13274 Only handles foreground segs.
13275 Does not own rendering. Use for low-level util methods by TimeGrid.
13276 */
13277 var TimeGridEventRenderer = /** @class */ (function (_super) {
13278 tslib_1.__extends(TimeGridEventRenderer, _super);
13279 function TimeGridEventRenderer(timeGrid, fillRenderer) {
13280 var _this = _super.call(this, timeGrid, fillRenderer) || this;
13281 _this.timeGrid = timeGrid;
13282 return _this;
13283 }
13284 TimeGridEventRenderer.prototype.renderFgSegs = function (segs) {
13285 this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls);
13286 };
13287 // Given an array of foreground segments, render a DOM element for each, computes position,
13288 // and attaches to the column inner-container elements.
13289 TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) {
13290 var segsByCol;
13291 var col;
13292 segsByCol = this.timeGrid.groupSegsByCol(segs);
13293 for (col = 0; col < this.timeGrid.colCnt; col++) {
13294 this.updateFgSegCoords(segsByCol[col]);
13295 }
13296 this.timeGrid.attachSegsByCol(segsByCol, containerEls);
13297 };
13298 TimeGridEventRenderer.prototype.unrenderFgSegs = function () {
13299 if (this.fgSegs) { // hack
13300 this.fgSegs.forEach(function (seg) {
13301 seg.el.remove();
13302 });
13303 }
13304 };
13305 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
13306 TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
13307 return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM)
13308 };
13309 // Computes a default `displayEventEnd` value if one is not expliclty defined
13310 TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
13311 return true;
13312 };
13313 // Renders the HTML for a single event segment's default rendering
13314 TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
13315 var view = this.view;
13316 var calendar = view.calendar;
13317 var componentFootprint = seg.footprint.componentFootprint;
13318 var isAllDay = componentFootprint.isAllDay;
13319 var eventDef = seg.footprint.eventDef;
13320 var isDraggable = view.isEventDefDraggable(eventDef);
13321 var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef);
13322 var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
13323 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
13324 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef));
13325 var timeText;
13326 var fullTimeText; // more verbose time text. for the print stylesheet
13327 var startTimeText; // just the start time text
13328 classes.unshift('fc-time-grid-event', 'fc-v-event');
13329 // if the event appears to span more than one day...
13330 if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
13331 // Don't display time text on segments that run entirely through a day.
13332 // That would appear as midnight-midnight and would look dumb.
13333 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
13334 if (seg.isStart || seg.isEnd) {
13335 var zonedStart = calendar.msToMoment(seg.startMs);
13336 var zonedEnd = calendar.msToMoment(seg.endMs);
13337 timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay);
13338 fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT');
13339 startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false
13340 }
13341 }
13342 else {
13343 // Display the normal time text for the *event's* times
13344 timeText = this.getTimeText(seg.footprint);
13345 fullTimeText = this.getTimeText(seg.footprint, 'LT');
13346 startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false
13347 }
13348 return '<a class="' + classes.join(' ') + '"' +
13349 (eventDef.url ?
13350 ' href="' + util_1.htmlEscape(eventDef.url) + '"' :
13351 '') +
13352 (skinCss ?
13353 ' style="' + skinCss + '"' :
13354 '') +
13355 '>' +
13356 '<div class="fc-content">' +
13357 (timeText ?
13358 '<div class="fc-time"' +
13359 ' data-start="' + util_1.htmlEscape(startTimeText) + '"' +
13360 ' data-full="' + util_1.htmlEscape(fullTimeText) + '"' +
13361 '>' +
13362 '<span>' + util_1.htmlEscape(timeText) + '</span>' +
13363 '</div>' :
13364 '') +
13365 (eventDef.title ?
13366 '<div class="fc-title">' +
13367 util_1.htmlEscape(eventDef.title) +
13368 '</div>' :
13369 '') +
13370 '</div>' +
13371 '<div class="fc-bg"></div>' +
13372 /* TODO: write CSS for this
13373 (isResizableFromStart ?
13374 '<div class="fc-resizer fc-start-resizer"></div>' :
13375 ''
13376 ) +
13377 */
13378 (isResizableFromEnd ?
13379 '<div class="fc-resizer fc-end-resizer"></div>' :
13380 '') +
13381 '</a>';
13382 };
13383 // Given segments that are assumed to all live in the *same column*,
13384 // compute their verical/horizontal coordinates and assign to their elements.
13385 TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) {
13386 this.timeGrid.computeSegVerticals(segs); // horizontals relies on this
13387 this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array
13388 this.timeGrid.assignSegVerticals(segs);
13389 this.assignFgSegHorizontals(segs);
13390 };
13391 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
13392 // NOTE: Also reorders the given array by date!
13393 TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) {
13394 var levels;
13395 var level0;
13396 var i;
13397 this.sortEventSegs(segs); // order by certain criteria
13398 levels = buildSlotSegLevels(segs);
13399 computeForwardSlotSegs(levels);
13400 if ((level0 = levels[0])) {
13401 for (i = 0; i < level0.length; i++) {
13402 computeSlotSegPressures(level0[i]);
13403 }
13404 for (i = 0; i < level0.length; i++) {
13405 this.computeFgSegForwardBack(level0[i], 0, 0);
13406 }
13407 }
13408 };
13409 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13410 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13411 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13412 //
13413 // The segment might be part of a "series", which means consecutive segments with the same pressure
13414 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13415 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13416 // coordinate of the first segment in the series.
13417 TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
13418 var forwardSegs = seg.forwardSegs;
13419 var i;
13420 if (seg.forwardCoord === undefined) { // not already computed
13421 if (!forwardSegs.length) {
13422 // if there are no forward segments, this segment should butt up against the edge
13423 seg.forwardCoord = 1;
13424 }
13425 else {
13426 // sort highest pressure first
13427 this.sortForwardSegs(forwardSegs);
13428 // this segment's forwardCoord will be calculated from the backwardCoord of the
13429 // highest-pressure forward segment.
13430 this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
13431 seg.forwardCoord = forwardSegs[0].backwardCoord;
13432 }
13433 // calculate the backwardCoord from the forwardCoord. consider the series
13434 seg.backwardCoord = seg.forwardCoord -
13435 (seg.forwardCoord - seriesBackwardCoord) / // available width for series
13436 (seriesBackwardPressure + 1); // # of segments in the series
13437 // use this segment's coordinates to computed the coordinates of the less-pressurized
13438 // forward segments
13439 for (i = 0; i < forwardSegs.length; i++) {
13440 this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
13441 }
13442 }
13443 };
13444 TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
13445 forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs'));
13446 };
13447 // A cmp function for determining which forward segment to rely on more when computing coordinates.
13448 TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) {
13449 // put higher-pressure first
13450 return seg2.forwardPressure - seg1.forwardPressure ||
13451 // put segments that are closer to initial edge first (and favor ones with no coords yet)
13452 (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
13453 // do normal sorting...
13454 this.compareEventSegs(seg1, seg2);
13455 };
13456 // Given foreground event segments that have already had their position coordinates computed,
13457 // assigns position-related CSS values to their elements.
13458 TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) {
13459 var i;
13460 var seg;
13461 for (i = 0; i < segs.length; i++) {
13462 seg = segs[i];
13463 seg.el.css(this.generateFgSegHorizontalCss(seg));
13464 // if the event is short that the title will be cut off,
13465 // attach a className that condenses the title into the time area.
13466 if (seg.footprint.eventDef.title && seg.bottom - seg.top < 30) {
13467 seg.el.addClass('fc-short'); // TODO: "condensed" is a better name
13468 }
13469 }
13470 };
13471 // Generates an object with CSS properties/values that should be applied to an event segment element.
13472 // Contains important positioning-related properties that should be applied to any event element, customized or not.
13473 TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) {
13474 var shouldOverlap = this.opt('slotEventOverlap');
13475 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
13476 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
13477 var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
13478 var isRTL = this.timeGrid.isRTL;
13479 var left; // amount of space from left edge, a fraction of the total width
13480 var right; // amount of space from right edge, a fraction of the total width
13481 if (shouldOverlap) {
13482 // double the width, but don't go beyond the maximum forward coordinate (1.0)
13483 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
13484 }
13485 if (isRTL) {
13486 left = 1 - forwardCoord;
13487 right = backwardCoord;
13488 }
13489 else {
13490 left = backwardCoord;
13491 right = 1 - forwardCoord;
13492 }
13493 props.zIndex = seg.level + 1; // convert from 0-base to 1-based
13494 props.left = left * 100 + '%';
13495 props.right = right * 100 + '%';
13496 if (shouldOverlap && seg.forwardPressure) {
13497 // add padding to the edge so that forward stacked events don't cover the resizer's icon
13498 props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13499 }
13500 return props;
13501 };
13502 return TimeGridEventRenderer;
13503 }(EventRenderer_1.default));
13504 exports.default = TimeGridEventRenderer;
13505 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
13506 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
13507 function buildSlotSegLevels(segs) {
13508 var levels = [];
13509 var i;
13510 var seg;
13511 var j;
13512 for (i = 0; i < segs.length; i++) {
13513 seg = segs[i];
13514 // go through all the levels and stop on the first level where there are no collisions
13515 for (j = 0; j < levels.length; j++) {
13516 if (!computeSlotSegCollisions(seg, levels[j]).length) {
13517 break;
13518 }
13519 }
13520 seg.level = j;
13521 (levels[j] || (levels[j] = [])).push(seg);
13522 }
13523 return levels;
13524 }
13525 // For every segment, figure out the other segments that are in subsequent
13526 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13527 function computeForwardSlotSegs(levels) {
13528 var i;
13529 var level;
13530 var j;
13531 var seg;
13532 var k;
13533 for (i = 0; i < levels.length; i++) {
13534 level = levels[i];
13535 for (j = 0; j < level.length; j++) {
13536 seg = level[j];
13537 seg.forwardSegs = [];
13538 for (k = i + 1; k < levels.length; k++) {
13539 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
13540 }
13541 }
13542 }
13543 }
13544 // Figure out which path forward (via seg.forwardSegs) results in the longest path until
13545 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
13546 function computeSlotSegPressures(seg) {
13547 var forwardSegs = seg.forwardSegs;
13548 var forwardPressure = 0;
13549 var i;
13550 var forwardSeg;
13551 if (seg.forwardPressure === undefined) { // not already computed
13552 for (i = 0; i < forwardSegs.length; i++) {
13553 forwardSeg = forwardSegs[i];
13554 // figure out the child's maximum forward path
13555 computeSlotSegPressures(forwardSeg);
13556 // either use the existing maximum, or use the child's forward pressure
13557 // plus one (for the forwardSeg itself)
13558 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
13559 }
13560 seg.forwardPressure = forwardPressure;
13561 }
13562 }
13563 // Find all the segments in `otherSegs` that vertically collide with `seg`.
13564 // Append into an optionally-supplied `results` array and return.
13565 function computeSlotSegCollisions(seg, otherSegs, results) {
13566 if (results === void 0) { results = []; }
13567 for (var i = 0; i < otherSegs.length; i++) {
13568 if (isSlotSegCollision(seg, otherSegs[i])) {
13569 results.push(otherSegs[i]);
13570 }
13571 }
13572 return results;
13573 }
13574 // Do these segments occupy the same vertical space?
13575 function isSlotSegCollision(seg1, seg2) {
13576 return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
13577 }
13578
13579
13580 /***/ }),
13581 /* 241 */
13582 /***/ (function(module, exports, __webpack_require__) {
13583
13584 Object.defineProperty(exports, "__esModule", { value: true });
13585 var tslib_1 = __webpack_require__(2);
13586 var $ = __webpack_require__(3);
13587 var HelperRenderer_1 = __webpack_require__(63);
13588 var TimeGridHelperRenderer = /** @class */ (function (_super) {
13589 tslib_1.__extends(TimeGridHelperRenderer, _super);
13590 function TimeGridHelperRenderer() {
13591 return _super !== null && _super.apply(this, arguments) || this;
13592 }
13593 TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
13594 var helperNodes = [];
13595 var i;
13596 var seg;
13597 var sourceEl;
13598 // TODO: not good to call eventRenderer this way
13599 this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls);
13600 // Try to make the segment that is in the same row as sourceSeg look the same
13601 for (i = 0; i < segs.length; i++) {
13602 seg = segs[i];
13603 if (sourceSeg && sourceSeg.col === seg.col) {
13604 sourceEl = sourceSeg.el;
13605 seg.el.css({
13606 left: sourceEl.css('left'),
13607 right: sourceEl.css('right'),
13608 'margin-left': sourceEl.css('margin-left'),
13609 'margin-right': sourceEl.css('margin-right')
13610 });
13611 }
13612 helperNodes.push(seg.el[0]);
13613 }
13614 return $(helperNodes); // must return the elements rendered
13615 };
13616 return TimeGridHelperRenderer;
13617 }(HelperRenderer_1.default));
13618 exports.default = TimeGridHelperRenderer;
13619
13620
13621 /***/ }),
13622 /* 242 */
13623 /***/ (function(module, exports, __webpack_require__) {
13624
13625 Object.defineProperty(exports, "__esModule", { value: true });
13626 var tslib_1 = __webpack_require__(2);
13627 var FillRenderer_1 = __webpack_require__(62);
13628 var TimeGridFillRenderer = /** @class */ (function (_super) {
13629 tslib_1.__extends(TimeGridFillRenderer, _super);
13630 function TimeGridFillRenderer() {
13631 return _super !== null && _super.apply(this, arguments) || this;
13632 }
13633 TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) {
13634 var timeGrid = this.component;
13635 var containerEls;
13636 // TODO: more efficient lookup
13637 if (type === 'bgEvent') {
13638 containerEls = timeGrid.bgContainerEls;
13639 }
13640 else if (type === 'businessHours') {
13641 containerEls = timeGrid.businessContainerEls;
13642 }
13643 else if (type === 'highlight') {
13644 containerEls = timeGrid.highlightContainerEls;
13645 }
13646 timeGrid.updateSegVerticals(segs);
13647 timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
13648 return segs.map(function (seg) {
13649 return seg.el[0];
13650 });
13651 };
13652 return TimeGridFillRenderer;
13653 }(FillRenderer_1.default));
13654 exports.default = TimeGridFillRenderer;
13655
13656
13657 /***/ }),
13658 /* 243 */
13659 /***/ (function(module, exports, __webpack_require__) {
13660
13661 Object.defineProperty(exports, "__esModule", { value: true });
13662 var tslib_1 = __webpack_require__(2);
13663 var $ = __webpack_require__(3);
13664 var util_1 = __webpack_require__(4);
13665 var EventRenderer_1 = __webpack_require__(44);
13666 /* Event-rendering methods for the DayGrid class
13667 ----------------------------------------------------------------------------------------------------------------------*/
13668 var DayGridEventRenderer = /** @class */ (function (_super) {
13669 tslib_1.__extends(DayGridEventRenderer, _super);
13670 function DayGridEventRenderer(dayGrid, fillRenderer) {
13671 var _this = _super.call(this, dayGrid, fillRenderer) || this;
13672 _this.dayGrid = dayGrid;
13673 return _this;
13674 }
13675 DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) {
13676 // don't render timed background events
13677 eventRanges = $.grep(eventRanges, function (eventRange) {
13678 return eventRange.eventDef.isAllDay();
13679 });
13680 _super.prototype.renderBgRanges.call(this, eventRanges);
13681 };
13682 // Renders the given foreground event segments onto the grid
13683 DayGridEventRenderer.prototype.renderFgSegs = function (segs) {
13684 var rowStructs = this.rowStructs = this.renderSegRows(segs);
13685 // append to each row's content skeleton
13686 this.dayGrid.rowEls.each(function (i, rowNode) {
13687 $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl);
13688 });
13689 };
13690 // Unrenders all currently rendered foreground event segments
13691 DayGridEventRenderer.prototype.unrenderFgSegs = function () {
13692 var rowStructs = this.rowStructs || [];
13693 var rowStruct;
13694 while ((rowStruct = rowStructs.pop())) {
13695 rowStruct.tbodyEl.remove();
13696 }
13697 this.rowStructs = null;
13698 };
13699 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
13700 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
13701 // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
13702 DayGridEventRenderer.prototype.renderSegRows = function (segs) {
13703 var rowStructs = [];
13704 var segRows;
13705 var row;
13706 segRows = this.groupSegRows(segs); // group into nested arrays
13707 // iterate each row of segment groupings
13708 for (row = 0; row < segRows.length; row++) {
13709 rowStructs.push(this.renderSegRow(row, segRows[row]));
13710 }
13711 return rowStructs;
13712 };
13713 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
13714 // the segments. Returns object with a bunch of internal data about how the render was calculated.
13715 // NOTE: modifies rowSegs
13716 DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
13717 var colCnt = this.dayGrid.colCnt;
13718 var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
13719 var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
13720 var tbody = $('<tbody>');
13721 var segMatrix = []; // lookup for which segments are rendered into which level+col cells
13722 var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
13723 var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
13724 var i;
13725 var levelSegs;
13726 var col;
13727 var tr;
13728 var j;
13729 var seg;
13730 var td;
13731 // populates empty cells from the current column (`col`) to `endCol`
13732 function emptyCellsUntil(endCol) {
13733 while (col < endCol) {
13734 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
13735 td = (loneCellMatrix[i - 1] || [])[col];
13736 if (td) {
13737 td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1);
13738 }
13739 else {
13740 td = $('<td>');
13741 tr.append(td);
13742 }
13743 cellMatrix[i][col] = td;
13744 loneCellMatrix[i][col] = td;
13745 col++;
13746 }
13747 }
13748 for (i = 0; i < levelCnt; i++) { // iterate through all levels
13749 levelSegs = segLevels[i];
13750 col = 0;
13751 tr = $('<tr>');
13752 segMatrix.push([]);
13753 cellMatrix.push([]);
13754 loneCellMatrix.push([]);
13755 // levelCnt might be 1 even though there are no actual levels. protect against this.
13756 // this single empty row is useful for styling.
13757 if (levelSegs) {
13758 for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
13759 seg = levelSegs[j];
13760 emptyCellsUntil(seg.leftCol);
13761 // create a container that occupies or more columns. append the event element.
13762 td = $('<td class="fc-event-container">').append(seg.el);
13763 if (seg.leftCol !== seg.rightCol) {
13764 td.attr('colspan', seg.rightCol - seg.leftCol + 1);
13765 }
13766 else { // a single-column segment
13767 loneCellMatrix[i][col] = td;
13768 }
13769 while (col <= seg.rightCol) {
13770 cellMatrix[i][col] = td;
13771 segMatrix[i][col] = seg;
13772 col++;
13773 }
13774 tr.append(td);
13775 }
13776 }
13777 emptyCellsUntil(colCnt); // finish off the row
13778 this.dayGrid.bookendCells(tr);
13779 tbody.append(tr);
13780 }
13781 return {
13782 row: row,
13783 tbodyEl: tbody,
13784 cellMatrix: cellMatrix,
13785 segMatrix: segMatrix,
13786 segLevels: segLevels,
13787 segs: rowSegs
13788 };
13789 };
13790 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
13791 // NOTE: modifies segs
13792 DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
13793 var levels = [];
13794 var i;
13795 var seg;
13796 var j;
13797 // Give preference to elements with certain criteria, so they have
13798 // a chance to be closer to the top.
13799 this.sortEventSegs(segs);
13800 for (i = 0; i < segs.length; i++) {
13801 seg = segs[i];
13802 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
13803 for (j = 0; j < levels.length; j++) {
13804 if (!isDaySegCollision(seg, levels[j])) {
13805 break;
13806 }
13807 }
13808 // `j` now holds the desired subrow index
13809 seg.level = j;
13810 // create new level array if needed and append segment
13811 (levels[j] || (levels[j] = [])).push(seg);
13812 }
13813 // order segments left-to-right. very important if calendar is RTL
13814 for (j = 0; j < levels.length; j++) {
13815 levels[j].sort(compareDaySegCols);
13816 }
13817 return levels;
13818 };
13819 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
13820 DayGridEventRenderer.prototype.groupSegRows = function (segs) {
13821 var segRows = [];
13822 var i;
13823 for (i = 0; i < this.dayGrid.rowCnt; i++) {
13824 segRows.push([]);
13825 }
13826 for (i = 0; i < segs.length; i++) {
13827 segRows[segs[i].row].push(segs[i]);
13828 }
13829 return segRows;
13830 };
13831 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
13832 DayGridEventRenderer.prototype.computeEventTimeFormat = function () {
13833 return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p"
13834 };
13835 // Computes a default `displayEventEnd` value if one is not expliclty defined
13836 DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
13837 return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
13838 };
13839 // Builds the HTML to be used for the default element for an individual segment
13840 DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
13841 var view = this.view;
13842 var eventDef = seg.footprint.eventDef;
13843 var isAllDay = seg.footprint.componentFootprint.isAllDay;
13844 var isDraggable = view.isEventDefDraggable(eventDef);
13845 var isResizableFromStart = !disableResizing && isAllDay &&
13846 seg.isStart && view.isEventDefResizableFromStart(eventDef);
13847 var isResizableFromEnd = !disableResizing && isAllDay &&
13848 seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
13849 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
13850 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef));
13851 var timeHtml = '';
13852 var timeText;
13853 var titleHtml;
13854 classes.unshift('fc-day-grid-event', 'fc-h-event');
13855 // Only display a timed events time if it is the starting segment
13856 if (seg.isStart) {
13857 timeText = this.getTimeText(seg.footprint);
13858 if (timeText) {
13859 timeHtml = '<span class="fc-time">' + util_1.htmlEscape(timeText) + '</span>';
13860 }
13861 }
13862 titleHtml =
13863 '<span class="fc-title">' +
13864 (util_1.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
13865 '</span>';
13866 return '<a class="' + classes.join(' ') + '"' +
13867 (eventDef.url ?
13868 ' href="' + util_1.htmlEscape(eventDef.url) + '"' :
13869 '') +
13870 (skinCss ?
13871 ' style="' + skinCss + '"' :
13872 '') +
13873 '>' +
13874 '<div class="fc-content">' +
13875 (this.dayGrid.isRTL ?
13876 titleHtml + ' ' + timeHtml : // put a natural space in between
13877 timeHtml + ' ' + titleHtml //
13878 ) +
13879 '</div>' +
13880 (isResizableFromStart ?
13881 '<div class="fc-resizer fc-start-resizer"></div>' :
13882 '') +
13883 (isResizableFromEnd ?
13884 '<div class="fc-resizer fc-end-resizer"></div>' :
13885 '') +
13886 '</a>';
13887 };
13888 return DayGridEventRenderer;
13889 }(EventRenderer_1.default));
13890 exports.default = DayGridEventRenderer;
13891 // Computes whether two segments' columns collide. They are assumed to be in the same row.
13892 function isDaySegCollision(seg, otherSegs) {
13893 var i;
13894 var otherSeg;
13895 for (i = 0; i < otherSegs.length; i++) {
13896 otherSeg = otherSegs[i];
13897 if (otherSeg.leftCol <= seg.rightCol &&
13898 otherSeg.rightCol >= seg.leftCol) {
13899 return true;
13900 }
13901 }
13902 return false;
13903 }
13904 // A cmp function for determining the leftmost event
13905 function compareDaySegCols(a, b) {
13906 return a.leftCol - b.leftCol;
13907 }
13908
13909
13910 /***/ }),
13911 /* 244 */
13912 /***/ (function(module, exports, __webpack_require__) {
13913
13914 Object.defineProperty(exports, "__esModule", { value: true });
13915 var tslib_1 = __webpack_require__(2);
13916 var $ = __webpack_require__(3);
13917 var HelperRenderer_1 = __webpack_require__(63);
13918 var DayGridHelperRenderer = /** @class */ (function (_super) {
13919 tslib_1.__extends(DayGridHelperRenderer, _super);
13920 function DayGridHelperRenderer() {
13921 return _super !== null && _super.apply(this, arguments) || this;
13922 }
13923 // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null.
13924 DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
13925 var helperNodes = [];
13926 var rowStructs;
13927 // TODO: not good to call eventRenderer this way
13928 rowStructs = this.eventRenderer.renderSegRows(segs);
13929 // inject each new event skeleton into each associated row
13930 this.component.rowEls.each(function (row, rowNode) {
13931 var rowEl = $(rowNode); // the .fc-row
13932 var skeletonEl = $('<div class="fc-helper-skeleton"><table></table></div>'); // will be absolutely positioned
13933 var skeletonTopEl;
13934 var skeletonTop;
13935 // If there is an original segment, match the top position. Otherwise, put it at the row's top level
13936 if (sourceSeg && sourceSeg.row === row) {
13937 skeletonTop = sourceSeg.el.position().top;
13938 }
13939 else {
13940 skeletonTopEl = rowEl.find('.fc-content-skeleton tbody');
13941 if (!skeletonTopEl.length) { // when no events
13942 skeletonTopEl = rowEl.find('.fc-content-skeleton table');
13943 }
13944 skeletonTop = skeletonTopEl.position().top;
13945 }
13946 skeletonEl.css('top', skeletonTop)
13947 .find('table')
13948 .append(rowStructs[row].tbodyEl);
13949 rowEl.append(skeletonEl);
13950 helperNodes.push(skeletonEl[0]);
13951 });
13952 return $(helperNodes); // must return the elements rendered
13953 };
13954 return DayGridHelperRenderer;
13955 }(HelperRenderer_1.default));
13956 exports.default = DayGridHelperRenderer;
13957
13958
13959 /***/ }),
13960 /* 245 */
13961 /***/ (function(module, exports, __webpack_require__) {
13962
13963 Object.defineProperty(exports, "__esModule", { value: true });
13964 var tslib_1 = __webpack_require__(2);
13965 var $ = __webpack_require__(3);
13966 var FillRenderer_1 = __webpack_require__(62);
13967 var DayGridFillRenderer = /** @class */ (function (_super) {
13968 tslib_1.__extends(DayGridFillRenderer, _super);
13969 function DayGridFillRenderer() {
13970 var _this = _super !== null && _super.apply(this, arguments) || this;
13971 _this.fillSegTag = 'td'; // override the default tag name
13972 return _this;
13973 }
13974 DayGridFillRenderer.prototype.attachSegEls = function (type, segs) {
13975 var nodes = [];
13976 var i;
13977 var seg;
13978 var skeletonEl;
13979 for (i = 0; i < segs.length; i++) {
13980 seg = segs[i];
13981 skeletonEl = this.renderFillRow(type, seg);
13982 this.component.rowEls.eq(seg.row).append(skeletonEl);
13983 nodes.push(skeletonEl[0]);
13984 }
13985 return nodes;
13986 };
13987 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
13988 DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
13989 var colCnt = this.component.colCnt;
13990 var startCol = seg.leftCol;
13991 var endCol = seg.rightCol + 1;
13992 var className;
13993 var skeletonEl;
13994 var trEl;
13995 if (type === 'businessHours') {
13996 className = 'bgevent';
13997 }
13998 else {
13999 className = type.toLowerCase();
14000 }
14001 skeletonEl = $('<div class="fc-' + className + '-skeleton">' +
14002 '<table><tr></tr></table>' +
14003 '</div>');
14004 trEl = skeletonEl.find('tr');
14005 if (startCol > 0) {
14006 trEl.append(
14007 // will create (startCol + 1) td's
14008 new Array(startCol + 1).join('<td></td>'));
14009 }
14010 trEl.append(seg.el.attr('colspan', endCol - startCol));
14011 if (endCol < colCnt) {
14012 trEl.append(
14013 // will create (colCnt - endCol) td's
14014 new Array(colCnt - endCol + 1).join('<td></td>'));
14015 }
14016 this.component.bookendCells(trEl);
14017 return skeletonEl;
14018 };
14019 return DayGridFillRenderer;
14020 }(FillRenderer_1.default));
14021 exports.default = DayGridFillRenderer;
14022
14023
14024 /***/ }),
14025 /* 246 */
14026 /***/ (function(module, exports, __webpack_require__) {
14027
14028 Object.defineProperty(exports, "__esModule", { value: true });
14029 var tslib_1 = __webpack_require__(2);
14030 var moment = __webpack_require__(0);
14031 var util_1 = __webpack_require__(4);
14032 var BasicView_1 = __webpack_require__(67);
14033 var MonthViewDateProfileGenerator_1 = __webpack_require__(247);
14034 /* A month view with day cells running in rows (one-per-week) and columns
14035 ----------------------------------------------------------------------------------------------------------------------*/
14036 var MonthView = /** @class */ (function (_super) {
14037 tslib_1.__extends(MonthView, _super);
14038 function MonthView() {
14039 return _super !== null && _super.apply(this, arguments) || this;
14040 }
14041 // Overrides the default BasicView behavior to have special multi-week auto-height logic
14042 MonthView.prototype.setGridHeight = function (height, isAuto) {
14043 // if auto, make the height of each row the height that it would be if there were 6 weeks
14044 if (isAuto) {
14045 height *= this.dayGrid.rowCnt / 6;
14046 }
14047 util_1.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
14048 };
14049 MonthView.prototype.isDateInOtherMonth = function (date, dateProfile) {
14050 return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize
14051 };
14052 return MonthView;
14053 }(BasicView_1.default));
14054 exports.default = MonthView;
14055 MonthView.prototype.dateProfileGeneratorClass = MonthViewDateProfileGenerator_1.default;
14056
14057
14058 /***/ }),
14059 /* 247 */
14060 /***/ (function(module, exports, __webpack_require__) {
14061
14062 Object.defineProperty(exports, "__esModule", { value: true });
14063 var tslib_1 = __webpack_require__(2);
14064 var BasicViewDateProfileGenerator_1 = __webpack_require__(68);
14065 var UnzonedRange_1 = __webpack_require__(5);
14066 var MonthViewDateProfileGenerator = /** @class */ (function (_super) {
14067 tslib_1.__extends(MonthViewDateProfileGenerator, _super);
14068 function MonthViewDateProfileGenerator() {
14069 return _super !== null && _super.apply(this, arguments) || this;
14070 }
14071 // Computes the date range that will be rendered.
14072 MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
14073 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay);
14074 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
14075 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
14076 var rowCnt;
14077 // ensure 6 weeks
14078 if (this.opt('fixedWeekCount')) {
14079 rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
14080 end.diff(start, 'weeks', true) // dontRound=true
14081 );
14082 end.add(6 - rowCnt, 'weeks');
14083 }
14084 return new UnzonedRange_1.default(start, end);
14085 };
14086 return MonthViewDateProfileGenerator;
14087 }(BasicViewDateProfileGenerator_1.default));
14088 exports.default = MonthViewDateProfileGenerator;
14089
14090
14091 /***/ }),
14092 /* 248 */
14093 /***/ (function(module, exports, __webpack_require__) {
14094
14095 Object.defineProperty(exports, "__esModule", { value: true });
14096 var tslib_1 = __webpack_require__(2);
14097 var $ = __webpack_require__(3);
14098 var util_1 = __webpack_require__(4);
14099 var UnzonedRange_1 = __webpack_require__(5);
14100 var View_1 = __webpack_require__(43);
14101 var Scroller_1 = __webpack_require__(41);
14102 var ListEventRenderer_1 = __webpack_require__(249);
14103 var ListEventPointing_1 = __webpack_require__(250);
14104 /*
14105 Responsible for the scroller, and forwarding event-related actions into the "grid".
14106 */
14107 var ListView = /** @class */ (function (_super) {
14108 tslib_1.__extends(ListView, _super);
14109 function ListView(calendar, viewSpec) {
14110 var _this = _super.call(this, calendar, viewSpec) || this;
14111 _this.segSelector = '.fc-list-item'; // which elements accept event actions
14112 _this.scroller = new Scroller_1.default({
14113 overflowX: 'hidden',
14114 overflowY: 'auto'
14115 });
14116 return _this;
14117 }
14118 ListView.prototype.renderSkeleton = function () {
14119 this.el.addClass('fc-list-view ' +
14120 this.calendar.theme.getClass('listView'));
14121 this.scroller.render();
14122 this.scroller.el.appendTo(this.el);
14123 this.contentEl = this.scroller.scrollEl; // shortcut
14124 };
14125 ListView.prototype.unrenderSkeleton = function () {
14126 this.scroller.destroy(); // will remove the Grid too
14127 };
14128 ListView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
14129 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
14130 this.scroller.clear(); // sets height to 'auto' and clears overflow
14131 if (!isAuto) {
14132 this.scroller.setHeight(this.computeScrollerHeight(totalHeight));
14133 }
14134 };
14135 ListView.prototype.computeScrollerHeight = function (totalHeight) {
14136 return totalHeight -
14137 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
14138 };
14139 ListView.prototype.renderDates = function (dateProfile) {
14140 var calendar = this.calendar;
14141 var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true);
14142 var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true);
14143 var dayDates = [];
14144 var dayRanges = [];
14145 while (dayStart < viewEnd) {
14146 dayDates.push(dayStart.clone());
14147 dayRanges.push(new UnzonedRange_1.default(dayStart, dayStart.clone().add(1, 'day')));
14148 dayStart.add(1, 'day');
14149 }
14150 this.dayDates = dayDates;
14151 this.dayRanges = dayRanges;
14152 // all real rendering happens in EventRenderer
14153 };
14154 // slices by day
14155 ListView.prototype.componentFootprintToSegs = function (footprint) {
14156 var dayRanges = this.dayRanges;
14157 var dayIndex;
14158 var segRange;
14159 var seg;
14160 var segs = [];
14161 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
14162 segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]);
14163 if (segRange) {
14164 seg = {
14165 startMs: segRange.startMs,
14166 endMs: segRange.endMs,
14167 isStart: segRange.isStart,
14168 isEnd: segRange.isEnd,
14169 dayIndex: dayIndex
14170 };
14171 segs.push(seg);
14172 // detect when footprint won't go fully into the next day,
14173 // and mutate the latest seg to the be the end.
14174 if (!seg.isEnd && !footprint.isAllDay &&
14175 dayIndex + 1 < dayRanges.length &&
14176 footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold) {
14177 seg.endMs = footprint.unzonedRange.endMs;
14178 seg.isEnd = true;
14179 break;
14180 }
14181 }
14182 }
14183 return segs;
14184 };
14185 ListView.prototype.renderEmptyMessage = function () {
14186 this.contentEl.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
14187 '<div class="fc-list-empty-wrap1">' +
14188 '<div class="fc-list-empty">' +
14189 util_1.htmlEscape(this.opt('noEventsMessage')) +
14190 '</div>' +
14191 '</div>' +
14192 '</div>');
14193 };
14194 // render the event segments in the view
14195 ListView.prototype.renderSegList = function (allSegs) {
14196 var segsByDay = this.groupSegsByDay(allSegs); // sparse array
14197 var dayIndex;
14198 var daySegs;
14199 var i;
14200 var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>');
14201 var tbodyEl = tableEl.find('tbody');
14202 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
14203 daySegs = segsByDay[dayIndex];
14204 if (daySegs) { // sparse array, so might be undefined
14205 // append a day header
14206 tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex]));
14207 this.eventRenderer.sortEventSegs(daySegs);
14208 for (i = 0; i < daySegs.length; i++) {
14209 tbodyEl.append(daySegs[i].el); // append event row
14210 }
14211 }
14212 }
14213 this.contentEl.empty().append(tableEl);
14214 };
14215 // Returns a sparse array of arrays, segs grouped by their dayIndex
14216 ListView.prototype.groupSegsByDay = function (segs) {
14217 var segsByDay = []; // sparse array
14218 var i;
14219 var seg;
14220 for (i = 0; i < segs.length; i++) {
14221 seg = segs[i];
14222 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
14223 .push(seg);
14224 }
14225 return segsByDay;
14226 };
14227 // generates the HTML for the day headers that live amongst the event rows
14228 ListView.prototype.dayHeaderHtml = function (dayDate) {
14229 var mainFormat = this.opt('listDayFormat');
14230 var altFormat = this.opt('listDayAltFormat');
14231 return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' +
14232 '<td class="' + (this.calendar.theme.getClass('tableListHeading') ||
14233 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' +
14234 (mainFormat ?
14235 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-main' }, util_1.htmlEscape(dayDate.format(mainFormat)) // inner HTML
14236 ) :
14237 '') +
14238 (altFormat ?
14239 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-alt' }, util_1.htmlEscape(dayDate.format(altFormat)) // inner HTML
14240 ) :
14241 '') +
14242 '</td>' +
14243 '</tr>';
14244 };
14245 return ListView;
14246 }(View_1.default));
14247 exports.default = ListView;
14248 ListView.prototype.eventRendererClass = ListEventRenderer_1.default;
14249 ListView.prototype.eventPointingClass = ListEventPointing_1.default;
14250
14251
14252 /***/ }),
14253 /* 249 */
14254 /***/ (function(module, exports, __webpack_require__) {
14255
14256 Object.defineProperty(exports, "__esModule", { value: true });
14257 var tslib_1 = __webpack_require__(2);
14258 var util_1 = __webpack_require__(4);
14259 var EventRenderer_1 = __webpack_require__(44);
14260 var ListEventRenderer = /** @class */ (function (_super) {
14261 tslib_1.__extends(ListEventRenderer, _super);
14262 function ListEventRenderer() {
14263 return _super !== null && _super.apply(this, arguments) || this;
14264 }
14265 ListEventRenderer.prototype.renderFgSegs = function (segs) {
14266 if (!segs.length) {
14267 this.component.renderEmptyMessage();
14268 }
14269 else {
14270 this.component.renderSegList(segs);
14271 }
14272 };
14273 // generates the HTML for a single event row
14274 ListEventRenderer.prototype.fgSegHtml = function (seg) {
14275 var view = this.view;
14276 var calendar = view.calendar;
14277 var theme = calendar.theme;
14278 var eventFootprint = seg.footprint;
14279 var eventDef = eventFootprint.eventDef;
14280 var componentFootprint = eventFootprint.componentFootprint;
14281 var url = eventDef.url;
14282 var classes = ['fc-list-item'].concat(this.getClasses(eventDef));
14283 var bgColor = this.getBgColor(eventDef);
14284 var timeHtml;
14285 if (componentFootprint.isAllDay) {
14286 timeHtml = view.getAllDayHtml();
14287 }
14288 else if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
14289 if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day
14290 timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay));
14291 }
14292 else { // inner segment that lasts the whole day
14293 timeHtml = view.getAllDayHtml();
14294 }
14295 }
14296 else {
14297 // Display the normal time text for the *event's* times
14298 timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint));
14299 }
14300 if (url) {
14301 classes.push('fc-has-url');
14302 }
14303 return '<tr class="' + classes.join(' ') + '">' +
14304 (this.displayEventTime ?
14305 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' +
14306 (timeHtml || '') +
14307 '</td>' :
14308 '') +
14309 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' +
14310 '<span class="fc-event-dot"' +
14311 (bgColor ?
14312 ' style="background-color:' + bgColor + '"' :
14313 '') +
14314 '></span>' +
14315 '</td>' +
14316 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' +
14317 '<a' + (url ? ' href="' + util_1.htmlEscape(url) + '"' : '') + '>' +
14318 util_1.htmlEscape(eventDef.title || '') +
14319 '</a>' +
14320 '</td>' +
14321 '</tr>';
14322 };
14323 // like "4:00am"
14324 ListEventRenderer.prototype.computeEventTimeFormat = function () {
14325 return this.opt('mediumTimeFormat');
14326 };
14327 return ListEventRenderer;
14328 }(EventRenderer_1.default));
14329 exports.default = ListEventRenderer;
14330
14331
14332 /***/ }),
14333 /* 250 */
14334 /***/ (function(module, exports, __webpack_require__) {
14335
14336 Object.defineProperty(exports, "__esModule", { value: true });
14337 var tslib_1 = __webpack_require__(2);
14338 var $ = __webpack_require__(3);
14339 var EventPointing_1 = __webpack_require__(64);
14340 var ListEventPointing = /** @class */ (function (_super) {
14341 tslib_1.__extends(ListEventPointing, _super);
14342 function ListEventPointing() {
14343 return _super !== null && _super.apply(this, arguments) || this;
14344 }
14345 // for events with a url, the whole <tr> should be clickable,
14346 // but it's impossible to wrap with an <a> tag. simulate this.
14347 ListEventPointing.prototype.handleClick = function (seg, ev) {
14348 var url;
14349 _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action
14350 // not clicking on or within an <a> with an href
14351 if (!$(ev.target).closest('a[href]').length) {
14352 url = seg.footprint.eventDef.url;
14353 if (url && !ev.isDefaultPrevented()) { // jsEvent not cancelled in handler
14354 window.location.href = url; // simulate link click
14355 }
14356 }
14357 };
14358 return ListEventPointing;
14359 }(EventPointing_1.default));
14360 exports.default = ListEventPointing;
14361
14362
14363 /***/ }),
14364 /* 251 */,
14365 /* 252 */,
14366 /* 253 */,
14367 /* 254 */,
14368 /* 255 */,
14369 /* 256 */
14370 /***/ (function(module, exports, __webpack_require__) {
14371
14372 var $ = __webpack_require__(3);
14373 var exportHooks = __webpack_require__(18);
14374 var util_1 = __webpack_require__(4);
14375 var Calendar_1 = __webpack_require__(232);
14376 // for intentional side-effects
14377 __webpack_require__(11);
14378 __webpack_require__(49);
14379 __webpack_require__(260);
14380 __webpack_require__(261);
14381 __webpack_require__(264);
14382 __webpack_require__(265);
14383 __webpack_require__(266);
14384 __webpack_require__(267);
14385 $.fullCalendar = exportHooks;
14386 $.fn.fullCalendar = function (options) {
14387 var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
14388 var res = this; // what this function will return (this jQuery object by default)
14389 this.each(function (i, _element) {
14390 var element = $(_element);
14391 var calendar = element.data('fullCalendar'); // get the existing calendar object (if any)
14392 var singleRes; // the returned value of this single method call
14393 // a method call
14394 if (typeof options === 'string') {
14395 if (options === 'getCalendar') {
14396 if (!i) { // first element only
14397 res = calendar;
14398 }
14399 }
14400 else if (options === 'destroy') { // don't warn if no calendar object
14401 if (calendar) {
14402 calendar.destroy();
14403 element.removeData('fullCalendar');
14404 }
14405 }
14406 else if (!calendar) {
14407 util_1.warn('Attempting to call a FullCalendar method on an element with no calendar.');
14408 }
14409 else if ($.isFunction(calendar[options])) {
14410 singleRes = calendar[options].apply(calendar, args);
14411 if (!i) {
14412 res = singleRes; // record the first method call result
14413 }
14414 if (options === 'destroy') { // for the destroy method, must remove Calendar object data
14415 element.removeData('fullCalendar');
14416 }
14417 }
14418 else {
14419 util_1.warn("'" + options + "' is an unknown FullCalendar method.");
14420 }
14421 }
14422 else if (!calendar) { // don't initialize twice
14423 calendar = new Calendar_1.default(element, options);
14424 element.data('fullCalendar', calendar);
14425 calendar.render();
14426 }
14427 });
14428 return res;
14429 };
14430 module.exports = exportHooks;
14431
14432
14433 /***/ }),
14434 /* 257 */
14435 /***/ (function(module, exports, __webpack_require__) {
14436
14437 Object.defineProperty(exports, "__esModule", { value: true });
14438 var $ = __webpack_require__(3);
14439 var util_1 = __webpack_require__(4);
14440 /* Toolbar with buttons and title
14441 ----------------------------------------------------------------------------------------------------------------------*/
14442 var Toolbar = /** @class */ (function () {
14443 function Toolbar(calendar, toolbarOptions) {
14444 this.el = null; // mirrors local `el`
14445 this.viewsWithButtons = [];
14446 this.calendar = calendar;
14447 this.toolbarOptions = toolbarOptions;
14448 }
14449 // method to update toolbar-specific options, not calendar-wide options
14450 Toolbar.prototype.setToolbarOptions = function (newToolbarOptions) {
14451 this.toolbarOptions = newToolbarOptions;
14452 };
14453 // can be called repeatedly and will rerender
14454 Toolbar.prototype.render = function () {
14455 var sections = this.toolbarOptions.layout;
14456 var el = this.el;
14457 if (sections) {
14458 if (!el) {
14459 el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'>");
14460 }
14461 else {
14462 el.empty();
14463 }
14464 el.append(this.renderSection('left'))
14465 .append(this.renderSection('right'))
14466 .append(this.renderSection('center'))
14467 .append('<div class="fc-clear"></div>');
14468 }
14469 else {
14470 this.removeElement();
14471 }
14472 };
14473 Toolbar.prototype.removeElement = function () {
14474 if (this.el) {
14475 this.el.remove();
14476 this.el = null;
14477 }
14478 };
14479 Toolbar.prototype.renderSection = function (position) {
14480 var _this = this;
14481 var calendar = this.calendar;
14482 var theme = calendar.theme;
14483 var optionsManager = calendar.optionsManager;
14484 var viewSpecManager = calendar.viewSpecManager;
14485 var sectionEl = $('<div class="fc-' + position + '">');
14486 var buttonStr = this.toolbarOptions.layout[position];
14487 var calendarCustomButtons = optionsManager.get('customButtons') || {};
14488 var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
14489 var calendarButtonText = optionsManager.get('buttonText') || {};
14490 if (buttonStr) {
14491 $.each(buttonStr.split(' '), function (i, buttonGroupStr) {
14492 var groupChildren = $();
14493 var isOnlyButtons = true;
14494 var groupEl;
14495 $.each(buttonGroupStr.split(','), function (j, buttonName) {
14496 var customButtonProps;
14497 var viewSpec;
14498 var buttonClick;
14499 var buttonIcon; // only one of these will be set
14500 var buttonText; // "
14501 var buttonInnerHtml;
14502 var buttonClasses;
14503 var buttonEl;
14504 var buttonAriaAttr;
14505 if (buttonName === 'title') {
14506 groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height
14507 isOnlyButtons = false;
14508 }
14509 else {
14510 if ((customButtonProps = calendarCustomButtons[buttonName])) {
14511 buttonClick = function (ev) {
14512 if (customButtonProps.click) {
14513 customButtonProps.click.call(buttonEl[0], ev);
14514 }
14515 };
14516 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
14517 (buttonIcon = theme.getIconClass(buttonName)) ||
14518 (buttonText = customButtonProps.text);
14519 }
14520 else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) {
14521 _this.viewsWithButtons.push(buttonName);
14522 buttonClick = function () {
14523 calendar.changeView(buttonName);
14524 };
14525 (buttonText = viewSpec.buttonTextOverride) ||
14526 (buttonIcon = theme.getIconClass(buttonName)) ||
14527 (buttonText = viewSpec.buttonTextDefault);
14528 }
14529 else if (calendar[buttonName]) { // a calendar method
14530 buttonClick = function () {
14531 calendar[buttonName]();
14532 };
14533 (buttonText = calendarButtonTextOverrides[buttonName]) ||
14534 (buttonIcon = theme.getIconClass(buttonName)) ||
14535 (buttonText = calendarButtonText[buttonName]);
14536 // ^ everything else is considered default
14537 }
14538 if (buttonClick) {
14539 buttonClasses = [
14540 'fc-' + buttonName + '-button',
14541 theme.getClass('button'),
14542 theme.getClass('stateDefault')
14543 ];
14544 if (buttonText) {
14545 buttonInnerHtml = util_1.htmlEscape(buttonText);
14546 buttonAriaAttr = '';
14547 }
14548 else if (buttonIcon) {
14549 buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
14550 buttonAriaAttr = ' aria-label="' + buttonName + '"';
14551 }
14552 buttonEl = $(// type="button" so that it doesn't submit a form
14553 '<button type="button" class="' + buttonClasses.join(' ') + '"' +
14554 buttonAriaAttr +
14555 '>' + buttonInnerHtml + '</button>')
14556 .click(function (ev) {
14557 // don't process clicks for disabled buttons
14558 if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) {
14559 buttonClick(ev);
14560 // after the click action, if the button becomes the "active" tab, or disabled,
14561 // it should never have a hover class, so remove it now.
14562 if (buttonEl.hasClass(theme.getClass('stateActive')) ||
14563 buttonEl.hasClass(theme.getClass('stateDisabled'))) {
14564 buttonEl.removeClass(theme.getClass('stateHover'));
14565 }
14566 }
14567 })
14568 .mousedown(function () {
14569 // the *down* effect (mouse pressed in).
14570 // only on buttons that are not the "active" tab, or disabled
14571 buttonEl
14572 .not('.' + theme.getClass('stateActive'))
14573 .not('.' + theme.getClass('stateDisabled'))
14574 .addClass(theme.getClass('stateDown'));
14575 })
14576 .mouseup(function () {
14577 // undo the *down* effect
14578 buttonEl.removeClass(theme.getClass('stateDown'));
14579 })
14580 .hover(function () {
14581 // the *hover* effect.
14582 // only on buttons that are not the "active" tab, or disabled
14583 buttonEl
14584 .not('.' + theme.getClass('stateActive'))
14585 .not('.' + theme.getClass('stateDisabled'))
14586 .addClass(theme.getClass('stateHover'));
14587 }, function () {
14588 // undo the *hover* effect
14589 buttonEl
14590 .removeClass(theme.getClass('stateHover'))
14591 .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup
14592 });
14593 groupChildren = groupChildren.add(buttonEl);
14594 }
14595 }
14596 });
14597 if (isOnlyButtons) {
14598 groupChildren
14599 .first().addClass(theme.getClass('cornerLeft')).end()
14600 .last().addClass(theme.getClass('cornerRight')).end();
14601 }
14602 if (groupChildren.length > 1) {
14603 groupEl = $('<div>');
14604 if (isOnlyButtons) {
14605 groupEl.addClass(theme.getClass('buttonGroup'));
14606 }
14607 groupEl.append(groupChildren);
14608 sectionEl.append(groupEl);
14609 }
14610 else {
14611 sectionEl.append(groupChildren); // 1 or 0 children
14612 }
14613 });
14614 }
14615 return sectionEl;
14616 };
14617 Toolbar.prototype.updateTitle = function (text) {
14618 if (this.el) {
14619 this.el.find('h2').text(text);
14620 }
14621 };
14622 Toolbar.prototype.activateButton = function (buttonName) {
14623 if (this.el) {
14624 this.el.find('.fc-' + buttonName + '-button')
14625 .addClass(this.calendar.theme.getClass('stateActive'));
14626 }
14627 };
14628 Toolbar.prototype.deactivateButton = function (buttonName) {
14629 if (this.el) {
14630 this.el.find('.fc-' + buttonName + '-button')
14631 .removeClass(this.calendar.theme.getClass('stateActive'));
14632 }
14633 };
14634 Toolbar.prototype.disableButton = function (buttonName) {
14635 if (this.el) {
14636 this.el.find('.fc-' + buttonName + '-button')
14637 .prop('disabled', true)
14638 .addClass(this.calendar.theme.getClass('stateDisabled'));
14639 }
14640 };
14641 Toolbar.prototype.enableButton = function (buttonName) {
14642 if (this.el) {
14643 this.el.find('.fc-' + buttonName + '-button')
14644 .prop('disabled', false)
14645 .removeClass(this.calendar.theme.getClass('stateDisabled'));
14646 }
14647 };
14648 Toolbar.prototype.getViewsWithButtons = function () {
14649 return this.viewsWithButtons;
14650 };
14651 return Toolbar;
14652 }());
14653 exports.default = Toolbar;
14654
14655
14656 /***/ }),
14657 /* 258 */
14658 /***/ (function(module, exports, __webpack_require__) {
14659
14660 Object.defineProperty(exports, "__esModule", { value: true });
14661 var tslib_1 = __webpack_require__(2);
14662 var $ = __webpack_require__(3);
14663 var util_1 = __webpack_require__(4);
14664 var options_1 = __webpack_require__(33);
14665 var locale_1 = __webpack_require__(32);
14666 var Model_1 = __webpack_require__(51);
14667 var OptionsManager = /** @class */ (function (_super) {
14668 tslib_1.__extends(OptionsManager, _super);
14669 function OptionsManager(_calendar, overrides) {
14670 var _this = _super.call(this) || this;
14671 _this._calendar = _calendar;
14672 _this.overrides = $.extend({}, overrides); // make a copy
14673 _this.dynamicOverrides = {};
14674 _this.compute();
14675 return _this;
14676 }
14677 OptionsManager.prototype.add = function (newOptionHash) {
14678 var optionCnt = 0;
14679 var optionName;
14680 this.recordOverrides(newOptionHash); // will trigger this model's watchers
14681 for (optionName in newOptionHash) {
14682 optionCnt++;
14683 }
14684 // special-case handling of single option change.
14685 // if only one option change, `optionName` will be its name.
14686 if (optionCnt === 1) {
14687 if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') {
14688 this._calendar.updateViewSize(true); // isResize=true
14689 return;
14690 }
14691 else if (optionName === 'defaultDate') {
14692 return; // can't change date this way. use gotoDate instead
14693 }
14694 else if (optionName === 'businessHours') {
14695 return; // this model already reacts to this
14696 }
14697 else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) {
14698 return; // doesn't affect rendering. only interactions.
14699 }
14700 else if (optionName === 'timezone') {
14701 this._calendar.view.flash('initialEvents');
14702 return;
14703 }
14704 }
14705 // catch-all. rerender the header and footer and rebuild/rerender the current view
14706 this._calendar.renderHeader();
14707 this._calendar.renderFooter();
14708 // even non-current views will be affected by this option change. do before rerender
14709 // TODO: detangle
14710 this._calendar.viewsByType = {};
14711 this._calendar.reinitView();
14712 };
14713 // Computes the flattened options hash for the calendar and assigns to `this.options`.
14714 // Assumes this.overrides and this.dynamicOverrides have already been initialized.
14715 OptionsManager.prototype.compute = function () {
14716 var locale;
14717 var localeDefaults;
14718 var isRTL;
14719 var dirDefaults;
14720 var rawOptions;
14721 locale = util_1.firstDefined(// explicit locale option given?
14722 this.dynamicOverrides.locale, this.overrides.locale);
14723 localeDefaults = locale_1.localeOptionHash[locale];
14724 if (!localeDefaults) { // explicit locale option not given or invalid?
14725 locale = options_1.globalDefaults.locale;
14726 localeDefaults = locale_1.localeOptionHash[locale] || {};
14727 }
14728 isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL?
14729 this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL);
14730 dirDefaults = isRTL ? options_1.rtlDefaults : {};
14731 this.dirDefaults = dirDefaults;
14732 this.localeDefaults = localeDefaults;
14733 rawOptions = options_1.mergeOptions([
14734 options_1.globalDefaults,
14735 dirDefaults,
14736 localeDefaults,
14737 this.overrides,
14738 this.dynamicOverrides
14739 ]);
14740 locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options
14741 this.reset(rawOptions);
14742 };
14743 // stores the new options internally, but does not rerender anything.
14744 OptionsManager.prototype.recordOverrides = function (newOptionHash) {
14745 var optionName;
14746 for (optionName in newOptionHash) {
14747 this.dynamicOverrides[optionName] = newOptionHash[optionName];
14748 }
14749 this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it
14750 this.compute(); // this.options needs to be recomputed after the dynamic override
14751 };
14752 return OptionsManager;
14753 }(Model_1.default));
14754 exports.default = OptionsManager;
14755
14756
14757 /***/ }),
14758 /* 259 */
14759 /***/ (function(module, exports, __webpack_require__) {
14760
14761 Object.defineProperty(exports, "__esModule", { value: true });
14762 var moment = __webpack_require__(0);
14763 var $ = __webpack_require__(3);
14764 var ViewRegistry_1 = __webpack_require__(24);
14765 var util_1 = __webpack_require__(4);
14766 var options_1 = __webpack_require__(33);
14767 var locale_1 = __webpack_require__(32);
14768 var ViewSpecManager = /** @class */ (function () {
14769 function ViewSpecManager(optionsManager, _calendar) {
14770 this.optionsManager = optionsManager;
14771 this._calendar = _calendar;
14772 this.clearCache();
14773 }
14774 ViewSpecManager.prototype.clearCache = function () {
14775 this.viewSpecCache = {};
14776 };
14777 // Gets information about how to create a view. Will use a cache.
14778 ViewSpecManager.prototype.getViewSpec = function (viewType) {
14779 var cache = this.viewSpecCache;
14780 return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType));
14781 };
14782 // Given a duration singular unit, like "week" or "day", finds a matching view spec.
14783 // Preference is given to views that have corresponding buttons.
14784 ViewSpecManager.prototype.getUnitViewSpec = function (unit) {
14785 var viewTypes;
14786 var i;
14787 var spec;
14788 if ($.inArray(unit, util_1.unitsDesc) !== -1) {
14789 // put views that have buttons first. there will be duplicates, but oh well
14790 viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well?
14791 $.each(ViewRegistry_1.viewHash, function (viewType) {
14792 viewTypes.push(viewType);
14793 });
14794 for (i = 0; i < viewTypes.length; i++) {
14795 spec = this.getViewSpec(viewTypes[i]);
14796 if (spec) {
14797 if (spec.singleUnit === unit) {
14798 return spec;
14799 }
14800 }
14801 }
14802 }
14803 };
14804 // Builds an object with information on how to create a given view
14805 ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) {
14806 var viewOverrides = this.optionsManager.overrides.views || {};
14807 var specChain = []; // for the view. lowest to highest priority
14808 var defaultsChain = []; // for the view. lowest to highest priority
14809 var overridesChain = []; // for the view. lowest to highest priority
14810 var viewType = requestedViewType;
14811 var spec; // for the view
14812 var overrides; // for the view
14813 var durationInput;
14814 var duration;
14815 var unit;
14816 // iterate from the specific view definition to a more general one until we hit an actual View class
14817 while (viewType) {
14818 spec = ViewRegistry_1.viewHash[viewType];
14819 overrides = viewOverrides[viewType];
14820 viewType = null; // clear. might repopulate for another iteration
14821 if (typeof spec === 'function') { // TODO: deprecate
14822 spec = { 'class': spec };
14823 }
14824 if (spec) {
14825 specChain.unshift(spec);
14826 defaultsChain.unshift(spec.defaults || {});
14827 durationInput = durationInput || spec.duration;
14828 viewType = viewType || spec.type;
14829 }
14830 if (overrides) {
14831 overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level
14832 durationInput = durationInput || overrides.duration;
14833 viewType = viewType || overrides.type;
14834 }
14835 }
14836 spec = util_1.mergeProps(specChain);
14837 spec.type = requestedViewType;
14838 if (!spec['class']) {
14839 return false;
14840 }
14841 // fall back to top-level `duration` option
14842 durationInput = durationInput ||
14843 this.optionsManager.dynamicOverrides.duration ||
14844 this.optionsManager.overrides.duration;
14845 if (durationInput) {
14846 duration = moment.duration(durationInput);
14847 if (duration.valueOf()) { // valid?
14848 unit = util_1.computeDurationGreatestUnit(duration, durationInput);
14849 spec.duration = duration;
14850 spec.durationUnit = unit;
14851 // view is a single-unit duration, like "week" or "day"
14852 // incorporate options for this. lowest priority
14853 if (duration.as(unit) === 1) {
14854 spec.singleUnit = unit;
14855 overridesChain.unshift(viewOverrides[unit] || {});
14856 }
14857 }
14858 }
14859 spec.defaults = options_1.mergeOptions(defaultsChain);
14860 spec.overrides = options_1.mergeOptions(overridesChain);
14861 this.buildViewSpecOptions(spec);
14862 this.buildViewSpecButtonText(spec, requestedViewType);
14863 return spec;
14864 };
14865 // Builds and assigns a view spec's options object from its already-assigned defaults and overrides
14866 ViewSpecManager.prototype.buildViewSpecOptions = function (spec) {
14867 var optionsManager = this.optionsManager;
14868 spec.options = options_1.mergeOptions([
14869 options_1.globalDefaults,
14870 spec.defaults,
14871 optionsManager.dirDefaults,
14872 optionsManager.localeDefaults,
14873 optionsManager.overrides,
14874 spec.overrides,
14875 optionsManager.dynamicOverrides // dynamically set via setter. highest precedence
14876 ]);
14877 locale_1.populateInstanceComputableOptions(spec.options);
14878 };
14879 // Computes and assigns a view spec's buttonText-related options
14880 ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) {
14881 var optionsManager = this.optionsManager;
14882 // given an options object with a possible `buttonText` hash, lookup the buttonText for the
14883 // requested view, falling back to a generic unit entry like "week" or "day"
14884 function queryButtonText(options) {
14885 var buttonText = options.buttonText || {};
14886 return buttonText[requestedViewType] ||
14887 // view can decide to look up a certain key
14888 (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) ||
14889 // a key like "month"
14890 (spec.singleUnit ? buttonText[spec.singleUnit] : null);
14891 }
14892 // highest to lowest priority
14893 spec.buttonTextOverride =
14894 queryButtonText(optionsManager.dynamicOverrides) ||
14895 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
14896 spec.overrides.buttonText; // `buttonText` for view-specific options is a string
14897 // highest to lowest priority. mirrors buildViewSpecOptions
14898 spec.buttonTextDefault =
14899 queryButtonText(optionsManager.localeDefaults) ||
14900 queryButtonText(optionsManager.dirDefaults) ||
14901 spec.defaults.buttonText || // a single string. from ViewSubclass.defaults
14902 queryButtonText(options_1.globalDefaults) ||
14903 (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days"
14904 requestedViewType; // fall back to given view name
14905 };
14906 return ViewSpecManager;
14907 }());
14908 exports.default = ViewSpecManager;
14909
14910
14911 /***/ }),
14912 /* 260 */
14913 /***/ (function(module, exports, __webpack_require__) {
14914
14915 Object.defineProperty(exports, "__esModule", { value: true });
14916 var EventSourceParser_1 = __webpack_require__(38);
14917 var ArrayEventSource_1 = __webpack_require__(56);
14918 var FuncEventSource_1 = __webpack_require__(223);
14919 var JsonFeedEventSource_1 = __webpack_require__(224);
14920 EventSourceParser_1.default.registerClass(ArrayEventSource_1.default);
14921 EventSourceParser_1.default.registerClass(FuncEventSource_1.default);
14922 EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default);
14923
14924
14925 /***/ }),
14926 /* 261 */
14927 /***/ (function(module, exports, __webpack_require__) {
14928
14929 Object.defineProperty(exports, "__esModule", { value: true });
14930 var ThemeRegistry_1 = __webpack_require__(57);
14931 var StandardTheme_1 = __webpack_require__(221);
14932 var JqueryUiTheme_1 = __webpack_require__(222);
14933 var Bootstrap3Theme_1 = __webpack_require__(262);
14934 var Bootstrap4Theme_1 = __webpack_require__(263);
14935 ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default);
14936 ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default);
14937 ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default);
14938 ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default);
14939
14940
14941 /***/ }),
14942 /* 262 */
14943 /***/ (function(module, exports, __webpack_require__) {
14944
14945 Object.defineProperty(exports, "__esModule", { value: true });
14946 var tslib_1 = __webpack_require__(2);
14947 var Theme_1 = __webpack_require__(22);
14948 var Bootstrap3Theme = /** @class */ (function (_super) {
14949 tslib_1.__extends(Bootstrap3Theme, _super);
14950 function Bootstrap3Theme() {
14951 return _super !== null && _super.apply(this, arguments) || this;
14952 }
14953 return Bootstrap3Theme;
14954 }(Theme_1.default));
14955 exports.default = Bootstrap3Theme;
14956 Bootstrap3Theme.prototype.classes = {
14957 widget: 'fc-bootstrap3',
14958 tableGrid: 'table-bordered',
14959 tableList: 'table',
14960 tableListHeading: 'active',
14961 buttonGroup: 'btn-group',
14962 button: 'btn btn-default',
14963 stateActive: 'active',
14964 stateDisabled: 'disabled',
14965 today: 'alert alert-info',
14966 popover: 'panel panel-default',
14967 popoverHeader: 'panel-heading',
14968 popoverContent: 'panel-body',
14969 // day grid
14970 // for left/right border color when border is inset from edges (all-day in agenda view)
14971 // avoid `panel` class b/c don't want margins/radius. only border color.
14972 headerRow: 'panel-default',
14973 dayRow: 'panel-default',
14974 // list view
14975 listView: 'panel panel-default'
14976 };
14977 Bootstrap3Theme.prototype.baseIconClass = 'glyphicon';
14978 Bootstrap3Theme.prototype.iconClasses = {
14979 close: 'glyphicon-remove',
14980 prev: 'glyphicon-chevron-left',
14981 next: 'glyphicon-chevron-right',
14982 prevYear: 'glyphicon-backward',
14983 nextYear: 'glyphicon-forward'
14984 };
14985 Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons';
14986 Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon';
14987 Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-';
14988
14989
14990 /***/ }),
14991 /* 263 */
14992 /***/ (function(module, exports, __webpack_require__) {
14993
14994 Object.defineProperty(exports, "__esModule", { value: true });
14995 var tslib_1 = __webpack_require__(2);
14996 var Theme_1 = __webpack_require__(22);
14997 var Bootstrap4Theme = /** @class */ (function (_super) {
14998 tslib_1.__extends(Bootstrap4Theme, _super);
14999 function Bootstrap4Theme() {
15000 return _super !== null && _super.apply(this, arguments) || this;
15001 }
15002 return Bootstrap4Theme;
15003 }(Theme_1.default));
15004 exports.default = Bootstrap4Theme;
15005 Bootstrap4Theme.prototype.classes = {
15006 widget: 'fc-bootstrap4',
15007 tableGrid: 'table-bordered',
15008 tableList: 'table',
15009 tableListHeading: 'table-active',
15010 buttonGroup: 'btn-group',
15011 button: 'btn btn-primary',
15012 stateActive: 'active',
15013 stateDisabled: 'disabled',
15014 today: 'alert alert-info',
15015 popover: 'card card-primary',
15016 popoverHeader: 'card-header',
15017 popoverContent: 'card-body',
15018 // day grid
15019 // for left/right border color when border is inset from edges (all-day in agenda view)
15020 // avoid `table` class b/c don't want margins/padding/structure. only border color.
15021 headerRow: 'table-bordered',
15022 dayRow: 'table-bordered',
15023 // list view
15024 listView: 'card card-primary'
15025 };
15026 Bootstrap4Theme.prototype.baseIconClass = 'fa';
15027 Bootstrap4Theme.prototype.iconClasses = {
15028 close: 'fa-times',
15029 prev: 'fa-chevron-left',
15030 next: 'fa-chevron-right',
15031 prevYear: 'fa-angle-double-left',
15032 nextYear: 'fa-angle-double-right'
15033 };
15034 Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
15035 Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
15036 Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-';
15037
15038
15039 /***/ }),
15040 /* 264 */
15041 /***/ (function(module, exports, __webpack_require__) {
15042
15043 Object.defineProperty(exports, "__esModule", { value: true });
15044 var ViewRegistry_1 = __webpack_require__(24);
15045 var BasicView_1 = __webpack_require__(67);
15046 var MonthView_1 = __webpack_require__(246);
15047 ViewRegistry_1.defineView('basic', {
15048 'class': BasicView_1.default
15049 });
15050 ViewRegistry_1.defineView('basicDay', {
15051 type: 'basic',
15052 duration: { days: 1 }
15053 });
15054 ViewRegistry_1.defineView('basicWeek', {
15055 type: 'basic',
15056 duration: { weeks: 1 }
15057 });
15058 ViewRegistry_1.defineView('month', {
15059 'class': MonthView_1.default,
15060 duration: { months: 1 },
15061 defaults: {
15062 fixedWeekCount: true
15063 }
15064 });
15065
15066
15067 /***/ }),
15068 /* 265 */
15069 /***/ (function(module, exports, __webpack_require__) {
15070
15071 Object.defineProperty(exports, "__esModule", { value: true });
15072 var ViewRegistry_1 = __webpack_require__(24);
15073 var AgendaView_1 = __webpack_require__(238);
15074 ViewRegistry_1.defineView('agenda', {
15075 'class': AgendaView_1.default,
15076 defaults: {
15077 allDaySlot: true,
15078 slotDuration: '00:30:00',
15079 slotEventOverlap: true // a bad name. confused with overlap/constraint system
15080 }
15081 });
15082 ViewRegistry_1.defineView('agendaDay', {
15083 type: 'agenda',
15084 duration: { days: 1 }
15085 });
15086 ViewRegistry_1.defineView('agendaWeek', {
15087 type: 'agenda',
15088 duration: { weeks: 1 }
15089 });
15090
15091
15092 /***/ }),
15093 /* 266 */
15094 /***/ (function(module, exports, __webpack_require__) {
15095
15096 Object.defineProperty(exports, "__esModule", { value: true });
15097 var ViewRegistry_1 = __webpack_require__(24);
15098 var ListView_1 = __webpack_require__(248);
15099 ViewRegistry_1.defineView('list', {
15100 'class': ListView_1.default,
15101 buttonTextKey: 'list',
15102 defaults: {
15103 buttonText: 'list',
15104 listDayFormat: 'LL',
15105 noEventsMessage: 'No events to display'
15106 }
15107 });
15108 ViewRegistry_1.defineView('listDay', {
15109 type: 'list',
15110 duration: { days: 1 },
15111 defaults: {
15112 listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header
15113 }
15114 });
15115 ViewRegistry_1.defineView('listWeek', {
15116 type: 'list',
15117 duration: { weeks: 1 },
15118 defaults: {
15119 listDayFormat: 'dddd',
15120 listDayAltFormat: 'LL'
15121 }
15122 });
15123 ViewRegistry_1.defineView('listMonth', {
15124 type: 'list',
15125 duration: { month: 1 },
15126 defaults: {
15127 listDayAltFormat: 'dddd' // day-of-week is nice-to-have
15128 }
15129 });
15130 ViewRegistry_1.defineView('listYear', {
15131 type: 'list',
15132 duration: { year: 1 },
15133 defaults: {
15134 listDayAltFormat: 'dddd' // day-of-week is nice-to-have
15135 }
15136 });
15137
15138
15139 /***/ }),
15140 /* 267 */
15141 /***/ (function(module, exports) {
15142
15143 Object.defineProperty(exports, "__esModule", { value: true });
15144
15145
15146 /***/ })
15147 /******/ ]);
15148 });