22ef94a3b788d825a8690746f5183d12724243a7
[lhc/web/www.git] / www / plugins-dist / organiseur / lib / fullcalendar / fullcalendar.js
1 /*!
2 * FullCalendar v3.9.0
3 * Docs & License: https://fullcalendar.io/
4 * (c) 2018 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 = 236);
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) {
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') {
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>')
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) {
581 return end.diff(start, unit, true);
582 }
583 else if (moment.isDuration(start)) {
584 return start.as(unit);
585 }
586 else {
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)) {
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])) {
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) {
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__(10);
911 var UnzonedRange = /** @class */ (function () {
912 function UnzonedRange(startInput, endInput) {
913 // TODO: move these into footprint.
914 // Especially, doesn't make sense for null startMs/endMs.
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) {
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) {
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__(208);
1062 var Class_1 = __webpack_require__(33);
1063 var EventDefParser_1 = __webpack_require__(49);
1064 var EventSource = /** @class */ (function (_super) {
1065 tslib_1.__extends(EventSource, _super);
1066 // can we do away with calendar? at least for the abstract?
1067 // useful for buildEventDef
1068 function EventSource(calendar) {
1069 var _this = _super.call(this) || this;
1070 _this.calendar = calendar;
1071 _this.className = [];
1072 _this.uid = String(EventSource.uuid++);
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__(14);
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') {
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 /* 10 */
1251 /***/ (function(module, exports, __webpack_require__) {
1252
1253 Object.defineProperty(exports, "__esModule", { value: true });
1254 var moment = __webpack_require__(0);
1255 var $ = __webpack_require__(3);
1256 var util_1 = __webpack_require__(4);
1257 var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
1258 var ambigTimeOrZoneRegex = /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/;
1259 var newMomentProto = moment.fn; // where we will attach our new methods
1260 exports.newMomentProto = newMomentProto;
1261 var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods
1262 exports.oldMomentProto = oldMomentProto;
1263 // tell momentjs to transfer these properties upon clone
1264 var momentProperties = moment.momentProperties;
1265 momentProperties.push('_fullCalendar');
1266 momentProperties.push('_ambigTime');
1267 momentProperties.push('_ambigZone');
1268 /*
1269 Call this if you want Moment's original format method to be used
1270 */
1271 function oldMomentFormat(mom, formatStr) {
1272 return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js
1273 }
1274 exports.oldMomentFormat = oldMomentFormat;
1275 // Creating
1276 // -------------------------------------------------------------------------------------------------
1277 // Creates a new moment, similar to the vanilla moment(...) constructor, but with
1278 // extra features (ambiguous time, enhanced formatting). When given an existing moment,
1279 // it will function as a clone (and retain the zone of the moment). Anything else will
1280 // result in a moment in the local zone.
1281 var momentExt = function () {
1282 return makeMoment(arguments);
1283 };
1284 exports.default = momentExt;
1285 // Sames as momentExt, but forces the resulting moment to be in the UTC timezone.
1286 momentExt.utc = function () {
1287 var mom = makeMoment(arguments, true);
1288 // Force it into UTC because makeMoment doesn't guarantee it
1289 // (if given a pre-existing moment for example)
1290 if (mom.hasTime()) {
1291 mom.utc();
1292 }
1293 return mom;
1294 };
1295 // Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved.
1296 // ISO8601 strings with no timezone offset will become ambiguously zoned.
1297 momentExt.parseZone = function () {
1298 return makeMoment(arguments, true, true);
1299 };
1300 // Builds an enhanced moment from args. When given an existing moment, it clones. When given a
1301 // native Date, or called with no arguments (the current time), the resulting moment will be local.
1302 // Anything else needs to be "parsed" (a string or an array), and will be affected by:
1303 // parseAsUTC - if there is no zone information, should we parse the input in UTC?
1304 // parseZone - if there is zone information, should we force the zone of the moment?
1305 function makeMoment(args, parseAsUTC, parseZone) {
1306 if (parseAsUTC === void 0) { parseAsUTC = false; }
1307 if (parseZone === void 0) { parseZone = false; }
1308 var input = args[0];
1309 var isSingleString = args.length === 1 && typeof input === 'string';
1310 var isAmbigTime;
1311 var isAmbigZone;
1312 var ambigMatch;
1313 var mom;
1314 if (moment.isMoment(input) || util_1.isNativeDate(input) || input === undefined) {
1315 mom = moment.apply(null, args);
1316 }
1317 else {
1318 isAmbigTime = false;
1319 isAmbigZone = false;
1320 if (isSingleString) {
1321 if (ambigDateOfMonthRegex.test(input)) {
1322 // accept strings like '2014-05', but convert to the first of the month
1323 input += '-01';
1324 args = [input]; // for when we pass it on to moment's constructor
1325 isAmbigTime = true;
1326 isAmbigZone = true;
1327 }
1328 else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {
1329 isAmbigTime = !ambigMatch[5]; // no time part?
1330 isAmbigZone = true;
1331 }
1332 }
1333 else if ($.isArray(input)) {
1334 // arrays have no timezone information, so assume ambiguous zone
1335 isAmbigZone = true;
1336 }
1337 // otherwise, probably a string with a format
1338 if (parseAsUTC || isAmbigTime) {
1339 mom = moment.utc.apply(moment, args);
1340 }
1341 else {
1342 mom = moment.apply(null, args);
1343 }
1344 if (isAmbigTime) {
1345 mom._ambigTime = true;
1346 mom._ambigZone = true; // ambiguous time always means ambiguous zone
1347 }
1348 else if (parseZone) {
1349 if (isAmbigZone) {
1350 mom._ambigZone = true;
1351 }
1352 else if (isSingleString) {
1353 mom.utcOffset(input); // if not a valid zone, will assign UTC
1354 }
1355 }
1356 }
1357 mom._fullCalendar = true; // flag for extended functionality
1358 return mom;
1359 }
1360 // Week Number
1361 // -------------------------------------------------------------------------------------------------
1362 // Returns the week number, considering the locale's custom week number calcuation
1363 // `weeks` is an alias for `week`
1364 newMomentProto.week = newMomentProto.weeks = function (input) {
1365 var weekCalc = this._locale._fullCalendar_weekCalc;
1366 if (input == null && typeof weekCalc === 'function') {
1367 return weekCalc(this);
1368 }
1369 else if (weekCalc === 'ISO') {
1370 return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter
1371 }
1372 return oldMomentProto.week.apply(this, arguments); // local getter/setter
1373 };
1374 // Time-of-day
1375 // -------------------------------------------------------------------------------------------------
1376 // GETTER
1377 // Returns a Duration with the hours/minutes/seconds/ms values of the moment.
1378 // If the moment has an ambiguous time, a duration of 00:00 will be returned.
1379 //
1380 // SETTER
1381 // You can supply a Duration, a Moment, or a Duration-like argument.
1382 // When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.
1383 newMomentProto.time = function (time) {
1384 // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.
1385 // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.
1386 if (!this._fullCalendar) {
1387 return oldMomentProto.time.apply(this, arguments);
1388 }
1389 if (time == null) {
1390 return moment.duration({
1391 hours: this.hours(),
1392 minutes: this.minutes(),
1393 seconds: this.seconds(),
1394 milliseconds: this.milliseconds()
1395 });
1396 }
1397 else {
1398 this._ambigTime = false; // mark that the moment now has a time
1399 if (!moment.isDuration(time) && !moment.isMoment(time)) {
1400 time = moment.duration(time);
1401 }
1402 // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).
1403 // Only for Duration times, not Moment times.
1404 var dayHours = 0;
1405 if (moment.isDuration(time)) {
1406 dayHours = Math.floor(time.asDays()) * 24;
1407 }
1408 // We need to set the individual fields.
1409 // Can't use startOf('day') then add duration. In case of DST at start of day.
1410 return this.hours(dayHours + time.hours())
1411 .minutes(time.minutes())
1412 .seconds(time.seconds())
1413 .milliseconds(time.milliseconds());
1414 }
1415 };
1416 // Converts the moment to UTC, stripping out its time-of-day and timezone offset,
1417 // but preserving its YMD. A moment with a stripped time will display no time
1418 // nor timezone offset when .format() is called.
1419 newMomentProto.stripTime = function () {
1420 if (!this._ambigTime) {
1421 this.utc(true); // keepLocalTime=true (for keeping *date* value)
1422 // set time to zero
1423 this.set({
1424 hours: 0,
1425 minutes: 0,
1426 seconds: 0,
1427 ms: 0
1428 });
1429 // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1430 // which clears all ambig flags.
1431 this._ambigTime = true;
1432 this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset
1433 }
1434 return this; // for chaining
1435 };
1436 // Returns if the moment has a non-ambiguous time (boolean)
1437 newMomentProto.hasTime = function () {
1438 return !this._ambigTime;
1439 };
1440 // Timezone
1441 // -------------------------------------------------------------------------------------------------
1442 // Converts the moment to UTC, stripping out its timezone offset, but preserving its
1443 // YMD and time-of-day. A moment with a stripped timezone offset will display no
1444 // timezone offset when .format() is called.
1445 newMomentProto.stripZone = function () {
1446 var wasAmbigTime;
1447 if (!this._ambigZone) {
1448 wasAmbigTime = this._ambigTime;
1449 this.utc(true); // keepLocalTime=true (for keeping date and time values)
1450 // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore
1451 this._ambigTime = wasAmbigTime || false;
1452 // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
1453 // which clears the ambig flags.
1454 this._ambigZone = true;
1455 }
1456 return this; // for chaining
1457 };
1458 // Returns of the moment has a non-ambiguous timezone offset (boolean)
1459 newMomentProto.hasZone = function () {
1460 return !this._ambigZone;
1461 };
1462 // implicitly marks a zone
1463 newMomentProto.local = function (keepLocalTime) {
1464 // for when converting from ambiguously-zoned to local,
1465 // keep the time values when converting from UTC -> local
1466 oldMomentProto.local.call(this, this._ambigZone || keepLocalTime);
1467 // ensure non-ambiguous
1468 // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals
1469 this._ambigTime = false;
1470 this._ambigZone = false;
1471 return this; // for chaining
1472 };
1473 // implicitly marks a zone
1474 newMomentProto.utc = function (keepLocalTime) {
1475 oldMomentProto.utc.call(this, keepLocalTime);
1476 // ensure non-ambiguous
1477 // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals
1478 this._ambigTime = false;
1479 this._ambigZone = false;
1480 return this;
1481 };
1482 // implicitly marks a zone (will probably get called upon .utc() and .local())
1483 newMomentProto.utcOffset = function (tzo) {
1484 if (tzo != null) {
1485 // these assignments needs to happen before the original zone method is called.
1486 // I forget why, something to do with a browser crash.
1487 this._ambigTime = false;
1488 this._ambigZone = false;
1489 }
1490 return oldMomentProto.utcOffset.apply(this, arguments);
1491 };
1492
1493
1494 /***/ }),
1495 /* 11 */
1496 /***/ (function(module, exports, __webpack_require__) {
1497
1498 /*
1499 USAGE:
1500 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
1501 in class:
1502 on: EmitterInterface['on']
1503 one: EmitterInterface['one']
1504 off: EmitterInterface['off']
1505 trigger: EmitterInterface['trigger']
1506 triggerWith: EmitterInterface['triggerWith']
1507 hasHandlers: EmitterInterface['hasHandlers']
1508 after class:
1509 EmitterMixin.mixInto(TheClass)
1510 */
1511 Object.defineProperty(exports, "__esModule", { value: true });
1512 var tslib_1 = __webpack_require__(2);
1513 var $ = __webpack_require__(3);
1514 var Mixin_1 = __webpack_require__(14);
1515 var EmitterMixin = /** @class */ (function (_super) {
1516 tslib_1.__extends(EmitterMixin, _super);
1517 function EmitterMixin() {
1518 return _super !== null && _super.apply(this, arguments) || this;
1519 }
1520 // jQuery-ification via $(this) allows a non-DOM object to have
1521 // the same event handling capabilities (including namespaces).
1522 EmitterMixin.prototype.on = function (types, handler) {
1523 $(this).on(types, this._prepareIntercept(handler));
1524 return this; // for chaining
1525 };
1526 EmitterMixin.prototype.one = function (types, handler) {
1527 $(this).one(types, this._prepareIntercept(handler));
1528 return this; // for chaining
1529 };
1530 EmitterMixin.prototype._prepareIntercept = function (handler) {
1531 // handlers are always called with an "event" object as their first param.
1532 // sneak the `this` context and arguments into the extra parameter object
1533 // and forward them on to the original handler.
1534 var intercept = function (ev, extra) {
1535 return handler.apply(extra.context || this, extra.args || []);
1536 };
1537 // mimick jQuery's internal "proxy" system (risky, I know)
1538 // causing all functions with the same .guid to appear to be the same.
1539 // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448
1540 // this is needed for calling .off with the original non-intercept handler.
1541 if (!handler.guid) {
1542 handler.guid = $.guid++;
1543 }
1544 intercept.guid = handler.guid;
1545 return intercept;
1546 };
1547 EmitterMixin.prototype.off = function (types, handler) {
1548 $(this).off(types, handler);
1549 return this; // for chaining
1550 };
1551 EmitterMixin.prototype.trigger = function (types) {
1552 var args = [];
1553 for (var _i = 1; _i < arguments.length; _i++) {
1554 args[_i - 1] = arguments[_i];
1555 }
1556 // pass in "extra" info to the intercept
1557 $(this).triggerHandler(types, { args: args });
1558 return this; // for chaining
1559 };
1560 EmitterMixin.prototype.triggerWith = function (types, context, args) {
1561 // `triggerHandler` is less reliant on the DOM compared to `trigger`.
1562 // pass in "extra" info to the intercept.
1563 $(this).triggerHandler(types, { context: context, args: args });
1564 return this; // for chaining
1565 };
1566 EmitterMixin.prototype.hasHandlers = function (type) {
1567 var hash = $._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/
1568 return hash && hash[type] && hash[type].length > 0;
1569 };
1570 return EmitterMixin;
1571 }(Mixin_1.default));
1572 exports.default = EmitterMixin;
1573
1574
1575 /***/ }),
1576 /* 12 */
1577 /***/ (function(module, exports) {
1578
1579 Object.defineProperty(exports, "__esModule", { value: true });
1580 /*
1581 Meant to be immutable
1582 */
1583 var ComponentFootprint = /** @class */ (function () {
1584 function ComponentFootprint(unzonedRange, isAllDay) {
1585 this.isAllDay = false; // component can choose to ignore this
1586 this.unzonedRange = unzonedRange;
1587 this.isAllDay = isAllDay;
1588 }
1589 /*
1590 Only works for non-open-ended ranges.
1591 */
1592 ComponentFootprint.prototype.toLegacy = function (calendar) {
1593 return {
1594 start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay),
1595 end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay)
1596 };
1597 };
1598 return ComponentFootprint;
1599 }());
1600 exports.default = ComponentFootprint;
1601
1602
1603 /***/ }),
1604 /* 13 */
1605 /***/ (function(module, exports, __webpack_require__) {
1606
1607 Object.defineProperty(exports, "__esModule", { value: true });
1608 var tslib_1 = __webpack_require__(2);
1609 var EventDef_1 = __webpack_require__(34);
1610 var EventInstance_1 = __webpack_require__(209);
1611 var EventDateProfile_1 = __webpack_require__(17);
1612 var SingleEventDef = /** @class */ (function (_super) {
1613 tslib_1.__extends(SingleEventDef, _super);
1614 function SingleEventDef() {
1615 return _super !== null && _super.apply(this, arguments) || this;
1616 }
1617 /*
1618 Will receive start/end params, but will be ignored.
1619 */
1620 SingleEventDef.prototype.buildInstances = function () {
1621 return [this.buildInstance()];
1622 };
1623 SingleEventDef.prototype.buildInstance = function () {
1624 return new EventInstance_1.default(this, // definition
1625 this.dateProfile);
1626 };
1627 SingleEventDef.prototype.isAllDay = function () {
1628 return this.dateProfile.isAllDay();
1629 };
1630 SingleEventDef.prototype.clone = function () {
1631 var def = _super.prototype.clone.call(this);
1632 def.dateProfile = this.dateProfile;
1633 return def;
1634 };
1635 SingleEventDef.prototype.rezone = function () {
1636 var calendar = this.source.calendar;
1637 var dateProfile = this.dateProfile;
1638 this.dateProfile = new EventDateProfile_1.default(calendar.moment(dateProfile.start), dateProfile.end ? calendar.moment(dateProfile.end) : null, calendar);
1639 };
1640 /*
1641 NOTE: if super-method fails, should still attempt to apply
1642 */
1643 SingleEventDef.prototype.applyManualStandardProps = function (rawProps) {
1644 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
1645 var dateProfile = EventDateProfile_1.default.parse(rawProps, this.source); // returns null on failure
1646 if (dateProfile) {
1647 this.dateProfile = dateProfile;
1648 // make sure `date` shows up in the legacy event objects as-is
1649 if (rawProps.date != null) {
1650 this.miscProps.date = rawProps.date;
1651 }
1652 return superSuccess;
1653 }
1654 else {
1655 return false;
1656 }
1657 };
1658 return SingleEventDef;
1659 }(EventDef_1.default));
1660 exports.default = SingleEventDef;
1661 // Parsing
1662 // ---------------------------------------------------------------------------------------------------------------------
1663 SingleEventDef.defineStandardProps({
1664 start: false,
1665 date: false,
1666 end: false,
1667 allDay: false
1668 });
1669
1670
1671 /***/ }),
1672 /* 14 */
1673 /***/ (function(module, exports) {
1674
1675 Object.defineProperty(exports, "__esModule", { value: true });
1676 var Mixin = /** @class */ (function () {
1677 function Mixin() {
1678 }
1679 Mixin.mixInto = function (destClass) {
1680 var _this = this;
1681 Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
1682 if (!destClass.prototype[name]) {
1683 destClass.prototype[name] = _this.prototype[name];
1684 }
1685 });
1686 };
1687 /*
1688 will override existing methods
1689 TODO: remove! not used anymore
1690 */
1691 Mixin.mixOver = function (destClass) {
1692 var _this = this;
1693 Object.getOwnPropertyNames(this.prototype).forEach(function (name) {
1694 destClass.prototype[name] = _this.prototype[name];
1695 });
1696 };
1697 return Mixin;
1698 }());
1699 exports.default = Mixin;
1700
1701
1702 /***/ }),
1703 /* 15 */
1704 /***/ (function(module, exports) {
1705
1706 Object.defineProperty(exports, "__esModule", { value: true });
1707 var Interaction = /** @class */ (function () {
1708 function Interaction(component) {
1709 this.view = component._getView();
1710 this.component = component;
1711 }
1712 Interaction.prototype.opt = function (name) {
1713 return this.view.opt(name);
1714 };
1715 Interaction.prototype.end = function () {
1716 // subclasses can implement
1717 };
1718 return Interaction;
1719 }());
1720 exports.default = Interaction;
1721
1722
1723 /***/ }),
1724 /* 16 */
1725 /***/ (function(module, exports, __webpack_require__) {
1726
1727 Object.defineProperty(exports, "__esModule", { value: true });
1728 exports.version = '3.9.0';
1729 // When introducing internal API incompatibilities (where fullcalendar plugins would break),
1730 // the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0)
1731 // and the below integer should be incremented.
1732 exports.internalApiVersion = 12;
1733 var util_1 = __webpack_require__(4);
1734 exports.applyAll = util_1.applyAll;
1735 exports.debounce = util_1.debounce;
1736 exports.isInt = util_1.isInt;
1737 exports.htmlEscape = util_1.htmlEscape;
1738 exports.cssToStr = util_1.cssToStr;
1739 exports.proxy = util_1.proxy;
1740 exports.capitaliseFirstLetter = util_1.capitaliseFirstLetter;
1741 exports.getOuterRect = util_1.getOuterRect;
1742 exports.getClientRect = util_1.getClientRect;
1743 exports.getContentRect = util_1.getContentRect;
1744 exports.getScrollbarWidths = util_1.getScrollbarWidths;
1745 exports.preventDefault = util_1.preventDefault;
1746 exports.parseFieldSpecs = util_1.parseFieldSpecs;
1747 exports.compareByFieldSpecs = util_1.compareByFieldSpecs;
1748 exports.compareByFieldSpec = util_1.compareByFieldSpec;
1749 exports.flexibleCompare = util_1.flexibleCompare;
1750 exports.computeGreatestUnit = util_1.computeGreatestUnit;
1751 exports.divideRangeByDuration = util_1.divideRangeByDuration;
1752 exports.divideDurationByDuration = util_1.divideDurationByDuration;
1753 exports.multiplyDuration = util_1.multiplyDuration;
1754 exports.durationHasTime = util_1.durationHasTime;
1755 exports.log = util_1.log;
1756 exports.warn = util_1.warn;
1757 exports.removeExact = util_1.removeExact;
1758 exports.intersectRects = util_1.intersectRects;
1759 var date_formatting_1 = __webpack_require__(47);
1760 exports.formatDate = date_formatting_1.formatDate;
1761 exports.formatRange = date_formatting_1.formatRange;
1762 exports.queryMostGranularFormatUnit = date_formatting_1.queryMostGranularFormatUnit;
1763 var locale_1 = __webpack_require__(31);
1764 exports.datepickerLocale = locale_1.datepickerLocale;
1765 exports.locale = locale_1.locale;
1766 var moment_ext_1 = __webpack_require__(10);
1767 exports.moment = moment_ext_1.default;
1768 var EmitterMixin_1 = __webpack_require__(11);
1769 exports.EmitterMixin = EmitterMixin_1.default;
1770 var ListenerMixin_1 = __webpack_require__(7);
1771 exports.ListenerMixin = ListenerMixin_1.default;
1772 var Model_1 = __webpack_require__(48);
1773 exports.Model = Model_1.default;
1774 var Constraints_1 = __webpack_require__(207);
1775 exports.Constraints = Constraints_1.default;
1776 var UnzonedRange_1 = __webpack_require__(5);
1777 exports.UnzonedRange = UnzonedRange_1.default;
1778 var ComponentFootprint_1 = __webpack_require__(12);
1779 exports.ComponentFootprint = ComponentFootprint_1.default;
1780 var BusinessHourGenerator_1 = __webpack_require__(212);
1781 exports.BusinessHourGenerator = BusinessHourGenerator_1.default;
1782 var EventDef_1 = __webpack_require__(34);
1783 exports.EventDef = EventDef_1.default;
1784 var EventDefMutation_1 = __webpack_require__(37);
1785 exports.EventDefMutation = EventDefMutation_1.default;
1786 var EventSourceParser_1 = __webpack_require__(38);
1787 exports.EventSourceParser = EventSourceParser_1.default;
1788 var EventSource_1 = __webpack_require__(6);
1789 exports.EventSource = EventSource_1.default;
1790 var ThemeRegistry_1 = __webpack_require__(51);
1791 exports.defineThemeSystem = ThemeRegistry_1.defineThemeSystem;
1792 var EventInstanceGroup_1 = __webpack_require__(18);
1793 exports.EventInstanceGroup = EventInstanceGroup_1.default;
1794 var ArrayEventSource_1 = __webpack_require__(52);
1795 exports.ArrayEventSource = ArrayEventSource_1.default;
1796 var FuncEventSource_1 = __webpack_require__(215);
1797 exports.FuncEventSource = FuncEventSource_1.default;
1798 var JsonFeedEventSource_1 = __webpack_require__(216);
1799 exports.JsonFeedEventSource = JsonFeedEventSource_1.default;
1800 var EventFootprint_1 = __webpack_require__(36);
1801 exports.EventFootprint = EventFootprint_1.default;
1802 var Class_1 = __webpack_require__(33);
1803 exports.Class = Class_1.default;
1804 var Mixin_1 = __webpack_require__(14);
1805 exports.Mixin = Mixin_1.default;
1806 var CoordCache_1 = __webpack_require__(53);
1807 exports.CoordCache = CoordCache_1.default;
1808 var DragListener_1 = __webpack_require__(54);
1809 exports.DragListener = DragListener_1.default;
1810 var Promise_1 = __webpack_require__(20);
1811 exports.Promise = Promise_1.default;
1812 var TaskQueue_1 = __webpack_require__(217);
1813 exports.TaskQueue = TaskQueue_1.default;
1814 var RenderQueue_1 = __webpack_require__(218);
1815 exports.RenderQueue = RenderQueue_1.default;
1816 var Scroller_1 = __webpack_require__(39);
1817 exports.Scroller = Scroller_1.default;
1818 var Theme_1 = __webpack_require__(19);
1819 exports.Theme = Theme_1.default;
1820 var DateComponent_1 = __webpack_require__(219);
1821 exports.DateComponent = DateComponent_1.default;
1822 var InteractiveDateComponent_1 = __webpack_require__(40);
1823 exports.InteractiveDateComponent = InteractiveDateComponent_1.default;
1824 var Calendar_1 = __webpack_require__(220);
1825 exports.Calendar = Calendar_1.default;
1826 var View_1 = __webpack_require__(41);
1827 exports.View = View_1.default;
1828 var ViewRegistry_1 = __webpack_require__(22);
1829 exports.defineView = ViewRegistry_1.defineView;
1830 exports.getViewConfig = ViewRegistry_1.getViewConfig;
1831 var DayTableMixin_1 = __webpack_require__(55);
1832 exports.DayTableMixin = DayTableMixin_1.default;
1833 var BusinessHourRenderer_1 = __webpack_require__(56);
1834 exports.BusinessHourRenderer = BusinessHourRenderer_1.default;
1835 var EventRenderer_1 = __webpack_require__(42);
1836 exports.EventRenderer = EventRenderer_1.default;
1837 var FillRenderer_1 = __webpack_require__(57);
1838 exports.FillRenderer = FillRenderer_1.default;
1839 var HelperRenderer_1 = __webpack_require__(58);
1840 exports.HelperRenderer = HelperRenderer_1.default;
1841 var ExternalDropping_1 = __webpack_require__(222);
1842 exports.ExternalDropping = ExternalDropping_1.default;
1843 var EventResizing_1 = __webpack_require__(223);
1844 exports.EventResizing = EventResizing_1.default;
1845 var EventPointing_1 = __webpack_require__(59);
1846 exports.EventPointing = EventPointing_1.default;
1847 var EventDragging_1 = __webpack_require__(224);
1848 exports.EventDragging = EventDragging_1.default;
1849 var DateSelecting_1 = __webpack_require__(225);
1850 exports.DateSelecting = DateSelecting_1.default;
1851 var StandardInteractionsMixin_1 = __webpack_require__(60);
1852 exports.StandardInteractionsMixin = StandardInteractionsMixin_1.default;
1853 var AgendaView_1 = __webpack_require__(226);
1854 exports.AgendaView = AgendaView_1.default;
1855 var TimeGrid_1 = __webpack_require__(227);
1856 exports.TimeGrid = TimeGrid_1.default;
1857 var DayGrid_1 = __webpack_require__(61);
1858 exports.DayGrid = DayGrid_1.default;
1859 var BasicView_1 = __webpack_require__(62);
1860 exports.BasicView = BasicView_1.default;
1861 var MonthView_1 = __webpack_require__(229);
1862 exports.MonthView = MonthView_1.default;
1863 var ListView_1 = __webpack_require__(230);
1864 exports.ListView = ListView_1.default;
1865
1866
1867 /***/ }),
1868 /* 17 */
1869 /***/ (function(module, exports, __webpack_require__) {
1870
1871 Object.defineProperty(exports, "__esModule", { value: true });
1872 var UnzonedRange_1 = __webpack_require__(5);
1873 /*
1874 Meant to be immutable
1875 */
1876 var EventDateProfile = /** @class */ (function () {
1877 function EventDateProfile(start, end, calendar) {
1878 this.start = start;
1879 this.end = end || null;
1880 this.unzonedRange = this.buildUnzonedRange(calendar);
1881 }
1882 /*
1883 Needs an EventSource object
1884 */
1885 EventDateProfile.parse = function (rawProps, source) {
1886 var startInput = rawProps.start || rawProps.date;
1887 var endInput = rawProps.end;
1888 if (!startInput) {
1889 return false;
1890 }
1891 var calendar = source.calendar;
1892 var start = calendar.moment(startInput);
1893 var end = endInput ? calendar.moment(endInput) : null;
1894 var forcedAllDay = rawProps.allDay;
1895 var forceEventDuration = calendar.opt('forceEventDuration');
1896 if (!start.isValid()) {
1897 return false;
1898 }
1899 if (end && (!end.isValid() || !end.isAfter(start))) {
1900 end = null;
1901 }
1902 if (forcedAllDay == null) {
1903 forcedAllDay = source.allDayDefault;
1904 if (forcedAllDay == null) {
1905 forcedAllDay = calendar.opt('allDayDefault');
1906 }
1907 }
1908 if (forcedAllDay === true) {
1909 start.stripTime();
1910 if (end) {
1911 end.stripTime();
1912 }
1913 }
1914 else if (forcedAllDay === false) {
1915 if (!start.hasTime()) {
1916 start.time(0);
1917 }
1918 if (end && !end.hasTime()) {
1919 end.time(0);
1920 }
1921 }
1922 if (!end && forceEventDuration) {
1923 end = calendar.getDefaultEventEnd(!start.hasTime(), start);
1924 }
1925 return new EventDateProfile(start, end, calendar);
1926 };
1927 EventDateProfile.isStandardProp = function (propName) {
1928 return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay';
1929 };
1930 EventDateProfile.prototype.isAllDay = function () {
1931 return !(this.start.hasTime() || (this.end && this.end.hasTime()));
1932 };
1933 /*
1934 Needs a Calendar object
1935 */
1936 EventDateProfile.prototype.buildUnzonedRange = function (calendar) {
1937 var startMs = this.start.clone().stripZone().valueOf();
1938 var endMs = this.getEnd(calendar).stripZone().valueOf();
1939 return new UnzonedRange_1.default(startMs, endMs);
1940 };
1941 /*
1942 Needs a Calendar object
1943 */
1944 EventDateProfile.prototype.getEnd = function (calendar) {
1945 return this.end ?
1946 this.end.clone() :
1947 // derive the end from the start and allDay. compute allDay if necessary
1948 calendar.getDefaultEventEnd(this.isAllDay(), this.start);
1949 };
1950 return EventDateProfile;
1951 }());
1952 exports.default = EventDateProfile;
1953
1954
1955 /***/ }),
1956 /* 18 */
1957 /***/ (function(module, exports, __webpack_require__) {
1958
1959 Object.defineProperty(exports, "__esModule", { value: true });
1960 var UnzonedRange_1 = __webpack_require__(5);
1961 var util_1 = __webpack_require__(35);
1962 var EventRange_1 = __webpack_require__(211);
1963 /*
1964 It's expected that there will be at least one EventInstance,
1965 OR that an explicitEventDef is assigned.
1966 */
1967 var EventInstanceGroup = /** @class */ (function () {
1968 function EventInstanceGroup(eventInstances) {
1969 this.eventInstances = eventInstances || [];
1970 }
1971 EventInstanceGroup.prototype.getAllEventRanges = function (constraintRange) {
1972 if (constraintRange) {
1973 return this.sliceNormalRenderRanges(constraintRange);
1974 }
1975 else {
1976 return this.eventInstances.map(util_1.eventInstanceToEventRange);
1977 }
1978 };
1979 EventInstanceGroup.prototype.sliceRenderRanges = function (constraintRange) {
1980 if (this.isInverse()) {
1981 return this.sliceInverseRenderRanges(constraintRange);
1982 }
1983 else {
1984 return this.sliceNormalRenderRanges(constraintRange);
1985 }
1986 };
1987 EventInstanceGroup.prototype.sliceNormalRenderRanges = function (constraintRange) {
1988 var eventInstances = this.eventInstances;
1989 var i;
1990 var eventInstance;
1991 var slicedRange;
1992 var slicedEventRanges = [];
1993 for (i = 0; i < eventInstances.length; i++) {
1994 eventInstance = eventInstances[i];
1995 slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange);
1996 if (slicedRange) {
1997 slicedEventRanges.push(new EventRange_1.default(slicedRange, eventInstance.def, eventInstance));
1998 }
1999 }
2000 return slicedEventRanges;
2001 };
2002 EventInstanceGroup.prototype.sliceInverseRenderRanges = function (constraintRange) {
2003 var unzonedRanges = this.eventInstances.map(util_1.eventInstanceToUnzonedRange);
2004 var ownerDef = this.getEventDef();
2005 unzonedRanges = UnzonedRange_1.default.invertRanges(unzonedRanges, constraintRange);
2006 return unzonedRanges.map(function (unzonedRange) {
2007 return new EventRange_1.default(unzonedRange, ownerDef); // don't give an EventInstance
2008 });
2009 };
2010 EventInstanceGroup.prototype.isInverse = function () {
2011 return this.getEventDef().hasInverseRendering();
2012 };
2013 EventInstanceGroup.prototype.getEventDef = function () {
2014 return this.explicitEventDef || this.eventInstances[0].def;
2015 };
2016 return EventInstanceGroup;
2017 }());
2018 exports.default = EventInstanceGroup;
2019
2020
2021 /***/ }),
2022 /* 19 */
2023 /***/ (function(module, exports, __webpack_require__) {
2024
2025 Object.defineProperty(exports, "__esModule", { value: true });
2026 var $ = __webpack_require__(3);
2027 var Theme = /** @class */ (function () {
2028 function Theme(optionsManager) {
2029 this.optionsManager = optionsManager;
2030 this.processIconOverride();
2031 }
2032 Theme.prototype.processIconOverride = function () {
2033 if (this.iconOverrideOption) {
2034 this.setIconOverride(this.optionsManager.get(this.iconOverrideOption));
2035 }
2036 };
2037 Theme.prototype.setIconOverride = function (iconOverrideHash) {
2038 var iconClassesCopy;
2039 var buttonName;
2040 if ($.isPlainObject(iconOverrideHash)) {
2041 iconClassesCopy = $.extend({}, this.iconClasses);
2042 for (buttonName in iconOverrideHash) {
2043 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
2044 }
2045 this.iconClasses = iconClassesCopy;
2046 }
2047 else if (iconOverrideHash === false) {
2048 this.iconClasses = {};
2049 }
2050 };
2051 Theme.prototype.applyIconOverridePrefix = function (className) {
2052 var prefix = this.iconOverridePrefix;
2053 if (prefix && className.indexOf(prefix) !== 0) {
2054 className = prefix + className;
2055 }
2056 return className;
2057 };
2058 Theme.prototype.getClass = function (key) {
2059 return this.classes[key] || '';
2060 };
2061 Theme.prototype.getIconClass = function (buttonName) {
2062 var className = this.iconClasses[buttonName];
2063 if (className) {
2064 return this.baseIconClass + ' ' + className;
2065 }
2066 return '';
2067 };
2068 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) {
2069 var className;
2070 if (this.iconOverrideCustomButtonOption) {
2071 className = customButtonProps[this.iconOverrideCustomButtonOption];
2072 if (className) {
2073 return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
2074 }
2075 }
2076 return '';
2077 };
2078 return Theme;
2079 }());
2080 exports.default = Theme;
2081 Theme.prototype.classes = {};
2082 Theme.prototype.iconClasses = {};
2083 Theme.prototype.baseIconClass = '';
2084 Theme.prototype.iconOverridePrefix = '';
2085
2086
2087 /***/ }),
2088 /* 20 */
2089 /***/ (function(module, exports, __webpack_require__) {
2090
2091 Object.defineProperty(exports, "__esModule", { value: true });
2092 var $ = __webpack_require__(3);
2093 var PromiseStub = {
2094 construct: function (executor) {
2095 var deferred = $.Deferred();
2096 var promise = deferred.promise();
2097 if (typeof executor === 'function') {
2098 executor(function (val) {
2099 deferred.resolve(val);
2100 attachImmediatelyResolvingThen(promise, val);
2101 }, function () {
2102 deferred.reject();
2103 attachImmediatelyRejectingThen(promise);
2104 });
2105 }
2106 return promise;
2107 },
2108 resolve: function (val) {
2109 var deferred = $.Deferred().resolve(val);
2110 var promise = deferred.promise();
2111 attachImmediatelyResolvingThen(promise, val);
2112 return promise;
2113 },
2114 reject: function () {
2115 var deferred = $.Deferred().reject();
2116 var promise = deferred.promise();
2117 attachImmediatelyRejectingThen(promise);
2118 return promise;
2119 }
2120 };
2121 exports.default = PromiseStub;
2122 function attachImmediatelyResolvingThen(promise, val) {
2123 promise.then = function (onResolve) {
2124 if (typeof onResolve === 'function') {
2125 return PromiseStub.resolve(onResolve(val));
2126 }
2127 return promise;
2128 };
2129 }
2130 function attachImmediatelyRejectingThen(promise) {
2131 promise.then = function (onResolve, onReject) {
2132 if (typeof onReject === 'function') {
2133 onReject();
2134 }
2135 return promise;
2136 };
2137 }
2138
2139
2140 /***/ }),
2141 /* 21 */
2142 /***/ (function(module, exports, __webpack_require__) {
2143
2144 Object.defineProperty(exports, "__esModule", { value: true });
2145 var $ = __webpack_require__(3);
2146 var exportHooks = __webpack_require__(16);
2147 var EmitterMixin_1 = __webpack_require__(11);
2148 var ListenerMixin_1 = __webpack_require__(7);
2149 exportHooks.touchMouseIgnoreWait = 500;
2150 var globalEmitter = null;
2151 var neededCount = 0;
2152 /*
2153 Listens to document and window-level user-interaction events, like touch events and mouse events,
2154 and fires these events as-is to whoever is observing a GlobalEmitter.
2155 Best when used as a singleton via GlobalEmitter.get()
2156
2157 Normalizes mouse/touch events. For examples:
2158 - ignores the the simulated mouse events that happen after a quick tap: mousemove+mousedown+mouseup+click
2159 - compensates for various buggy scenarios where a touchend does not fire
2160 */
2161 var GlobalEmitter = /** @class */ (function () {
2162 function GlobalEmitter() {
2163 this.isTouching = false;
2164 this.mouseIgnoreDepth = 0;
2165 }
2166 // gets the singleton
2167 GlobalEmitter.get = function () {
2168 if (!globalEmitter) {
2169 globalEmitter = new GlobalEmitter();
2170 globalEmitter.bind();
2171 }
2172 return globalEmitter;
2173 };
2174 // called when an object knows it will need a GlobalEmitter in the near future.
2175 GlobalEmitter.needed = function () {
2176 GlobalEmitter.get(); // ensures globalEmitter
2177 neededCount++;
2178 };
2179 // called when the object that originally called needed() doesn't need a GlobalEmitter anymore.
2180 GlobalEmitter.unneeded = function () {
2181 neededCount--;
2182 if (!neededCount) {
2183 globalEmitter.unbind();
2184 globalEmitter = null;
2185 }
2186 };
2187 GlobalEmitter.prototype.bind = function () {
2188 var _this = this;
2189 this.listenTo($(document), {
2190 touchstart: this.handleTouchStart,
2191 touchcancel: this.handleTouchCancel,
2192 touchend: this.handleTouchEnd,
2193 mousedown: this.handleMouseDown,
2194 mousemove: this.handleMouseMove,
2195 mouseup: this.handleMouseUp,
2196 click: this.handleClick,
2197 selectstart: this.handleSelectStart,
2198 contextmenu: this.handleContextMenu
2199 });
2200 // because we need to call preventDefault
2201 // because https://www.chromestatus.com/features/5093566007214080
2202 // TODO: investigate performance because this is a global handler
2203 window.addEventListener('touchmove', this.handleTouchMoveProxy = function (ev) {
2204 _this.handleTouchMove($.Event(ev));
2205 }, { passive: false } // allows preventDefault()
2206 );
2207 // attach a handler to get called when ANY scroll action happens on the page.
2208 // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
2209 // http://stackoverflow.com/a/32954565/96342
2210 window.addEventListener('scroll', this.handleScrollProxy = function (ev) {
2211 _this.handleScroll($.Event(ev));
2212 }, true // useCapture
2213 );
2214 };
2215 GlobalEmitter.prototype.unbind = function () {
2216 this.stopListeningTo($(document));
2217 window.removeEventListener('touchmove', this.handleTouchMoveProxy);
2218 window.removeEventListener('scroll', this.handleScrollProxy, true // useCapture
2219 );
2220 };
2221 // Touch Handlers
2222 // -----------------------------------------------------------------------------------------------------------------
2223 GlobalEmitter.prototype.handleTouchStart = function (ev) {
2224 // if a previous touch interaction never ended with a touchend, then implicitly end it,
2225 // but since a new touch interaction is about to begin, don't start the mouse ignore period.
2226 this.stopTouch(ev, true); // skipMouseIgnore=true
2227 this.isTouching = true;
2228 this.trigger('touchstart', ev);
2229 };
2230 GlobalEmitter.prototype.handleTouchMove = function (ev) {
2231 if (this.isTouching) {
2232 this.trigger('touchmove', ev);
2233 }
2234 };
2235 GlobalEmitter.prototype.handleTouchCancel = function (ev) {
2236 if (this.isTouching) {
2237 this.trigger('touchcancel', ev);
2238 // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both.
2239 // If touchend fires later, it won't have any effect b/c isTouching will be false.
2240 this.stopTouch(ev);
2241 }
2242 };
2243 GlobalEmitter.prototype.handleTouchEnd = function (ev) {
2244 this.stopTouch(ev);
2245 };
2246 // Mouse Handlers
2247 // -----------------------------------------------------------------------------------------------------------------
2248 GlobalEmitter.prototype.handleMouseDown = function (ev) {
2249 if (!this.shouldIgnoreMouse()) {
2250 this.trigger('mousedown', ev);
2251 }
2252 };
2253 GlobalEmitter.prototype.handleMouseMove = function (ev) {
2254 if (!this.shouldIgnoreMouse()) {
2255 this.trigger('mousemove', ev);
2256 }
2257 };
2258 GlobalEmitter.prototype.handleMouseUp = function (ev) {
2259 if (!this.shouldIgnoreMouse()) {
2260 this.trigger('mouseup', ev);
2261 }
2262 };
2263 GlobalEmitter.prototype.handleClick = function (ev) {
2264 if (!this.shouldIgnoreMouse()) {
2265 this.trigger('click', ev);
2266 }
2267 };
2268 // Misc Handlers
2269 // -----------------------------------------------------------------------------------------------------------------
2270 GlobalEmitter.prototype.handleSelectStart = function (ev) {
2271 this.trigger('selectstart', ev);
2272 };
2273 GlobalEmitter.prototype.handleContextMenu = function (ev) {
2274 this.trigger('contextmenu', ev);
2275 };
2276 GlobalEmitter.prototype.handleScroll = function (ev) {
2277 this.trigger('scroll', ev);
2278 };
2279 // Utils
2280 // -----------------------------------------------------------------------------------------------------------------
2281 GlobalEmitter.prototype.stopTouch = function (ev, skipMouseIgnore) {
2282 if (skipMouseIgnore === void 0) { skipMouseIgnore = false; }
2283 if (this.isTouching) {
2284 this.isTouching = false;
2285 this.trigger('touchend', ev);
2286 if (!skipMouseIgnore) {
2287 this.startTouchMouseIgnore();
2288 }
2289 }
2290 };
2291 GlobalEmitter.prototype.startTouchMouseIgnore = function () {
2292 var _this = this;
2293 var wait = exportHooks.touchMouseIgnoreWait;
2294 if (wait) {
2295 this.mouseIgnoreDepth++;
2296 setTimeout(function () {
2297 _this.mouseIgnoreDepth--;
2298 }, wait);
2299 }
2300 };
2301 GlobalEmitter.prototype.shouldIgnoreMouse = function () {
2302 return this.isTouching || Boolean(this.mouseIgnoreDepth);
2303 };
2304 return GlobalEmitter;
2305 }());
2306 exports.default = GlobalEmitter;
2307 ListenerMixin_1.default.mixInto(GlobalEmitter);
2308 EmitterMixin_1.default.mixInto(GlobalEmitter);
2309
2310
2311 /***/ }),
2312 /* 22 */
2313 /***/ (function(module, exports, __webpack_require__) {
2314
2315 Object.defineProperty(exports, "__esModule", { value: true });
2316 var exportHooks = __webpack_require__(16);
2317 exports.viewHash = {};
2318 exportHooks.views = exports.viewHash;
2319 function defineView(viewName, viewConfig) {
2320 exports.viewHash[viewName] = viewConfig;
2321 }
2322 exports.defineView = defineView;
2323 function getViewConfig(viewName) {
2324 return exports.viewHash[viewName];
2325 }
2326 exports.getViewConfig = getViewConfig;
2327
2328
2329 /***/ }),
2330 /* 23 */
2331 /***/ (function(module, exports, __webpack_require__) {
2332
2333 Object.defineProperty(exports, "__esModule", { value: true });
2334 var tslib_1 = __webpack_require__(2);
2335 var util_1 = __webpack_require__(4);
2336 var DragListener_1 = __webpack_require__(54);
2337 /* Tracks mouse movements over a component and raises events about which hit the mouse is over.
2338 ------------------------------------------------------------------------------------------------------------------------
2339 options:
2340 - subjectEl
2341 - subjectCenter
2342 */
2343 var HitDragListener = /** @class */ (function (_super) {
2344 tslib_1.__extends(HitDragListener, _super);
2345 function HitDragListener(component, options) {
2346 var _this = _super.call(this, options) || this;
2347 _this.component = component;
2348 return _this;
2349 }
2350 // Called when drag listening starts (but a real drag has not necessarily began).
2351 // ev might be undefined if dragging was started manually.
2352 HitDragListener.prototype.handleInteractionStart = function (ev) {
2353 var subjectEl = this.subjectEl;
2354 var subjectRect;
2355 var origPoint;
2356 var point;
2357 this.component.hitsNeeded();
2358 this.computeScrollBounds(); // for autoscroll
2359 if (ev) {
2360 origPoint = { left: util_1.getEvX(ev), top: util_1.getEvY(ev) };
2361 point = origPoint;
2362 // constrain the point to bounds of the element being dragged
2363 if (subjectEl) {
2364 subjectRect = util_1.getOuterRect(subjectEl); // used for centering as well
2365 point = util_1.constrainPoint(point, subjectRect);
2366 }
2367 this.origHit = this.queryHit(point.left, point.top);
2368 // treat the center of the subject as the collision point?
2369 if (subjectEl && this.options.subjectCenter) {
2370 // only consider the area the subject overlaps the hit. best for large subjects.
2371 // TODO: skip this if hit didn't supply left/right/top/bottom
2372 if (this.origHit) {
2373 subjectRect = util_1.intersectRects(this.origHit, subjectRect) ||
2374 subjectRect; // in case there is no intersection
2375 }
2376 point = util_1.getRectCenter(subjectRect);
2377 }
2378 this.coordAdjust = util_1.diffPoints(point, origPoint); // point - origPoint
2379 }
2380 else {
2381 this.origHit = null;
2382 this.coordAdjust = null;
2383 }
2384 // call the super-method. do it after origHit has been computed
2385 _super.prototype.handleInteractionStart.call(this, ev);
2386 };
2387 // Called when the actual drag has started
2388 HitDragListener.prototype.handleDragStart = function (ev) {
2389 var hit;
2390 _super.prototype.handleDragStart.call(this, ev);
2391 // might be different from this.origHit if the min-distance is large
2392 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev));
2393 // report the initial hit the mouse is over
2394 // especially important if no min-distance and drag starts immediately
2395 if (hit) {
2396 this.handleHitOver(hit);
2397 }
2398 };
2399 // Called when the drag moves
2400 HitDragListener.prototype.handleDrag = function (dx, dy, ev) {
2401 var hit;
2402 _super.prototype.handleDrag.call(this, dx, dy, ev);
2403 hit = this.queryHit(util_1.getEvX(ev), util_1.getEvY(ev));
2404 if (!isHitsEqual(hit, this.hit)) {
2405 if (this.hit) {
2406 this.handleHitOut();
2407 }
2408 if (hit) {
2409 this.handleHitOver(hit);
2410 }
2411 }
2412 };
2413 // Called when dragging has been stopped
2414 HitDragListener.prototype.handleDragEnd = function (ev) {
2415 this.handleHitDone();
2416 _super.prototype.handleDragEnd.call(this, ev);
2417 };
2418 // Called when a the mouse has just moved over a new hit
2419 HitDragListener.prototype.handleHitOver = function (hit) {
2420 var isOrig = isHitsEqual(hit, this.origHit);
2421 this.hit = hit;
2422 this.trigger('hitOver', this.hit, isOrig, this.origHit);
2423 };
2424 // Called when the mouse has just moved out of a hit
2425 HitDragListener.prototype.handleHitOut = function () {
2426 if (this.hit) {
2427 this.trigger('hitOut', this.hit);
2428 this.handleHitDone();
2429 this.hit = null;
2430 }
2431 };
2432 // Called after a hitOut. Also called before a dragStop
2433 HitDragListener.prototype.handleHitDone = function () {
2434 if (this.hit) {
2435 this.trigger('hitDone', this.hit);
2436 }
2437 };
2438 // Called when the interaction ends, whether there was a real drag or not
2439 HitDragListener.prototype.handleInteractionEnd = function (ev, isCancelled) {
2440 _super.prototype.handleInteractionEnd.call(this, ev, isCancelled);
2441 this.origHit = null;
2442 this.hit = null;
2443 this.component.hitsNotNeeded();
2444 };
2445 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
2446 HitDragListener.prototype.handleScrollEnd = function () {
2447 _super.prototype.handleScrollEnd.call(this);
2448 // hits' absolute positions will be in new places after a user's scroll.
2449 // HACK for recomputing.
2450 if (this.isDragging) {
2451 this.component.releaseHits();
2452 this.component.prepareHits();
2453 }
2454 };
2455 // Gets the hit underneath the coordinates for the given mouse event
2456 HitDragListener.prototype.queryHit = function (left, top) {
2457 if (this.coordAdjust) {
2458 left += this.coordAdjust.left;
2459 top += this.coordAdjust.top;
2460 }
2461 return this.component.queryHit(left, top);
2462 };
2463 return HitDragListener;
2464 }(DragListener_1.default));
2465 exports.default = HitDragListener;
2466 // Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.
2467 // Two null values will be considered equal, as two "out of the component" states are the same.
2468 function isHitsEqual(hit0, hit1) {
2469 if (!hit0 && !hit1) {
2470 return true;
2471 }
2472 if (hit0 && hit1) {
2473 return hit0.component === hit1.component &&
2474 isHitPropsWithin(hit0, hit1) &&
2475 isHitPropsWithin(hit1, hit0); // ensures all props are identical
2476 }
2477 return false;
2478 }
2479 // Returns true if all of subHit's non-standard properties are within superHit
2480 function isHitPropsWithin(subHit, superHit) {
2481 for (var propName in subHit) {
2482 if (!/^(component|left|right|top|bottom)$/.test(propName)) {
2483 if (subHit[propName] !== superHit[propName]) {
2484 return false;
2485 }
2486 }
2487 }
2488 return true;
2489 }
2490
2491
2492 /***/ }),
2493 /* 24 */,
2494 /* 25 */,
2495 /* 26 */,
2496 /* 27 */,
2497 /* 28 */,
2498 /* 29 */,
2499 /* 30 */,
2500 /* 31 */
2501 /***/ (function(module, exports, __webpack_require__) {
2502
2503 Object.defineProperty(exports, "__esModule", { value: true });
2504 var $ = __webpack_require__(3);
2505 var moment = __webpack_require__(0);
2506 var exportHooks = __webpack_require__(16);
2507 var options_1 = __webpack_require__(32);
2508 var util_1 = __webpack_require__(4);
2509 exports.localeOptionHash = {};
2510 exportHooks.locales = exports.localeOptionHash;
2511 // NOTE: can't guarantee any of these computations will run because not every locale has datepicker
2512 // configs, so make sure there are English fallbacks for these in the defaults file.
2513 var dpComputableOptions = {
2514 buttonText: function (dpOptions) {
2515 return {
2516 // the translations sometimes wrongly contain HTML entities
2517 prev: util_1.stripHtmlEntities(dpOptions.prevText),
2518 next: util_1.stripHtmlEntities(dpOptions.nextText),
2519 today: util_1.stripHtmlEntities(dpOptions.currentText)
2520 };
2521 },
2522 // Produces format strings like "MMMM YYYY" -> "September 2014"
2523 monthYearFormat: function (dpOptions) {
2524 return dpOptions.showMonthAfterYear ?
2525 'YYYY[' + dpOptions.yearSuffix + '] MMMM' :
2526 'MMMM YYYY[' + dpOptions.yearSuffix + ']';
2527 }
2528 };
2529 var momComputableOptions = {
2530 // Produces format strings like "ddd M/D" -> "Fri 9/15"
2531 dayOfMonthFormat: function (momOptions, fcOptions) {
2532 var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY"
2533 // strip the year off the edge, as well as other misc non-whitespace chars
2534 format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '');
2535 if (fcOptions.isRTL) {
2536 format += ' ddd'; // for RTL, add day-of-week to end
2537 }
2538 else {
2539 format = 'ddd ' + format; // for LTR, add day-of-week to beginning
2540 }
2541 return format;
2542 },
2543 // Produces format strings like "h:mma" -> "6:00pm"
2544 mediumTimeFormat: function (momOptions) {
2545 return momOptions.longDateFormat('LT')
2546 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2547 },
2548 // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
2549 smallTimeFormat: function (momOptions) {
2550 return momOptions.longDateFormat('LT')
2551 .replace(':mm', '(:mm)')
2552 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2553 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2554 },
2555 // Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
2556 extraSmallTimeFormat: function (momOptions) {
2557 return momOptions.longDateFormat('LT')
2558 .replace(':mm', '(:mm)')
2559 .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
2560 .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
2561 },
2562 // Produces format strings like "ha" / "H" -> "6pm" / "18"
2563 hourFormat: function (momOptions) {
2564 return momOptions.longDateFormat('LT')
2565 .replace(':mm', '')
2566 .replace(/(\Wmm)$/, '') // like above, but for foreign locales
2567 .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
2568 },
2569 // Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
2570 noMeridiemTimeFormat: function (momOptions) {
2571 return momOptions.longDateFormat('LT')
2572 .replace(/\s*a$/i, ''); // remove trailing AM/PM
2573 }
2574 };
2575 // options that should be computed off live calendar options (considers override options)
2576 // TODO: best place for this? related to locale?
2577 // TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it
2578 var instanceComputableOptions = {
2579 // Produces format strings for results like "Mo 16"
2580 smallDayDateFormat: function (options) {
2581 return options.isRTL ?
2582 'D dd' :
2583 'dd D';
2584 },
2585 // Produces format strings for results like "Wk 5"
2586 weekFormat: function (options) {
2587 return options.isRTL ?
2588 'w[ ' + options.weekNumberTitle + ']' :
2589 '[' + options.weekNumberTitle + ' ]w';
2590 },
2591 // Produces format strings for results like "Wk5"
2592 smallWeekFormat: function (options) {
2593 return options.isRTL ?
2594 'w[' + options.weekNumberTitle + ']' :
2595 '[' + options.weekNumberTitle + ']w';
2596 }
2597 };
2598 // TODO: make these computable properties in optionsManager
2599 function populateInstanceComputableOptions(options) {
2600 $.each(instanceComputableOptions, function (name, func) {
2601 if (options[name] == null) {
2602 options[name] = func(options);
2603 }
2604 });
2605 }
2606 exports.populateInstanceComputableOptions = populateInstanceComputableOptions;
2607 // Initialize jQuery UI datepicker translations while using some of the translations
2608 // Will set this as the default locales for datepicker.
2609 function datepickerLocale(localeCode, dpLocaleCode, dpOptions) {
2610 // get the FullCalendar internal option hash for this locale. create if necessary
2611 var fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {});
2612 // transfer some simple options from datepicker to fc
2613 fcOptions.isRTL = dpOptions.isRTL;
2614 fcOptions.weekNumberTitle = dpOptions.weekHeader;
2615 // compute some more complex options from datepicker
2616 $.each(dpComputableOptions, function (name, func) {
2617 fcOptions[name] = func(dpOptions);
2618 });
2619 var jqDatePicker = $.datepicker;
2620 // is jQuery UI Datepicker is on the page?
2621 if (jqDatePicker) {
2622 // Register the locale data.
2623 // FullCalendar and MomentJS use locale codes like "pt-br" but Datepicker
2624 // does it like "pt-BR" or if it doesn't have the locale, maybe just "pt".
2625 // Make an alias so the locale can be referenced either way.
2626 jqDatePicker.regional[dpLocaleCode] =
2627 jqDatePicker.regional[localeCode] = // alias
2628 dpOptions;
2629 // Alias 'en' to the default locale data. Do this every time.
2630 jqDatePicker.regional.en = jqDatePicker.regional[''];
2631 // Set as Datepicker's global defaults.
2632 jqDatePicker.setDefaults(dpOptions);
2633 }
2634 }
2635 exports.datepickerLocale = datepickerLocale;
2636 // Sets FullCalendar-specific translations. Will set the locales as the global default.
2637 function locale(localeCode, newFcOptions) {
2638 var fcOptions;
2639 var momOptions;
2640 // get the FullCalendar internal option hash for this locale. create if necessary
2641 fcOptions = exports.localeOptionHash[localeCode] || (exports.localeOptionHash[localeCode] = {});
2642 // provided new options for this locales? merge them in
2643 if (newFcOptions) {
2644 fcOptions = exports.localeOptionHash[localeCode] = options_1.mergeOptions([fcOptions, newFcOptions]);
2645 }
2646 // compute locale options that weren't defined.
2647 // always do this. newFcOptions can be undefined when initializing from i18n file,
2648 // so no way to tell if this is an initialization or a default-setting.
2649 momOptions = getMomentLocaleData(localeCode); // will fall back to en
2650 $.each(momComputableOptions, function (name, func) {
2651 if (fcOptions[name] == null) {
2652 fcOptions[name] = (func)(momOptions, fcOptions);
2653 }
2654 });
2655 // set it as the default locale for FullCalendar
2656 options_1.globalDefaults.locale = localeCode;
2657 }
2658 exports.locale = locale;
2659 // Returns moment's internal locale data. If doesn't exist, returns English.
2660 function getMomentLocaleData(localeCode) {
2661 return moment.localeData(localeCode) || moment.localeData('en');
2662 }
2663 exports.getMomentLocaleData = getMomentLocaleData;
2664 // Initialize English by forcing computation of moment-derived options.
2665 // Also, sets it as the default.
2666 locale('en', options_1.englishDefaults);
2667
2668
2669 /***/ }),
2670 /* 32 */
2671 /***/ (function(module, exports, __webpack_require__) {
2672
2673 Object.defineProperty(exports, "__esModule", { value: true });
2674 var util_1 = __webpack_require__(4);
2675 exports.globalDefaults = {
2676 titleRangeSeparator: ' \u2013 ',
2677 monthYearFormat: 'MMMM YYYY',
2678 defaultTimedEventDuration: '02:00:00',
2679 defaultAllDayEventDuration: { days: 1 },
2680 forceEventDuration: false,
2681 nextDayThreshold: '09:00:00',
2682 // display
2683 columnHeader: true,
2684 defaultView: 'month',
2685 aspectRatio: 1.35,
2686 header: {
2687 left: 'title',
2688 center: '',
2689 right: 'today prev,next'
2690 },
2691 weekends: true,
2692 weekNumbers: false,
2693 weekNumberTitle: 'W',
2694 weekNumberCalculation: 'local',
2695 // editable: false,
2696 // nowIndicator: false,
2697 scrollTime: '06:00:00',
2698 minTime: '00:00:00',
2699 maxTime: '24:00:00',
2700 showNonCurrentDates: true,
2701 // event ajax
2702 lazyFetching: true,
2703 startParam: 'start',
2704 endParam: 'end',
2705 timezoneParam: 'timezone',
2706 timezone: false,
2707 // allDayDefault: undefined,
2708 // locale
2709 locale: null,
2710 isRTL: false,
2711 buttonText: {
2712 prev: 'prev',
2713 next: 'next',
2714 prevYear: 'prev year',
2715 nextYear: 'next year',
2716 year: 'year',
2717 today: 'today',
2718 month: 'month',
2719 week: 'week',
2720 day: 'day'
2721 },
2722 // buttonIcons: null,
2723 allDayText: 'all-day',
2724 // allows setting a min-height to the event segment to prevent short events overlapping each other
2725 agendaEventMinHeight: 0,
2726 // jquery-ui theming
2727 theme: false,
2728 // themeButtonIcons: null,
2729 // eventResizableFromStart: false,
2730 dragOpacity: .75,
2731 dragRevertDuration: 500,
2732 dragScroll: true,
2733 // selectable: false,
2734 unselectAuto: true,
2735 // selectMinDistance: 0,
2736 dropAccept: '*',
2737 eventOrder: 'title',
2738 // eventRenderWait: null,
2739 eventLimit: false,
2740 eventLimitText: 'more',
2741 eventLimitClick: 'popover',
2742 dayPopoverFormat: 'LL',
2743 handleWindowResize: true,
2744 windowResizeDelay: 100,
2745 longPressDelay: 1000
2746 };
2747 exports.englishDefaults = {
2748 dayPopoverFormat: 'dddd, MMMM D'
2749 };
2750 exports.rtlDefaults = {
2751 header: {
2752 left: 'next,prev today',
2753 center: '',
2754 right: 'title'
2755 },
2756 buttonIcons: {
2757 prev: 'right-single-arrow',
2758 next: 'left-single-arrow',
2759 prevYear: 'right-double-arrow',
2760 nextYear: 'left-double-arrow'
2761 },
2762 themeButtonIcons: {
2763 prev: 'circle-triangle-e',
2764 next: 'circle-triangle-w',
2765 nextYear: 'seek-prev',
2766 prevYear: 'seek-next'
2767 }
2768 };
2769 var complexOptions = [
2770 'header',
2771 'footer',
2772 'buttonText',
2773 'buttonIcons',
2774 'themeButtonIcons'
2775 ];
2776 // Merges an array of option objects into a single object
2777 function mergeOptions(optionObjs) {
2778 return util_1.mergeProps(optionObjs, complexOptions);
2779 }
2780 exports.mergeOptions = mergeOptions;
2781
2782
2783 /***/ }),
2784 /* 33 */
2785 /***/ (function(module, exports, __webpack_require__) {
2786
2787 Object.defineProperty(exports, "__esModule", { value: true });
2788 var tslib_1 = __webpack_require__(2);
2789 var util_1 = __webpack_require__(4);
2790 // Class that all other classes will inherit from
2791 var Class = /** @class */ (function () {
2792 function Class() {
2793 }
2794 // Called on a class to create a subclass.
2795 // LIMITATION: cannot provide a constructor!
2796 Class.extend = function (members) {
2797 var SubClass = /** @class */ (function (_super) {
2798 tslib_1.__extends(SubClass, _super);
2799 function SubClass() {
2800 return _super !== null && _super.apply(this, arguments) || this;
2801 }
2802 return SubClass;
2803 }(this));
2804 util_1.copyOwnProps(members, SubClass.prototype);
2805 return SubClass;
2806 };
2807 // Adds new member variables/methods to the class's prototype.
2808 // Can be called with another class, or a plain object hash containing new members.
2809 Class.mixin = function (members) {
2810 util_1.copyOwnProps(members, this.prototype);
2811 };
2812 return Class;
2813 }());
2814 exports.default = Class;
2815
2816
2817 /***/ }),
2818 /* 34 */
2819 /***/ (function(module, exports, __webpack_require__) {
2820
2821 Object.defineProperty(exports, "__esModule", { value: true });
2822 var $ = __webpack_require__(3);
2823 var ParsableModelMixin_1 = __webpack_require__(208);
2824 var EventDef = /** @class */ (function () {
2825 function EventDef(source) {
2826 this.source = source;
2827 this.className = [];
2828 this.miscProps = {};
2829 }
2830 EventDef.parse = function (rawInput, source) {
2831 var def = new this(source);
2832 if (def.applyProps(rawInput)) {
2833 return def;
2834 }
2835 return false;
2836 };
2837 EventDef.normalizeId = function (id) {
2838 return String(id);
2839 };
2840 EventDef.generateId = function () {
2841 return '_fc' + (EventDef.uuid++);
2842 };
2843 EventDef.prototype.clone = function () {
2844 var copy = new this.constructor(this.source);
2845 copy.id = this.id;
2846 copy.rawId = this.rawId;
2847 copy.uid = this.uid; // not really unique anymore :(
2848 EventDef.copyVerbatimStandardProps(this, copy);
2849 copy.className = this.className.slice(); // copy
2850 copy.miscProps = $.extend({}, this.miscProps);
2851 return copy;
2852 };
2853 EventDef.prototype.hasInverseRendering = function () {
2854 return this.getRendering() === 'inverse-background';
2855 };
2856 EventDef.prototype.hasBgRendering = function () {
2857 var rendering = this.getRendering();
2858 return rendering === 'inverse-background' || rendering === 'background';
2859 };
2860 EventDef.prototype.getRendering = function () {
2861 if (this.rendering != null) {
2862 return this.rendering;
2863 }
2864 return this.source.rendering;
2865 };
2866 EventDef.prototype.getConstraint = function () {
2867 if (this.constraint != null) {
2868 return this.constraint;
2869 }
2870 if (this.source.constraint != null) {
2871 return this.source.constraint;
2872 }
2873 return this.source.calendar.opt('eventConstraint'); // what about View option?
2874 };
2875 EventDef.prototype.getOverlap = function () {
2876 if (this.overlap != null) {
2877 return this.overlap;
2878 }
2879 if (this.source.overlap != null) {
2880 return this.source.overlap;
2881 }
2882 return this.source.calendar.opt('eventOverlap'); // what about View option?
2883 };
2884 EventDef.prototype.isStartExplicitlyEditable = function () {
2885 if (this.startEditable != null) {
2886 return this.startEditable;
2887 }
2888 return this.source.startEditable;
2889 };
2890 EventDef.prototype.isDurationExplicitlyEditable = function () {
2891 if (this.durationEditable != null) {
2892 return this.durationEditable;
2893 }
2894 return this.source.durationEditable;
2895 };
2896 EventDef.prototype.isExplicitlyEditable = function () {
2897 if (this.editable != null) {
2898 return this.editable;
2899 }
2900 return this.source.editable;
2901 };
2902 EventDef.prototype.toLegacy = function () {
2903 var obj = $.extend({}, this.miscProps);
2904 obj._id = this.uid;
2905 obj.source = this.source;
2906 obj.className = this.className.slice(); // copy
2907 obj.allDay = this.isAllDay();
2908 if (this.rawId != null) {
2909 obj.id = this.rawId;
2910 }
2911 EventDef.copyVerbatimStandardProps(this, obj);
2912 return obj;
2913 };
2914 EventDef.prototype.applyManualStandardProps = function (rawProps) {
2915 if (rawProps.id != null) {
2916 this.id = EventDef.normalizeId((this.rawId = rawProps.id));
2917 }
2918 else {
2919 this.id = EventDef.generateId();
2920 }
2921 if (rawProps._id != null) {
2922 this.uid = String(rawProps._id);
2923 }
2924 else {
2925 this.uid = EventDef.generateId();
2926 }
2927 // TODO: converge with EventSource
2928 if ($.isArray(rawProps.className)) {
2929 this.className = rawProps.className;
2930 }
2931 if (typeof rawProps.className === 'string') {
2932 this.className = rawProps.className.split(/\s+/);
2933 }
2934 return true;
2935 };
2936 EventDef.prototype.applyMiscProps = function (rawProps) {
2937 $.extend(this.miscProps, rawProps);
2938 };
2939 EventDef.uuid = 0;
2940 EventDef.defineStandardProps = ParsableModelMixin_1.default.defineStandardProps;
2941 EventDef.copyVerbatimStandardProps = ParsableModelMixin_1.default.copyVerbatimStandardProps;
2942 return EventDef;
2943 }());
2944 exports.default = EventDef;
2945 ParsableModelMixin_1.default.mixInto(EventDef);
2946 EventDef.defineStandardProps({
2947 // not automatically assigned (`false`)
2948 _id: false,
2949 id: false,
2950 className: false,
2951 source: false,
2952 // automatically assigned (`true`)
2953 title: true,
2954 url: true,
2955 rendering: true,
2956 constraint: true,
2957 overlap: true,
2958 editable: true,
2959 startEditable: true,
2960 durationEditable: true,
2961 color: true,
2962 backgroundColor: true,
2963 borderColor: true,
2964 textColor: true
2965 });
2966
2967
2968 /***/ }),
2969 /* 35 */
2970 /***/ (function(module, exports, __webpack_require__) {
2971
2972 Object.defineProperty(exports, "__esModule", { value: true });
2973 var EventRange_1 = __webpack_require__(211);
2974 var EventFootprint_1 = __webpack_require__(36);
2975 var ComponentFootprint_1 = __webpack_require__(12);
2976 function eventDefsToEventInstances(eventDefs, unzonedRange) {
2977 var eventInstances = [];
2978 var i;
2979 for (i = 0; i < eventDefs.length; i++) {
2980 eventInstances.push.apply(eventInstances, // append
2981 eventDefs[i].buildInstances(unzonedRange));
2982 }
2983 return eventInstances;
2984 }
2985 exports.eventDefsToEventInstances = eventDefsToEventInstances;
2986 function eventInstanceToEventRange(eventInstance) {
2987 return new EventRange_1.default(eventInstance.dateProfile.unzonedRange, eventInstance.def, eventInstance);
2988 }
2989 exports.eventInstanceToEventRange = eventInstanceToEventRange;
2990 function eventRangeToEventFootprint(eventRange) {
2991 return new EventFootprint_1.default(new ComponentFootprint_1.default(eventRange.unzonedRange, eventRange.eventDef.isAllDay()), eventRange.eventDef, eventRange.eventInstance // might not exist
2992 );
2993 }
2994 exports.eventRangeToEventFootprint = eventRangeToEventFootprint;
2995 function eventInstanceToUnzonedRange(eventInstance) {
2996 return eventInstance.dateProfile.unzonedRange;
2997 }
2998 exports.eventInstanceToUnzonedRange = eventInstanceToUnzonedRange;
2999 function eventFootprintToComponentFootprint(eventFootprint) {
3000 return eventFootprint.componentFootprint;
3001 }
3002 exports.eventFootprintToComponentFootprint = eventFootprintToComponentFootprint;
3003
3004
3005 /***/ }),
3006 /* 36 */
3007 /***/ (function(module, exports) {
3008
3009 Object.defineProperty(exports, "__esModule", { value: true });
3010 var EventFootprint = /** @class */ (function () {
3011 function EventFootprint(componentFootprint, eventDef, eventInstance) {
3012 this.componentFootprint = componentFootprint;
3013 this.eventDef = eventDef;
3014 if (eventInstance) {
3015 this.eventInstance = eventInstance;
3016 }
3017 }
3018 EventFootprint.prototype.getEventLegacy = function () {
3019 return (this.eventInstance || this.eventDef).toLegacy();
3020 };
3021 return EventFootprint;
3022 }());
3023 exports.default = EventFootprint;
3024
3025
3026 /***/ }),
3027 /* 37 */
3028 /***/ (function(module, exports, __webpack_require__) {
3029
3030 Object.defineProperty(exports, "__esModule", { value: true });
3031 var util_1 = __webpack_require__(4);
3032 var EventDateProfile_1 = __webpack_require__(17);
3033 var EventDef_1 = __webpack_require__(34);
3034 var EventDefDateMutation_1 = __webpack_require__(50);
3035 var SingleEventDef_1 = __webpack_require__(13);
3036 var EventDefMutation = /** @class */ (function () {
3037 function EventDefMutation() {
3038 }
3039 EventDefMutation.createFromRawProps = function (eventInstance, rawProps, largeUnit) {
3040 var eventDef = eventInstance.def;
3041 var dateProps = {};
3042 var standardProps = {};
3043 var miscProps = {};
3044 var verbatimStandardProps = {};
3045 var eventDefId = null;
3046 var className = null;
3047 var propName;
3048 var dateProfile;
3049 var dateMutation;
3050 var defMutation;
3051 for (propName in rawProps) {
3052 if (EventDateProfile_1.default.isStandardProp(propName)) {
3053 dateProps[propName] = rawProps[propName];
3054 }
3055 else if (eventDef.isStandardProp(propName)) {
3056 standardProps[propName] = rawProps[propName];
3057 }
3058 else if (eventDef.miscProps[propName] !== rawProps[propName]) {
3059 miscProps[propName] = rawProps[propName];
3060 }
3061 }
3062 dateProfile = EventDateProfile_1.default.parse(dateProps, eventDef.source);
3063 if (dateProfile) {
3064 dateMutation = EventDefDateMutation_1.default.createFromDiff(eventInstance.dateProfile, dateProfile, largeUnit);
3065 }
3066 if (standardProps.id !== eventDef.id) {
3067 eventDefId = standardProps.id; // only apply if there's a change
3068 }
3069 if (!util_1.isArraysEqual(standardProps.className, eventDef.className)) {
3070 className = standardProps.className; // only apply if there's a change
3071 }
3072 EventDef_1.default.copyVerbatimStandardProps(standardProps, // src
3073 verbatimStandardProps // dest
3074 );
3075 defMutation = new EventDefMutation();
3076 defMutation.eventDefId = eventDefId;
3077 defMutation.className = className;
3078 defMutation.verbatimStandardProps = verbatimStandardProps;
3079 defMutation.miscProps = miscProps;
3080 if (dateMutation) {
3081 defMutation.dateMutation = dateMutation;
3082 }
3083 return defMutation;
3084 };
3085 /*
3086 eventDef assumed to be a SingleEventDef.
3087 returns an undo function.
3088 */
3089 EventDefMutation.prototype.mutateSingle = function (eventDef) {
3090 var origDateProfile;
3091 if (this.dateMutation) {
3092 origDateProfile = eventDef.dateProfile;
3093 eventDef.dateProfile = this.dateMutation.buildNewDateProfile(origDateProfile, eventDef.source.calendar);
3094 }
3095 // can't undo
3096 // TODO: more DRY with EventDef::applyManualStandardProps
3097 if (this.eventDefId != null) {
3098 eventDef.id = EventDef_1.default.normalizeId((eventDef.rawId = this.eventDefId));
3099 }
3100 // can't undo
3101 // TODO: more DRY with EventDef::applyManualStandardProps
3102 if (this.className) {
3103 eventDef.className = this.className;
3104 }
3105 // can't undo
3106 if (this.verbatimStandardProps) {
3107 SingleEventDef_1.default.copyVerbatimStandardProps(this.verbatimStandardProps, // src
3108 eventDef // dest
3109 );
3110 }
3111 // can't undo
3112 if (this.miscProps) {
3113 eventDef.applyMiscProps(this.miscProps);
3114 }
3115 if (origDateProfile) {
3116 return function () {
3117 eventDef.dateProfile = origDateProfile;
3118 };
3119 }
3120 else {
3121 return function () { };
3122 }
3123 };
3124 EventDefMutation.prototype.setDateMutation = function (dateMutation) {
3125 if (dateMutation && !dateMutation.isEmpty()) {
3126 this.dateMutation = dateMutation;
3127 }
3128 else {
3129 this.dateMutation = null;
3130 }
3131 };
3132 EventDefMutation.prototype.isEmpty = function () {
3133 return !this.dateMutation;
3134 };
3135 return EventDefMutation;
3136 }());
3137 exports.default = EventDefMutation;
3138
3139
3140 /***/ }),
3141 /* 38 */
3142 /***/ (function(module, exports) {
3143
3144 Object.defineProperty(exports, "__esModule", { value: true });
3145 exports.default = {
3146 sourceClasses: [],
3147 registerClass: function (EventSourceClass) {
3148 this.sourceClasses.unshift(EventSourceClass); // give highest priority
3149 },
3150 parse: function (rawInput, calendar) {
3151 var sourceClasses = this.sourceClasses;
3152 var i;
3153 var eventSource;
3154 for (i = 0; i < sourceClasses.length; i++) {
3155 eventSource = sourceClasses[i].parse(rawInput, calendar);
3156 if (eventSource) {
3157 return eventSource;
3158 }
3159 }
3160 }
3161 };
3162
3163
3164 /***/ }),
3165 /* 39 */
3166 /***/ (function(module, exports, __webpack_require__) {
3167
3168 Object.defineProperty(exports, "__esModule", { value: true });
3169 var tslib_1 = __webpack_require__(2);
3170 var $ = __webpack_require__(3);
3171 var util_1 = __webpack_require__(4);
3172 var Class_1 = __webpack_require__(33);
3173 /*
3174 Embodies a div that has potential scrollbars
3175 */
3176 var Scroller = /** @class */ (function (_super) {
3177 tslib_1.__extends(Scroller, _super);
3178 function Scroller(options) {
3179 var _this = _super.call(this) || this;
3180 options = options || {};
3181 _this.overflowX = options.overflowX || options.overflow || 'auto';
3182 _this.overflowY = options.overflowY || options.overflow || 'auto';
3183 return _this;
3184 }
3185 Scroller.prototype.render = function () {
3186 this.el = this.renderEl();
3187 this.applyOverflow();
3188 };
3189 Scroller.prototype.renderEl = function () {
3190 return (this.scrollEl = $('<div class="fc-scroller"></div>'));
3191 };
3192 // sets to natural height, unlocks overflow
3193 Scroller.prototype.clear = function () {
3194 this.setHeight('auto');
3195 this.applyOverflow();
3196 };
3197 Scroller.prototype.destroy = function () {
3198 this.el.remove();
3199 };
3200 // Overflow
3201 // -----------------------------------------------------------------------------------------------------------------
3202 Scroller.prototype.applyOverflow = function () {
3203 this.scrollEl.css({
3204 'overflow-x': this.overflowX,
3205 'overflow-y': this.overflowY
3206 });
3207 };
3208 // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
3209 // Useful for preserving scrollbar widths regardless of future resizes.
3210 // Can pass in scrollbarWidths for optimization.
3211 Scroller.prototype.lockOverflow = function (scrollbarWidths) {
3212 var overflowX = this.overflowX;
3213 var overflowY = this.overflowY;
3214 scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
3215 if (overflowX === 'auto') {
3216 overflowX = (scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars?
3217 // OR scrolling pane with massless scrollbars?
3218 this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth) ? 'scroll' : 'hidden';
3219 }
3220 if (overflowY === 'auto') {
3221 overflowY = (scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars?
3222 // OR scrolling pane with massless scrollbars?
3223 this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight) ? 'scroll' : 'hidden';
3224 }
3225 this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY });
3226 };
3227 // Getters / Setters
3228 // -----------------------------------------------------------------------------------------------------------------
3229 Scroller.prototype.setHeight = function (height) {
3230 this.scrollEl.height(height);
3231 };
3232 Scroller.prototype.getScrollTop = function () {
3233 return this.scrollEl.scrollTop();
3234 };
3235 Scroller.prototype.setScrollTop = function (top) {
3236 this.scrollEl.scrollTop(top);
3237 };
3238 Scroller.prototype.getClientWidth = function () {
3239 return this.scrollEl[0].clientWidth;
3240 };
3241 Scroller.prototype.getClientHeight = function () {
3242 return this.scrollEl[0].clientHeight;
3243 };
3244 Scroller.prototype.getScrollbarWidths = function () {
3245 return util_1.getScrollbarWidths(this.scrollEl);
3246 };
3247 return Scroller;
3248 }(Class_1.default));
3249 exports.default = Scroller;
3250
3251
3252 /***/ }),
3253 /* 40 */
3254 /***/ (function(module, exports, __webpack_require__) {
3255
3256 Object.defineProperty(exports, "__esModule", { value: true });
3257 var tslib_1 = __webpack_require__(2);
3258 var $ = __webpack_require__(3);
3259 var util_1 = __webpack_require__(4);
3260 var DateComponent_1 = __webpack_require__(219);
3261 var GlobalEmitter_1 = __webpack_require__(21);
3262 var InteractiveDateComponent = /** @class */ (function (_super) {
3263 tslib_1.__extends(InteractiveDateComponent, _super);
3264 function InteractiveDateComponent(_view, _options) {
3265 var _this = _super.call(this, _view, _options) || this;
3266 // self-config, overridable by subclasses
3267 _this.segSelector = '.fc-event-container > *'; // what constitutes an event element?
3268 if (_this.dateSelectingClass) {
3269 _this.dateClicking = new _this.dateClickingClass(_this);
3270 }
3271 if (_this.dateSelectingClass) {
3272 _this.dateSelecting = new _this.dateSelectingClass(_this);
3273 }
3274 if (_this.eventPointingClass) {
3275 _this.eventPointing = new _this.eventPointingClass(_this);
3276 }
3277 if (_this.eventDraggingClass && _this.eventPointing) {
3278 _this.eventDragging = new _this.eventDraggingClass(_this, _this.eventPointing);
3279 }
3280 if (_this.eventResizingClass && _this.eventPointing) {
3281 _this.eventResizing = new _this.eventResizingClass(_this, _this.eventPointing);
3282 }
3283 if (_this.externalDroppingClass) {
3284 _this.externalDropping = new _this.externalDroppingClass(_this);
3285 }
3286 return _this;
3287 }
3288 // Sets the container element that the view should render inside of, does global DOM-related initializations,
3289 // and renders all the non-date-related content inside.
3290 InteractiveDateComponent.prototype.setElement = function (el) {
3291 _super.prototype.setElement.call(this, el);
3292 if (this.dateClicking) {
3293 this.dateClicking.bindToEl(el);
3294 }
3295 if (this.dateSelecting) {
3296 this.dateSelecting.bindToEl(el);
3297 }
3298 this.bindAllSegHandlersToEl(el);
3299 };
3300 InteractiveDateComponent.prototype.removeElement = function () {
3301 this.endInteractions();
3302 _super.prototype.removeElement.call(this);
3303 };
3304 InteractiveDateComponent.prototype.executeEventUnrender = function () {
3305 this.endInteractions();
3306 _super.prototype.executeEventUnrender.call(this);
3307 };
3308 InteractiveDateComponent.prototype.bindGlobalHandlers = function () {
3309 _super.prototype.bindGlobalHandlers.call(this);
3310 if (this.externalDropping) {
3311 this.externalDropping.bindToDocument();
3312 }
3313 };
3314 InteractiveDateComponent.prototype.unbindGlobalHandlers = function () {
3315 _super.prototype.unbindGlobalHandlers.call(this);
3316 if (this.externalDropping) {
3317 this.externalDropping.unbindFromDocument();
3318 }
3319 };
3320 InteractiveDateComponent.prototype.bindDateHandlerToEl = function (el, name, handler) {
3321 var _this = this;
3322 // attach a handler to the grid's root element.
3323 // jQuery will take care of unregistering them when removeElement gets called.
3324 this.el.on(name, function (ev) {
3325 if (!$(ev.target).is(_this.segSelector + ':not(.fc-helper),' + // directly on an event element
3326 _this.segSelector + ':not(.fc-helper) *,' + // within an event element
3327 '.fc-more,' + // a "more.." link
3328 'a[data-goto]' // a clickable nav link
3329 )) {
3330 return handler.call(_this, ev);
3331 }
3332 });
3333 };
3334 InteractiveDateComponent.prototype.bindAllSegHandlersToEl = function (el) {
3335 [
3336 this.eventPointing,
3337 this.eventDragging,
3338 this.eventResizing
3339 ].forEach(function (eventInteraction) {
3340 if (eventInteraction) {
3341 eventInteraction.bindToEl(el);
3342 }
3343 });
3344 };
3345 InteractiveDateComponent.prototype.bindSegHandlerToEl = function (el, name, handler) {
3346 var _this = this;
3347 el.on(name, this.segSelector, function (ev) {
3348 var segEl = $(ev.currentTarget);
3349 if (!segEl.is('.fc-helper')) {
3350 var seg = segEl.data('fc-seg'); // grab segment data. put there by View::renderEventsPayload
3351 if (seg && !_this.shouldIgnoreEventPointing()) {
3352 return handler.call(_this, seg, ev); // context will be the Grid
3353 }
3354 }
3355 });
3356 };
3357 InteractiveDateComponent.prototype.shouldIgnoreMouse = function () {
3358 // HACK
3359 // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter.
3360 return GlobalEmitter_1.default.get().shouldIgnoreMouse();
3361 };
3362 InteractiveDateComponent.prototype.shouldIgnoreTouch = function () {
3363 var view = this._getView();
3364 // On iOS (and Android?) when a new selection is initiated overtop another selection,
3365 // the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
3366 // HACK: simply don't allow this to happen.
3367 // ALSO: prevent selection when an *event* is already raised.
3368 return view.isSelected || view.selectedEvent;
3369 };
3370 InteractiveDateComponent.prototype.shouldIgnoreEventPointing = function () {
3371 // only call the handlers if there is not a drag/resize in progress
3372 return (this.eventDragging && this.eventDragging.isDragging) ||
3373 (this.eventResizing && this.eventResizing.isResizing);
3374 };
3375 InteractiveDateComponent.prototype.canStartSelection = function (seg, ev) {
3376 return util_1.getEvIsTouch(ev) &&
3377 !this.canStartResize(seg, ev) &&
3378 (this.isEventDefDraggable(seg.footprint.eventDef) ||
3379 this.isEventDefResizable(seg.footprint.eventDef));
3380 };
3381 InteractiveDateComponent.prototype.canStartDrag = function (seg, ev) {
3382 return !this.canStartResize(seg, ev) &&
3383 this.isEventDefDraggable(seg.footprint.eventDef);
3384 };
3385 InteractiveDateComponent.prototype.canStartResize = function (seg, ev) {
3386 var view = this._getView();
3387 var eventDef = seg.footprint.eventDef;
3388 return (!util_1.getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) &&
3389 this.isEventDefResizable(eventDef) &&
3390 $(ev.target).is('.fc-resizer');
3391 };
3392 // Kills all in-progress dragging.
3393 // Useful for when public API methods that result in re-rendering are invoked during a drag.
3394 // Also useful for when touch devices misbehave and don't fire their touchend.
3395 InteractiveDateComponent.prototype.endInteractions = function () {
3396 [
3397 this.dateClicking,
3398 this.dateSelecting,
3399 this.eventPointing,
3400 this.eventDragging,
3401 this.eventResizing
3402 ].forEach(function (interaction) {
3403 if (interaction) {
3404 interaction.end();
3405 }
3406 });
3407 };
3408 // Event Drag-n-Drop
3409 // ---------------------------------------------------------------------------------------------------------------
3410 // Computes if the given event is allowed to be dragged by the user
3411 InteractiveDateComponent.prototype.isEventDefDraggable = function (eventDef) {
3412 return this.isEventDefStartEditable(eventDef);
3413 };
3414 InteractiveDateComponent.prototype.isEventDefStartEditable = function (eventDef) {
3415 var isEditable = eventDef.isStartExplicitlyEditable();
3416 if (isEditable == null) {
3417 isEditable = this.opt('eventStartEditable');
3418 if (isEditable == null) {
3419 isEditable = this.isEventDefGenerallyEditable(eventDef);
3420 }
3421 }
3422 return isEditable;
3423 };
3424 InteractiveDateComponent.prototype.isEventDefGenerallyEditable = function (eventDef) {
3425 var isEditable = eventDef.isExplicitlyEditable();
3426 if (isEditable == null) {
3427 isEditable = this.opt('editable');
3428 }
3429 return isEditable;
3430 };
3431 // Event Resizing
3432 // ---------------------------------------------------------------------------------------------------------------
3433 // Computes if the given event is allowed to be resized from its starting edge
3434 InteractiveDateComponent.prototype.isEventDefResizableFromStart = function (eventDef) {
3435 return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef);
3436 };
3437 // Computes if the given event is allowed to be resized from its ending edge
3438 InteractiveDateComponent.prototype.isEventDefResizableFromEnd = function (eventDef) {
3439 return this.isEventDefResizable(eventDef);
3440 };
3441 // Computes if the given event is allowed to be resized by the user at all
3442 InteractiveDateComponent.prototype.isEventDefResizable = function (eventDef) {
3443 var isResizable = eventDef.isDurationExplicitlyEditable();
3444 if (isResizable == null) {
3445 isResizable = this.opt('eventDurationEditable');
3446 if (isResizable == null) {
3447 isResizable = this.isEventDefGenerallyEditable(eventDef);
3448 }
3449 }
3450 return isResizable;
3451 };
3452 // Event Mutation / Constraints
3453 // ---------------------------------------------------------------------------------------------------------------
3454 // Diffs the two dates, returning a duration, based on granularity of the grid
3455 // TODO: port isTimeScale into this system?
3456 InteractiveDateComponent.prototype.diffDates = function (a, b) {
3457 if (this.largeUnit) {
3458 return util_1.diffByUnit(a, b, this.largeUnit);
3459 }
3460 else {
3461 return util_1.diffDayTime(a, b);
3462 }
3463 };
3464 // is it allowed, in relation to the view's validRange?
3465 // NOTE: very similar to isExternalInstanceGroupAllowed
3466 InteractiveDateComponent.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) {
3467 var view = this._getView();
3468 var dateProfile = this.dateProfile;
3469 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
3470 var i;
3471 for (i = 0; i < eventFootprints.length; i++) {
3472 // TODO: just use getAllEventRanges directly
3473 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
3474 return false;
3475 }
3476 }
3477 return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup);
3478 };
3479 // NOTE: very similar to isEventInstanceGroupAllowed
3480 // when it's a completely anonymous external drag, no event.
3481 InteractiveDateComponent.prototype.isExternalInstanceGroupAllowed = function (eventInstanceGroup) {
3482 var view = this._getView();
3483 var dateProfile = this.dateProfile;
3484 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
3485 var i;
3486 for (i = 0; i < eventFootprints.length; i++) {
3487 if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
3488 return false;
3489 }
3490 }
3491 for (i = 0; i < eventFootprints.length; i++) {
3492 // treat it as a selection
3493 // TODO: pass in eventInstanceGroup instead
3494 // because we don't want calendar's constraint system to depend on a component's
3495 // determination of footprints.
3496 if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) {
3497 return false;
3498 }
3499 }
3500 return true;
3501 };
3502 return InteractiveDateComponent;
3503 }(DateComponent_1.default));
3504 exports.default = InteractiveDateComponent;
3505
3506
3507 /***/ }),
3508 /* 41 */
3509 /***/ (function(module, exports, __webpack_require__) {
3510
3511 Object.defineProperty(exports, "__esModule", { value: true });
3512 var tslib_1 = __webpack_require__(2);
3513 var $ = __webpack_require__(3);
3514 var moment = __webpack_require__(0);
3515 var util_1 = __webpack_require__(4);
3516 var RenderQueue_1 = __webpack_require__(218);
3517 var DateProfileGenerator_1 = __webpack_require__(221);
3518 var InteractiveDateComponent_1 = __webpack_require__(40);
3519 var GlobalEmitter_1 = __webpack_require__(21);
3520 var UnzonedRange_1 = __webpack_require__(5);
3521 /* An abstract class from which other views inherit from
3522 ----------------------------------------------------------------------------------------------------------------------*/
3523 var View = /** @class */ (function (_super) {
3524 tslib_1.__extends(View, _super);
3525 function View(calendar, viewSpec) {
3526 var _this = _super.call(this, null, viewSpec.options) || this;
3527 _this.batchRenderDepth = 0;
3528 _this.isSelected = false; // boolean whether a range of time is user-selected or not
3529 _this.calendar = calendar;
3530 _this.viewSpec = viewSpec;
3531 // shortcuts
3532 _this.type = viewSpec.type;
3533 // .name is deprecated
3534 _this.name = _this.type;
3535 _this.initRenderQueue();
3536 _this.initHiddenDays();
3537 _this.dateProfileGenerator = new _this.dateProfileGeneratorClass(_this);
3538 _this.bindBaseRenderHandlers();
3539 _this.eventOrderSpecs = util_1.parseFieldSpecs(_this.opt('eventOrder'));
3540 // legacy
3541 if (_this['initialize']) {
3542 _this['initialize']();
3543 }
3544 return _this;
3545 }
3546 View.prototype._getView = function () {
3547 return this;
3548 };
3549 // Retrieves an option with the given name
3550 View.prototype.opt = function (name) {
3551 return this.options[name];
3552 };
3553 /* Render Queue
3554 ------------------------------------------------------------------------------------------------------------------*/
3555 View.prototype.initRenderQueue = function () {
3556 this.renderQueue = new RenderQueue_1.default({
3557 event: this.opt('eventRenderWait')
3558 });
3559 this.renderQueue.on('start', this.onRenderQueueStart.bind(this));
3560 this.renderQueue.on('stop', this.onRenderQueueStop.bind(this));
3561 this.on('before:change', this.startBatchRender);
3562 this.on('change', this.stopBatchRender);
3563 };
3564 View.prototype.onRenderQueueStart = function () {
3565 this.calendar.freezeContentHeight();
3566 this.addScroll(this.queryScroll());
3567 };
3568 View.prototype.onRenderQueueStop = function () {
3569 if (this.calendar.updateViewSize()) {
3570 this.popScroll();
3571 }
3572 this.calendar.thawContentHeight();
3573 };
3574 View.prototype.startBatchRender = function () {
3575 if (!(this.batchRenderDepth++)) {
3576 this.renderQueue.pause();
3577 }
3578 };
3579 View.prototype.stopBatchRender = function () {
3580 if (!(--this.batchRenderDepth)) {
3581 this.renderQueue.resume();
3582 }
3583 };
3584 View.prototype.requestRender = function (func, namespace, actionType) {
3585 this.renderQueue.queue(func, namespace, actionType);
3586 };
3587 // given func will auto-bind to `this`
3588 View.prototype.whenSizeUpdated = function (func) {
3589 if (this.renderQueue.isRunning) {
3590 this.renderQueue.one('stop', func.bind(this));
3591 }
3592 else {
3593 func.call(this);
3594 }
3595 };
3596 /* Title and Date Formatting
3597 ------------------------------------------------------------------------------------------------------------------*/
3598 // Computes what the title at the top of the calendar should be for this view
3599 View.prototype.computeTitle = function (dateProfile) {
3600 var unzonedRange;
3601 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
3602 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
3603 unzonedRange = dateProfile.currentUnzonedRange;
3604 }
3605 else {
3606 unzonedRange = dateProfile.activeUnzonedRange;
3607 }
3608 return this.formatRange({
3609 start: this.calendar.msToMoment(unzonedRange.startMs, dateProfile.isRangeAllDay),
3610 end: this.calendar.msToMoment(unzonedRange.endMs, dateProfile.isRangeAllDay)
3611 }, dateProfile.isRangeAllDay, this.opt('titleFormat') || this.computeTitleFormat(dateProfile), this.opt('titleRangeSeparator'));
3612 };
3613 // Generates the format string that should be used to generate the title for the current date range.
3614 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
3615 View.prototype.computeTitleFormat = function (dateProfile) {
3616 var currentRangeUnit = dateProfile.currentRangeUnit;
3617 if (currentRangeUnit === 'year') {
3618 return 'YYYY';
3619 }
3620 else if (currentRangeUnit === 'month') {
3621 return this.opt('monthYearFormat'); // like "September 2014"
3622 }
3623 else if (dateProfile.currentUnzonedRange.as('days') > 1) {
3624 return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014"
3625 }
3626 else {
3627 return 'LL'; // one day. longer, like "September 9 2014"
3628 }
3629 };
3630 // Date Setting/Unsetting
3631 // -----------------------------------------------------------------------------------------------------------------
3632 View.prototype.setDate = function (date) {
3633 var currentDateProfile = this.get('dateProfile');
3634 var newDateProfile = this.dateProfileGenerator.build(date, undefined, true); // forceToValid=true
3635 if (!currentDateProfile ||
3636 !currentDateProfile.activeUnzonedRange.equals(newDateProfile.activeUnzonedRange)) {
3637 this.set('dateProfile', newDateProfile);
3638 }
3639 };
3640 View.prototype.unsetDate = function () {
3641 this.unset('dateProfile');
3642 };
3643 // Event Data
3644 // -----------------------------------------------------------------------------------------------------------------
3645 View.prototype.fetchInitialEvents = function (dateProfile) {
3646 var calendar = this.calendar;
3647 var forceAllDay = dateProfile.isRangeAllDay && !this.usesMinMaxTime;
3648 return calendar.requestEvents(calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, forceAllDay), calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, forceAllDay));
3649 };
3650 View.prototype.bindEventChanges = function () {
3651 this.listenTo(this.calendar, 'eventsReset', this.resetEvents); // TODO: make this a real event
3652 };
3653 View.prototype.unbindEventChanges = function () {
3654 this.stopListeningTo(this.calendar, 'eventsReset');
3655 };
3656 View.prototype.setEvents = function (eventsPayload) {
3657 this.set('currentEvents', eventsPayload);
3658 this.set('hasEvents', true);
3659 };
3660 View.prototype.unsetEvents = function () {
3661 this.unset('currentEvents');
3662 this.unset('hasEvents');
3663 };
3664 View.prototype.resetEvents = function (eventsPayload) {
3665 this.startBatchRender();
3666 this.unsetEvents();
3667 this.setEvents(eventsPayload);
3668 this.stopBatchRender();
3669 };
3670 // Date High-level Rendering
3671 // -----------------------------------------------------------------------------------------------------------------
3672 View.prototype.requestDateRender = function (dateProfile) {
3673 var _this = this;
3674 this.requestRender(function () {
3675 _this.executeDateRender(dateProfile);
3676 }, 'date', 'init');
3677 };
3678 View.prototype.requestDateUnrender = function () {
3679 var _this = this;
3680 this.requestRender(function () {
3681 _this.executeDateUnrender();
3682 }, 'date', 'destroy');
3683 };
3684 // if dateProfile not specified, uses current
3685 View.prototype.executeDateRender = function (dateProfile) {
3686 _super.prototype.executeDateRender.call(this, dateProfile);
3687 if (this['render']) {
3688 this['render'](); // TODO: deprecate
3689 }
3690 this.trigger('datesRendered');
3691 this.addScroll({ isDateInit: true });
3692 this.startNowIndicator(); // shouldn't render yet because updateSize will be called soon
3693 };
3694 View.prototype.executeDateUnrender = function () {
3695 this.unselect();
3696 this.stopNowIndicator();
3697 this.trigger('before:datesUnrendered');
3698 if (this['destroy']) {
3699 this['destroy'](); // TODO: deprecate
3700 }
3701 _super.prototype.executeDateUnrender.call(this);
3702 };
3703 // "Base" rendering
3704 // -----------------------------------------------------------------------------------------------------------------
3705 View.prototype.bindBaseRenderHandlers = function () {
3706 var _this = this;
3707 this.on('datesRendered', function () {
3708 _this.whenSizeUpdated(_this.triggerViewRender);
3709 });
3710 this.on('before:datesUnrendered', function () {
3711 _this.triggerViewDestroy();
3712 });
3713 };
3714 View.prototype.triggerViewRender = function () {
3715 this.publiclyTrigger('viewRender', {
3716 context: this,
3717 args: [this, this.el]
3718 });
3719 };
3720 View.prototype.triggerViewDestroy = function () {
3721 this.publiclyTrigger('viewDestroy', {
3722 context: this,
3723 args: [this, this.el]
3724 });
3725 };
3726 // Event High-level Rendering
3727 // -----------------------------------------------------------------------------------------------------------------
3728 View.prototype.requestEventsRender = function (eventsPayload) {
3729 var _this = this;
3730 this.requestRender(function () {
3731 _this.executeEventRender(eventsPayload);
3732 _this.whenSizeUpdated(_this.triggerAfterEventsRendered);
3733 }, 'event', 'init');
3734 };
3735 View.prototype.requestEventsUnrender = function () {
3736 var _this = this;
3737 this.requestRender(function () {
3738 _this.triggerBeforeEventsDestroyed();
3739 _this.executeEventUnrender();
3740 }, 'event', 'destroy');
3741 };
3742 // Business Hour High-level Rendering
3743 // -----------------------------------------------------------------------------------------------------------------
3744 View.prototype.requestBusinessHoursRender = function (businessHourGenerator) {
3745 var _this = this;
3746 this.requestRender(function () {
3747 _this.renderBusinessHours(businessHourGenerator);
3748 }, 'businessHours', 'init');
3749 };
3750 View.prototype.requestBusinessHoursUnrender = function () {
3751 var _this = this;
3752 this.requestRender(function () {
3753 _this.unrenderBusinessHours();
3754 }, 'businessHours', 'destroy');
3755 };
3756 // Misc view rendering utils
3757 // -----------------------------------------------------------------------------------------------------------------
3758 // Binds DOM handlers to elements that reside outside the view container, such as the document
3759 View.prototype.bindGlobalHandlers = function () {
3760 _super.prototype.bindGlobalHandlers.call(this);
3761 this.listenTo(GlobalEmitter_1.default.get(), {
3762 touchstart: this.processUnselect,
3763 mousedown: this.handleDocumentMousedown
3764 });
3765 };
3766 // Unbinds DOM handlers from elements that reside outside the view container
3767 View.prototype.unbindGlobalHandlers = function () {
3768 _super.prototype.unbindGlobalHandlers.call(this);
3769 this.stopListeningTo(GlobalEmitter_1.default.get());
3770 };
3771 /* Now Indicator
3772 ------------------------------------------------------------------------------------------------------------------*/
3773 // Immediately render the current time indicator and begins re-rendering it at an interval,
3774 // which is defined by this.getNowIndicatorUnit().
3775 // TODO: somehow do this for the current whole day's background too
3776 View.prototype.startNowIndicator = function () {
3777 var _this = this;
3778 var unit;
3779 var update;
3780 var delay; // ms wait value
3781 if (this.opt('nowIndicator')) {
3782 unit = this.getNowIndicatorUnit();
3783 if (unit) {
3784 update = util_1.proxy(this, 'updateNowIndicator'); // bind to `this`
3785 this.initialNowDate = this.calendar.getNow();
3786 this.initialNowQueriedMs = new Date().valueOf();
3787 // wait until the beginning of the next interval
3788 delay = this.initialNowDate.clone().startOf(unit).add(1, unit).valueOf() - this.initialNowDate.valueOf();
3789 this.nowIndicatorTimeoutID = setTimeout(function () {
3790 _this.nowIndicatorTimeoutID = null;
3791 update();
3792 delay = +moment.duration(1, unit);
3793 delay = Math.max(100, delay); // prevent too frequent
3794 _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
3795 }, delay);
3796 }
3797 // rendering will be initiated in updateSize
3798 }
3799 };
3800 // rerenders the now indicator, computing the new current time from the amount of time that has passed
3801 // since the initial getNow call.
3802 View.prototype.updateNowIndicator = function () {
3803 if (this.isDatesRendered &&
3804 this.initialNowDate // activated before?
3805 ) {
3806 this.unrenderNowIndicator(); // won't unrender if unnecessary
3807 this.renderNowIndicator(this.initialNowDate.clone().add(new Date().valueOf() - this.initialNowQueriedMs) // add ms
3808 );
3809 this.isNowIndicatorRendered = true;
3810 }
3811 };
3812 // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
3813 // Won't cause side effects if indicator isn't rendered.
3814 View.prototype.stopNowIndicator = function () {
3815 if (this.isNowIndicatorRendered) {
3816 if (this.nowIndicatorTimeoutID) {
3817 clearTimeout(this.nowIndicatorTimeoutID);
3818 this.nowIndicatorTimeoutID = null;
3819 }
3820 if (this.nowIndicatorIntervalID) {
3821 clearInterval(this.nowIndicatorIntervalID);
3822 this.nowIndicatorIntervalID = null;
3823 }
3824 this.unrenderNowIndicator();
3825 this.isNowIndicatorRendered = false;
3826 }
3827 };
3828 /* Dimensions
3829 ------------------------------------------------------------------------------------------------------------------*/
3830 View.prototype.updateSize = function (totalHeight, isAuto, isResize) {
3831 if (this['setHeight']) {
3832 this['setHeight'](totalHeight, isAuto);
3833 }
3834 else {
3835 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
3836 }
3837 this.updateNowIndicator();
3838 };
3839 /* Scroller
3840 ------------------------------------------------------------------------------------------------------------------*/
3841 View.prototype.addScroll = function (scroll) {
3842 var queuedScroll = this.queuedScroll || (this.queuedScroll = {});
3843 $.extend(queuedScroll, scroll);
3844 };
3845 View.prototype.popScroll = function () {
3846 this.applyQueuedScroll();
3847 this.queuedScroll = null;
3848 };
3849 View.prototype.applyQueuedScroll = function () {
3850 if (this.queuedScroll) {
3851 this.applyScroll(this.queuedScroll);
3852 }
3853 };
3854 View.prototype.queryScroll = function () {
3855 var scroll = {};
3856 if (this.isDatesRendered) {
3857 $.extend(scroll, this.queryDateScroll());
3858 }
3859 return scroll;
3860 };
3861 View.prototype.applyScroll = function (scroll) {
3862 if (scroll.isDateInit && this.isDatesRendered) {
3863 $.extend(scroll, this.computeInitialDateScroll());
3864 }
3865 if (this.isDatesRendered) {
3866 this.applyDateScroll(scroll);
3867 }
3868 };
3869 View.prototype.computeInitialDateScroll = function () {
3870 return {}; // subclasses must implement
3871 };
3872 View.prototype.queryDateScroll = function () {
3873 return {}; // subclasses must implement
3874 };
3875 View.prototype.applyDateScroll = function (scroll) {
3876 // subclasses must implement
3877 };
3878 /* Event Drag-n-Drop
3879 ------------------------------------------------------------------------------------------------------------------*/
3880 View.prototype.reportEventDrop = function (eventInstance, eventMutation, el, ev) {
3881 var eventManager = this.calendar.eventManager;
3882 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation);
3883 var dateMutation = eventMutation.dateMutation;
3884 // update the EventInstance, for handlers
3885 if (dateMutation) {
3886 eventInstance.dateProfile = dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar);
3887 }
3888 this.triggerEventDrop(eventInstance,
3889 // a drop doesn't necessarily mean a date mutation (ex: resource change)
3890 (dateMutation && dateMutation.dateDelta) || moment.duration(), undoFunc, el, ev);
3891 };
3892 // Triggers event-drop handlers that have subscribed via the API
3893 View.prototype.triggerEventDrop = function (eventInstance, dateDelta, undoFunc, el, ev) {
3894 this.publiclyTrigger('eventDrop', {
3895 context: el[0],
3896 args: [
3897 eventInstance.toLegacy(),
3898 dateDelta,
3899 undoFunc,
3900 ev,
3901 {},
3902 this
3903 ]
3904 });
3905 };
3906 /* External Element Drag-n-Drop
3907 ------------------------------------------------------------------------------------------------------------------*/
3908 // Must be called when an external element, via jQuery UI, has been dropped onto the calendar.
3909 // `meta` is the parsed data that has been embedded into the dragging event.
3910 // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event.
3911 View.prototype.reportExternalDrop = function (singleEventDef, isEvent, isSticky, el, ev, ui) {
3912 if (isEvent) {
3913 this.calendar.eventManager.addEventDef(singleEventDef, isSticky);
3914 }
3915 this.triggerExternalDrop(singleEventDef, isEvent, el, ev, ui);
3916 };
3917 // Triggers external-drop handlers that have subscribed via the API
3918 View.prototype.triggerExternalDrop = function (singleEventDef, isEvent, el, ev, ui) {
3919 // trigger 'drop' regardless of whether element represents an event
3920 this.publiclyTrigger('drop', {
3921 context: el[0],
3922 args: [
3923 singleEventDef.dateProfile.start.clone(),
3924 ev,
3925 ui,
3926 this
3927 ]
3928 });
3929 if (isEvent) {
3930 // signal an external event landed
3931 this.publiclyTrigger('eventReceive', {
3932 context: this,
3933 args: [
3934 singleEventDef.buildInstance().toLegacy(),
3935 this
3936 ]
3937 });
3938 }
3939 };
3940 /* Event Resizing
3941 ------------------------------------------------------------------------------------------------------------------*/
3942 // Must be called when an event in the view has been resized to a new length
3943 View.prototype.reportEventResize = function (eventInstance, eventMutation, el, ev) {
3944 var eventManager = this.calendar.eventManager;
3945 var undoFunc = eventManager.mutateEventsWithId(eventInstance.def.id, eventMutation);
3946 // update the EventInstance, for handlers
3947 eventInstance.dateProfile = eventMutation.dateMutation.buildNewDateProfile(eventInstance.dateProfile, this.calendar);
3948 this.triggerEventResize(eventInstance, eventMutation.dateMutation.endDelta, undoFunc, el, ev);
3949 };
3950 // Triggers event-resize handlers that have subscribed via the API
3951 View.prototype.triggerEventResize = function (eventInstance, durationDelta, undoFunc, el, ev) {
3952 this.publiclyTrigger('eventResize', {
3953 context: el[0],
3954 args: [
3955 eventInstance.toLegacy(),
3956 durationDelta,
3957 undoFunc,
3958 ev,
3959 {},
3960 this
3961 ]
3962 });
3963 };
3964 /* Selection (time range)
3965 ------------------------------------------------------------------------------------------------------------------*/
3966 // Selects a date span on the view. `start` and `end` are both Moments.
3967 // `ev` is the native mouse event that begin the interaction.
3968 View.prototype.select = function (footprint, ev) {
3969 this.unselect(ev);
3970 this.renderSelectionFootprint(footprint);
3971 this.reportSelection(footprint, ev);
3972 };
3973 View.prototype.renderSelectionFootprint = function (footprint) {
3974 if (this['renderSelection']) {
3975 this['renderSelection'](footprint.toLegacy(this.calendar));
3976 }
3977 else {
3978 _super.prototype.renderSelectionFootprint.call(this, footprint);
3979 }
3980 };
3981 // Called when a new selection is made. Updates internal state and triggers handlers.
3982 View.prototype.reportSelection = function (footprint, ev) {
3983 this.isSelected = true;
3984 this.triggerSelect(footprint, ev);
3985 };
3986 // Triggers handlers to 'select'
3987 View.prototype.triggerSelect = function (footprint, ev) {
3988 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile?
3989 this.publiclyTrigger('select', {
3990 context: this,
3991 args: [
3992 dateProfile.start,
3993 dateProfile.end,
3994 ev,
3995 this
3996 ]
3997 });
3998 };
3999 // Undoes a selection. updates in the internal state and triggers handlers.
4000 // `ev` is the native mouse event that began the interaction.
4001 View.prototype.unselect = function (ev) {
4002 if (this.isSelected) {
4003 this.isSelected = false;
4004 if (this['destroySelection']) {
4005 this['destroySelection'](); // TODO: deprecate
4006 }
4007 this.unrenderSelection();
4008 this.publiclyTrigger('unselect', {
4009 context: this,
4010 args: [ev, this]
4011 });
4012 }
4013 };
4014 /* Event Selection
4015 ------------------------------------------------------------------------------------------------------------------*/
4016 View.prototype.selectEventInstance = function (eventInstance) {
4017 if (!this.selectedEventInstance ||
4018 this.selectedEventInstance !== eventInstance) {
4019 this.unselectEventInstance();
4020 this.getEventSegs().forEach(function (seg) {
4021 if (seg.footprint.eventInstance === eventInstance &&
4022 seg.el // necessary?
4023 ) {
4024 seg.el.addClass('fc-selected');
4025 }
4026 });
4027 this.selectedEventInstance = eventInstance;
4028 }
4029 };
4030 View.prototype.unselectEventInstance = function () {
4031 if (this.selectedEventInstance) {
4032 this.getEventSegs().forEach(function (seg) {
4033 if (seg.el) {
4034 seg.el.removeClass('fc-selected');
4035 }
4036 });
4037 this.selectedEventInstance = null;
4038 }
4039 };
4040 View.prototype.isEventDefSelected = function (eventDef) {
4041 // event references might change on refetchEvents(), while selectedEventInstance doesn't,
4042 // so compare IDs
4043 return this.selectedEventInstance && this.selectedEventInstance.def.id === eventDef.id;
4044 };
4045 /* Mouse / Touch Unselecting (time range & event unselection)
4046 ------------------------------------------------------------------------------------------------------------------*/
4047 // TODO: move consistently to down/start or up/end?
4048 // TODO: don't kill previous selection if touch scrolling
4049 View.prototype.handleDocumentMousedown = function (ev) {
4050 if (util_1.isPrimaryMouseButton(ev)) {
4051 this.processUnselect(ev);
4052 }
4053 };
4054 View.prototype.processUnselect = function (ev) {
4055 this.processRangeUnselect(ev);
4056 this.processEventUnselect(ev);
4057 };
4058 View.prototype.processRangeUnselect = function (ev) {
4059 var ignore;
4060 // is there a time-range selection?
4061 if (this.isSelected && this.opt('unselectAuto')) {
4062 // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element
4063 ignore = this.opt('unselectCancel');
4064 if (!ignore || !$(ev.target).closest(ignore).length) {
4065 this.unselect(ev);
4066 }
4067 }
4068 };
4069 View.prototype.processEventUnselect = function (ev) {
4070 if (this.selectedEventInstance) {
4071 if (!$(ev.target).closest('.fc-selected').length) {
4072 this.unselectEventInstance();
4073 }
4074 }
4075 };
4076 /* Triggers
4077 ------------------------------------------------------------------------------------------------------------------*/
4078 View.prototype.triggerBaseRendered = function () {
4079 this.publiclyTrigger('viewRender', {
4080 context: this,
4081 args: [this, this.el]
4082 });
4083 };
4084 View.prototype.triggerBaseUnrendered = function () {
4085 this.publiclyTrigger('viewDestroy', {
4086 context: this,
4087 args: [this, this.el]
4088 });
4089 };
4090 // Triggers handlers to 'dayClick'
4091 // Span has start/end of the clicked area. Only the start is useful.
4092 View.prototype.triggerDayClick = function (footprint, dayEl, ev) {
4093 var dateProfile = this.calendar.footprintToDateProfile(footprint); // abuse of "Event"DateProfile?
4094 this.publiclyTrigger('dayClick', {
4095 context: dayEl,
4096 args: [dateProfile.start, ev, this]
4097 });
4098 };
4099 /* Date Utils
4100 ------------------------------------------------------------------------------------------------------------------*/
4101 // For DateComponent::getDayClasses
4102 View.prototype.isDateInOtherMonth = function (date, dateProfile) {
4103 return false;
4104 };
4105 // Arguments after name will be forwarded to a hypothetical function value
4106 // WARNING: passed-in arguments will be given to generator functions as-is and can cause side-effects.
4107 // Always clone your objects if you fear mutation.
4108 View.prototype.getUnzonedRangeOption = function (name) {
4109 var val = this.opt(name);
4110 if (typeof val === 'function') {
4111 val = val.apply(null, Array.prototype.slice.call(arguments, 1));
4112 }
4113 if (val) {
4114 return this.calendar.parseUnzonedRange(val);
4115 }
4116 };
4117 /* Hidden Days
4118 ------------------------------------------------------------------------------------------------------------------*/
4119 // Initializes internal variables related to calculating hidden days-of-week
4120 View.prototype.initHiddenDays = function () {
4121 var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden
4122 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
4123 var dayCnt = 0;
4124 var i;
4125 if (this.opt('weekends') === false) {
4126 hiddenDays.push(0, 6); // 0=sunday, 6=saturday
4127 }
4128 for (i = 0; i < 7; i++) {
4129 if (!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)) {
4130 dayCnt++;
4131 }
4132 }
4133 if (!dayCnt) {
4134 throw new Error('invalid hiddenDays'); // all days were hidden? bad.
4135 }
4136 this.isHiddenDayHash = isHiddenDayHash;
4137 };
4138 // Remove days from the beginning and end of the range that are computed as hidden.
4139 // If the whole range is trimmed off, returns null
4140 View.prototype.trimHiddenDays = function (inputUnzonedRange) {
4141 var start = inputUnzonedRange.getStart();
4142 var end = inputUnzonedRange.getEnd();
4143 if (start) {
4144 start = this.skipHiddenDays(start);
4145 }
4146 if (end) {
4147 end = this.skipHiddenDays(end, -1, true);
4148 }
4149 if (start === null || end === null || start < end) {
4150 return new UnzonedRange_1.default(start, end);
4151 }
4152 return null;
4153 };
4154 // Is the current day hidden?
4155 // `day` is a day-of-week index (0-6), or a Moment
4156 View.prototype.isHiddenDay = function (day) {
4157 if (moment.isMoment(day)) {
4158 day = day.day();
4159 }
4160 return this.isHiddenDayHash[day];
4161 };
4162 // Incrementing the current day until it is no longer a hidden day, returning a copy.
4163 // DOES NOT CONSIDER validUnzonedRange!
4164 // If the initial value of `date` is not a hidden day, don't do anything.
4165 // Pass `isExclusive` as `true` if you are dealing with an end date.
4166 // `inc` defaults to `1` (increment one day forward each time)
4167 View.prototype.skipHiddenDays = function (date, inc, isExclusive) {
4168 if (inc === void 0) { inc = 1; }
4169 if (isExclusive === void 0) { isExclusive = false; }
4170 var out = date.clone();
4171 while (this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]) {
4172 out.add(inc, 'days');
4173 }
4174 return out;
4175 };
4176 return View;
4177 }(InteractiveDateComponent_1.default));
4178 exports.default = View;
4179 View.prototype.usesMinMaxTime = false;
4180 View.prototype.dateProfileGeneratorClass = DateProfileGenerator_1.default;
4181 View.watch('displayingDates', ['isInDom', 'dateProfile'], function (deps) {
4182 this.requestDateRender(deps.dateProfile);
4183 }, function () {
4184 this.requestDateUnrender();
4185 });
4186 View.watch('displayingBusinessHours', ['displayingDates', 'businessHourGenerator'], function (deps) {
4187 this.requestBusinessHoursRender(deps.businessHourGenerator);
4188 }, function () {
4189 this.requestBusinessHoursUnrender();
4190 });
4191 View.watch('initialEvents', ['dateProfile'], function (deps) {
4192 return this.fetchInitialEvents(deps.dateProfile);
4193 });
4194 View.watch('bindingEvents', ['initialEvents'], function (deps) {
4195 this.setEvents(deps.initialEvents);
4196 this.bindEventChanges();
4197 }, function () {
4198 this.unbindEventChanges();
4199 this.unsetEvents();
4200 });
4201 View.watch('displayingEvents', ['displayingDates', 'hasEvents'], function () {
4202 this.requestEventsRender(this.get('currentEvents'));
4203 }, function () {
4204 this.requestEventsUnrender();
4205 });
4206 View.watch('title', ['dateProfile'], function (deps) {
4207 return (this.title = this.computeTitle(deps.dateProfile)); // assign to View for legacy reasons
4208 });
4209 View.watch('legacyDateProps', ['dateProfile'], function (deps) {
4210 var calendar = this.calendar;
4211 var dateProfile = deps.dateProfile;
4212 // DEPRECATED, but we need to keep it updated...
4213 this.start = calendar.msToMoment(dateProfile.activeUnzonedRange.startMs, dateProfile.isRangeAllDay);
4214 this.end = calendar.msToMoment(dateProfile.activeUnzonedRange.endMs, dateProfile.isRangeAllDay);
4215 this.intervalStart = calendar.msToMoment(dateProfile.currentUnzonedRange.startMs, dateProfile.isRangeAllDay);
4216 this.intervalEnd = calendar.msToMoment(dateProfile.currentUnzonedRange.endMs, dateProfile.isRangeAllDay);
4217 });
4218
4219
4220 /***/ }),
4221 /* 42 */
4222 /***/ (function(module, exports, __webpack_require__) {
4223
4224 Object.defineProperty(exports, "__esModule", { value: true });
4225 var $ = __webpack_require__(3);
4226 var util_1 = __webpack_require__(4);
4227 var EventRenderer = /** @class */ (function () {
4228 function EventRenderer(component, fillRenderer) {
4229 this.view = component._getView();
4230 this.component = component;
4231 this.fillRenderer = fillRenderer;
4232 }
4233 EventRenderer.prototype.opt = function (name) {
4234 return this.view.opt(name);
4235 };
4236 // Updates values that rely on options and also relate to range
4237 EventRenderer.prototype.rangeUpdated = function () {
4238 var displayEventTime;
4239 var displayEventEnd;
4240 this.eventTimeFormat =
4241 this.opt('eventTimeFormat') ||
4242 this.opt('timeFormat') || // deprecated
4243 this.computeEventTimeFormat();
4244 displayEventTime = this.opt('displayEventTime');
4245 if (displayEventTime == null) {
4246 displayEventTime = this.computeDisplayEventTime(); // might be based off of range
4247 }
4248 displayEventEnd = this.opt('displayEventEnd');
4249 if (displayEventEnd == null) {
4250 displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
4251 }
4252 this.displayEventTime = displayEventTime;
4253 this.displayEventEnd = displayEventEnd;
4254 };
4255 EventRenderer.prototype.render = function (eventsPayload) {
4256 var dateProfile = this.component._getDateProfile();
4257 var eventDefId;
4258 var instanceGroup;
4259 var eventRanges;
4260 var bgRanges = [];
4261 var fgRanges = [];
4262 for (eventDefId in eventsPayload) {
4263 instanceGroup = eventsPayload[eventDefId];
4264 eventRanges = instanceGroup.sliceRenderRanges(dateProfile.activeUnzonedRange);
4265 if (instanceGroup.getEventDef().hasBgRendering()) {
4266 bgRanges.push.apply(bgRanges, eventRanges);
4267 }
4268 else {
4269 fgRanges.push.apply(fgRanges, eventRanges);
4270 }
4271 }
4272 this.renderBgRanges(bgRanges);
4273 this.renderFgRanges(fgRanges);
4274 };
4275 EventRenderer.prototype.unrender = function () {
4276 this.unrenderBgRanges();
4277 this.unrenderFgRanges();
4278 };
4279 EventRenderer.prototype.renderFgRanges = function (eventRanges) {
4280 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
4281 var segs = this.component.eventFootprintsToSegs(eventFootprints);
4282 // render an `.el` on each seg
4283 // returns a subset of the segs. segs that were actually rendered
4284 segs = this.renderFgSegEls(segs);
4285 if (this.renderFgSegs(segs) !== false) {
4286 this.fgSegs = segs;
4287 }
4288 };
4289 EventRenderer.prototype.unrenderFgRanges = function () {
4290 this.unrenderFgSegs(this.fgSegs || []);
4291 this.fgSegs = null;
4292 };
4293 EventRenderer.prototype.renderBgRanges = function (eventRanges) {
4294 var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
4295 var segs = this.component.eventFootprintsToSegs(eventFootprints);
4296 if (this.renderBgSegs(segs) !== false) {
4297 this.bgSegs = segs;
4298 }
4299 };
4300 EventRenderer.prototype.unrenderBgRanges = function () {
4301 this.unrenderBgSegs();
4302 this.bgSegs = null;
4303 };
4304 EventRenderer.prototype.getSegs = function () {
4305 return (this.bgSegs || []).concat(this.fgSegs || []);
4306 };
4307 // Renders foreground event segments onto the grid
4308 EventRenderer.prototype.renderFgSegs = function (segs) {
4309 // subclasses must implement
4310 // segs already has rendered els, and has been filtered.
4311 return false; // signal failure if not implemented
4312 };
4313 // Unrenders all currently rendered foreground segments
4314 EventRenderer.prototype.unrenderFgSegs = function (segs) {
4315 // subclasses must implement
4316 };
4317 EventRenderer.prototype.renderBgSegs = function (segs) {
4318 var _this = this;
4319 if (this.fillRenderer) {
4320 this.fillRenderer.renderSegs('bgEvent', segs, {
4321 getClasses: function (seg) {
4322 return _this.getBgClasses(seg.footprint.eventDef);
4323 },
4324 getCss: function (seg) {
4325 return {
4326 'background-color': _this.getBgColor(seg.footprint.eventDef)
4327 };
4328 },
4329 filterEl: function (seg, el) {
4330 return _this.filterEventRenderEl(seg.footprint, el);
4331 }
4332 });
4333 }
4334 else {
4335 return false; // signal failure if no fillRenderer
4336 }
4337 };
4338 EventRenderer.prototype.unrenderBgSegs = function () {
4339 if (this.fillRenderer) {
4340 this.fillRenderer.unrender('bgEvent');
4341 }
4342 };
4343 // Renders and assigns an `el` property for each foreground event segment.
4344 // Only returns segments that successfully rendered.
4345 EventRenderer.prototype.renderFgSegEls = function (segs, disableResizing) {
4346 var _this = this;
4347 if (disableResizing === void 0) { disableResizing = false; }
4348 var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender');
4349 var html = '';
4350 var renderedSegs = [];
4351 var i;
4352 if (segs.length) {
4353 // build a large concatenation of event segment HTML
4354 for (i = 0; i < segs.length; i++) {
4355 this.beforeFgSegHtml(segs[i]);
4356 html += this.fgSegHtml(segs[i], disableResizing);
4357 }
4358 // Grab individual elements from the combined HTML string. Use each as the default rendering.
4359 // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
4360 $(html).each(function (i, node) {
4361 var seg = segs[i];
4362 var el = $(node);
4363 if (hasEventRenderHandlers) {
4364 el = _this.filterEventRenderEl(seg.footprint, el);
4365 }
4366 if (el) {
4367 el.data('fc-seg', seg); // used by handlers
4368 seg.el = el;
4369 renderedSegs.push(seg);
4370 }
4371 });
4372 }
4373 return renderedSegs;
4374 };
4375 EventRenderer.prototype.beforeFgSegHtml = function (seg) {
4376 };
4377 // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()
4378 EventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
4379 // subclasses should implement
4380 };
4381 // Generic utility for generating the HTML classNames for an event segment's element
4382 EventRenderer.prototype.getSegClasses = function (seg, isDraggable, isResizable) {
4383 var classes = [
4384 'fc-event',
4385 seg.isStart ? 'fc-start' : 'fc-not-start',
4386 seg.isEnd ? 'fc-end' : 'fc-not-end'
4387 ].concat(this.getClasses(seg.footprint.eventDef));
4388 if (isDraggable) {
4389 classes.push('fc-draggable');
4390 }
4391 if (isResizable) {
4392 classes.push('fc-resizable');
4393 }
4394 // event is currently selected? attach a className.
4395 if (this.view.isEventDefSelected(seg.footprint.eventDef)) {
4396 classes.push('fc-selected');
4397 }
4398 return classes;
4399 };
4400 // Given an event and the default element used for rendering, returns the element that should actually be used.
4401 // Basically runs events and elements through the eventRender hook.
4402 EventRenderer.prototype.filterEventRenderEl = function (eventFootprint, el) {
4403 var legacy = eventFootprint.getEventLegacy();
4404 var custom = this.view.publiclyTrigger('eventRender', {
4405 context: legacy,
4406 args: [legacy, el, this.view]
4407 });
4408 if (custom === false) {
4409 el = null;
4410 }
4411 else if (custom && custom !== true) {
4412 el = $(custom);
4413 }
4414 return el;
4415 };
4416 // Compute the text that should be displayed on an event's element.
4417 // `range` can be the Event object itself, or something range-like, with at least a `start`.
4418 // If event times are disabled, or the event has no time, will return a blank string.
4419 // If not specified, formatStr will default to the eventTimeFormat setting,
4420 // and displayEnd will default to the displayEventEnd setting.
4421 EventRenderer.prototype.getTimeText = function (eventFootprint, formatStr, displayEnd) {
4422 return this._getTimeText(eventFootprint.eventInstance.dateProfile.start, eventFootprint.eventInstance.dateProfile.end, eventFootprint.componentFootprint.isAllDay, formatStr, displayEnd);
4423 };
4424 EventRenderer.prototype._getTimeText = function (start, end, isAllDay, formatStr, displayEnd) {
4425 if (formatStr == null) {
4426 formatStr = this.eventTimeFormat;
4427 }
4428 if (displayEnd == null) {
4429 displayEnd = this.displayEventEnd;
4430 }
4431 if (this.displayEventTime && !isAllDay) {
4432 if (displayEnd && end) {
4433 return this.view.formatRange({ start: start, end: end }, false, // allDay
4434 formatStr);
4435 }
4436 else {
4437 return start.format(formatStr);
4438 }
4439 }
4440 return '';
4441 };
4442 EventRenderer.prototype.computeEventTimeFormat = function () {
4443 return this.opt('smallTimeFormat');
4444 };
4445 EventRenderer.prototype.computeDisplayEventTime = function () {
4446 return true;
4447 };
4448 EventRenderer.prototype.computeDisplayEventEnd = function () {
4449 return true;
4450 };
4451 EventRenderer.prototype.getBgClasses = function (eventDef) {
4452 var classNames = this.getClasses(eventDef);
4453 classNames.push('fc-bgevent');
4454 return classNames;
4455 };
4456 EventRenderer.prototype.getClasses = function (eventDef) {
4457 var objs = this.getStylingObjs(eventDef);
4458 var i;
4459 var classNames = [];
4460 for (i = 0; i < objs.length; i++) {
4461 classNames.push.apply(// append
4462 classNames, objs[i].eventClassName || objs[i].className || []);
4463 }
4464 return classNames;
4465 };
4466 // Utility for generating event skin-related CSS properties
4467 EventRenderer.prototype.getSkinCss = function (eventDef) {
4468 return {
4469 'background-color': this.getBgColor(eventDef),
4470 'border-color': this.getBorderColor(eventDef),
4471 color: this.getTextColor(eventDef)
4472 };
4473 };
4474 // Queries for caller-specified color, then falls back to default
4475 EventRenderer.prototype.getBgColor = function (eventDef) {
4476 var objs = this.getStylingObjs(eventDef);
4477 var i;
4478 var val;
4479 for (i = 0; i < objs.length && !val; i++) {
4480 val = objs[i].eventBackgroundColor || objs[i].eventColor ||
4481 objs[i].backgroundColor || objs[i].color;
4482 }
4483 if (!val) {
4484 val = this.opt('eventBackgroundColor') || this.opt('eventColor');
4485 }
4486 return val;
4487 };
4488 // Queries for caller-specified color, then falls back to default
4489 EventRenderer.prototype.getBorderColor = function (eventDef) {
4490 var objs = this.getStylingObjs(eventDef);
4491 var i;
4492 var val;
4493 for (i = 0; i < objs.length && !val; i++) {
4494 val = objs[i].eventBorderColor || objs[i].eventColor ||
4495 objs[i].borderColor || objs[i].color;
4496 }
4497 if (!val) {
4498 val = this.opt('eventBorderColor') || this.opt('eventColor');
4499 }
4500 return val;
4501 };
4502 // Queries for caller-specified color, then falls back to default
4503 EventRenderer.prototype.getTextColor = function (eventDef) {
4504 var objs = this.getStylingObjs(eventDef);
4505 var i;
4506 var val;
4507 for (i = 0; i < objs.length && !val; i++) {
4508 val = objs[i].eventTextColor ||
4509 objs[i].textColor;
4510 }
4511 if (!val) {
4512 val = this.opt('eventTextColor');
4513 }
4514 return val;
4515 };
4516 EventRenderer.prototype.getStylingObjs = function (eventDef) {
4517 var objs = this.getFallbackStylingObjs(eventDef);
4518 objs.unshift(eventDef);
4519 return objs;
4520 };
4521 EventRenderer.prototype.getFallbackStylingObjs = function (eventDef) {
4522 return [eventDef.source];
4523 };
4524 EventRenderer.prototype.sortEventSegs = function (segs) {
4525 segs.sort(util_1.proxy(this, 'compareEventSegs'));
4526 };
4527 // A cmp function for determining which segments should take visual priority
4528 EventRenderer.prototype.compareEventSegs = function (seg1, seg2) {
4529 var f1 = seg1.footprint;
4530 var f2 = seg2.footprint;
4531 var cf1 = f1.componentFootprint;
4532 var cf2 = f2.componentFootprint;
4533 var r1 = cf1.unzonedRange;
4534 var r2 = cf2.unzonedRange;
4535 return r1.startMs - r2.startMs || // earlier events go first
4536 (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first
4537 cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1)
4538 util_1.compareByFieldSpecs(f1.eventDef, f2.eventDef, this.view.eventOrderSpecs, f1.eventDef.miscProps, f2.eventDef.miscProps);
4539 };
4540 return EventRenderer;
4541 }());
4542 exports.default = EventRenderer;
4543
4544
4545 /***/ }),
4546 /* 43 */,
4547 /* 44 */,
4548 /* 45 */,
4549 /* 46 */,
4550 /* 47 */
4551 /***/ (function(module, exports, __webpack_require__) {
4552
4553 Object.defineProperty(exports, "__esModule", { value: true });
4554 var moment_ext_1 = __webpack_require__(10);
4555 // Plugin
4556 // -------------------------------------------------------------------------------------------------
4557 moment_ext_1.newMomentProto.format = function () {
4558 if (this._fullCalendar && arguments[0]) {
4559 return formatDate(this, arguments[0]); // our extended formatting
4560 }
4561 if (this._ambigTime) {
4562 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4563 }
4564 if (this._ambigZone) {
4565 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4566 }
4567 if (this._fullCalendar) {
4568 // moment.format() doesn't ensure english, but we want to.
4569 return moment_ext_1.oldMomentFormat(englishMoment(this));
4570 }
4571 return moment_ext_1.oldMomentProto.format.apply(this, arguments);
4572 };
4573 moment_ext_1.newMomentProto.toISOString = function () {
4574 if (this._ambigTime) {
4575 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
4576 }
4577 if (this._ambigZone) {
4578 return moment_ext_1.oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
4579 }
4580 if (this._fullCalendar) {
4581 // depending on browser, moment might not output english. ensure english.
4582 // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22
4583 return moment_ext_1.oldMomentProto.toISOString.apply(englishMoment(this), arguments);
4584 }
4585 return moment_ext_1.oldMomentProto.toISOString.apply(this, arguments);
4586 };
4587 function englishMoment(mom) {
4588 if (mom.locale() !== 'en') {
4589 return mom.clone().locale('en');
4590 }
4591 return mom;
4592 }
4593 // Config
4594 // ---------------------------------------------------------------------------------------------------------------------
4595 /*
4596 Inserted between chunks in the fake ("intermediate") formatting string.
4597 Important that it passes as whitespace (\s) because moment often identifies non-standalone months
4598 via a regexp with an \s.
4599 */
4600 var PART_SEPARATOR = '\u000b'; // vertical tab
4601 /*
4602 Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text,
4603 but rather, a "special" token that has custom rendering (see specialTokens map).
4604 */
4605 var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1
4606 /*
4607 Inserted at the beginning and end of a span of text that must have non-zero numeric characters.
4608 Handling of these markers is done in a post-processing step at the very end of text rendering.
4609 */
4610 var MAYBE_MARKER = '\u001e'; // information separator 2
4611 var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global
4612 /*
4613 Addition formatting tokens we want recognized
4614 */
4615 var specialTokens = {
4616 t: function (date) {
4617 return moment_ext_1.oldMomentFormat(date, 'a').charAt(0);
4618 },
4619 T: function (date) {
4620 return moment_ext_1.oldMomentFormat(date, 'A').charAt(0);
4621 }
4622 };
4623 /*
4624 The first characters of formatting tokens for units that are 1 day or larger.
4625 `value` is for ranking relative size (lower means bigger).
4626 `unit` is a normalized unit, used for comparing moments.
4627 */
4628 var largeTokenMap = {
4629 Y: { value: 1, unit: 'year' },
4630 M: { value: 2, unit: 'month' },
4631 W: { value: 3, unit: 'week' },
4632 w: { value: 3, unit: 'week' },
4633 D: { value: 4, unit: 'day' },
4634 d: { value: 4, unit: 'day' } // day of week
4635 };
4636 // Single Date Formatting
4637 // ---------------------------------------------------------------------------------------------------------------------
4638 /*
4639 Formats `date` with a Moment formatting string, but allow our non-zero areas and special token
4640 */
4641 function formatDate(date, formatStr) {
4642 return renderFakeFormatString(getParsedFormatString(formatStr).fakeFormatString, date);
4643 }
4644 exports.formatDate = formatDate;
4645 // Date Range Formatting
4646 // -------------------------------------------------------------------------------------------------
4647 // TODO: make it work with timezone offset
4648 /*
4649 Using a formatting string meant for a single date, generate a range string, like
4650 "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
4651 If the dates are the same as far as the format string is concerned, just return a single
4652 rendering of one date, without any separator.
4653 */
4654 function formatRange(date1, date2, formatStr, separator, isRTL) {
4655 var localeData;
4656 date1 = moment_ext_1.default.parseZone(date1);
4657 date2 = moment_ext_1.default.parseZone(date2);
4658 localeData = date1.localeData();
4659 // Expand localized format strings, like "LL" -> "MMMM D YYYY".
4660 // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
4661 // or non-zero areas in Moment's localized format strings.
4662 formatStr = localeData.longDateFormat(formatStr) || formatStr;
4663 return renderParsedFormat(getParsedFormatString(formatStr), date1, date2, separator || ' - ', isRTL);
4664 }
4665 exports.formatRange = formatRange;
4666 /*
4667 Renders a range with an already-parsed format string.
4668 */
4669 function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
4670 var sameUnits = parsedFormat.sameUnits;
4671 var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons
4672 var unzonedDate2 = date2.clone().stripZone(); // "
4673 var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1);
4674 var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2);
4675 var leftI;
4676 var leftStr = '';
4677 var rightI;
4678 var rightStr = '';
4679 var middleI;
4680 var middleStr1 = '';
4681 var middleStr2 = '';
4682 var middleStr = '';
4683 // Start at the leftmost side of the formatting string and continue until you hit a token
4684 // that is not the same between dates.
4685 for (leftI = 0; leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI])); leftI++) {
4686 leftStr += renderedParts1[leftI];
4687 }
4688 // Similarly, start at the rightmost side of the formatting string and move left
4689 for (rightI = sameUnits.length - 1; rightI > leftI && (!sameUnits[rightI] || unzonedDate1.isSame(unzonedDate2, sameUnits[rightI])); rightI--) {
4690 // If current chunk is on the boundary of unique date-content, and is a special-case
4691 // date-formatting postfix character, then don't consume it. Consider it unique date-content.
4692 // TODO: make configurable
4693 if (rightI - 1 === leftI && renderedParts1[rightI] === '.') {
4694 break;
4695 }
4696 rightStr = renderedParts1[rightI] + rightStr;
4697 }
4698 // The area in the middle is different for both of the dates.
4699 // Collect them distinctly so we can jam them together later.
4700 for (middleI = leftI; middleI <= rightI; middleI++) {
4701 middleStr1 += renderedParts1[middleI];
4702 middleStr2 += renderedParts2[middleI];
4703 }
4704 if (middleStr1 || middleStr2) {
4705 if (isRTL) {
4706 middleStr = middleStr2 + separator + middleStr1;
4707 }
4708 else {
4709 middleStr = middleStr1 + separator + middleStr2;
4710 }
4711 }
4712 return processMaybeMarkers(leftStr + middleStr + rightStr);
4713 }
4714 // Format String Parsing
4715 // ---------------------------------------------------------------------------------------------------------------------
4716 var parsedFormatStrCache = {};
4717 /*
4718 Returns a parsed format string, leveraging a cache.
4719 */
4720 function getParsedFormatString(formatStr) {
4721 return parsedFormatStrCache[formatStr] ||
4722 (parsedFormatStrCache[formatStr] = parseFormatString(formatStr));
4723 }
4724 /*
4725 Parses a format string into the following:
4726 - fakeFormatString: a momentJS formatting string, littered with special control characters that get post-processed.
4727 - sameUnits: for every part in fakeFormatString, if the part is a token, the value will be a unit string (like "day"),
4728 that indicates how similar a range's start & end must be in order to share the same formatted text.
4729 If not a token, then the value is null.
4730 Always a flat array (not nested liked "chunks").
4731 */
4732 function parseFormatString(formatStr) {
4733 var chunks = chunkFormatString(formatStr);
4734 return {
4735 fakeFormatString: buildFakeFormatString(chunks),
4736 sameUnits: buildSameUnits(chunks)
4737 };
4738 }
4739 /*
4740 Break the formatting string into an array of chunks.
4741 A 'maybe' chunk will have nested chunks.
4742 */
4743 function chunkFormatString(formatStr) {
4744 var chunks = [];
4745 var match;
4746 // TODO: more descrimination
4747 // \4 is a backreference to the first character of a multi-character set.
4748 var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;
4749 while ((match = chunker.exec(formatStr))) {
4750 if (match[1]) {
4751 chunks.push.apply(chunks, // append
4752 splitStringLiteral(match[1]));
4753 }
4754 else if (match[2]) {
4755 chunks.push({ maybe: chunkFormatString(match[2]) });
4756 }
4757 else if (match[3]) {
4758 chunks.push({ token: match[3] });
4759 }
4760 else if (match[5]) {
4761 chunks.push.apply(chunks, // append
4762 splitStringLiteral(match[5]));
4763 }
4764 }
4765 return chunks;
4766 }
4767 /*
4768 Potentially splits a literal-text string into multiple parts. For special cases.
4769 */
4770 function splitStringLiteral(s) {
4771 if (s === '. ') {
4772 return ['.', ' ']; // for locales with periods bound to the end of each year/month/date
4773 }
4774 else {
4775 return [s];
4776 }
4777 }
4778 /*
4779 Given chunks parsed from a real format string, generate a fake (aka "intermediate") format string with special control
4780 characters that will eventually be given to moment for formatting, and then post-processed.
4781 */
4782 function buildFakeFormatString(chunks) {
4783 var parts = [];
4784 var i;
4785 var chunk;
4786 for (i = 0; i < chunks.length; i++) {
4787 chunk = chunks[i];
4788 if (typeof chunk === 'string') {
4789 parts.push('[' + chunk + ']');
4790 }
4791 else if (chunk.token) {
4792 if (chunk.token in specialTokens) {
4793 parts.push(SPECIAL_TOKEN_MARKER + // useful during post-processing
4794 '[' + chunk.token + ']' // preserve as literal text
4795 );
4796 }
4797 else {
4798 parts.push(chunk.token); // unprotected text implies a format string
4799 }
4800 }
4801 else if (chunk.maybe) {
4802 parts.push(MAYBE_MARKER + // useful during post-processing
4803 buildFakeFormatString(chunk.maybe) +
4804 MAYBE_MARKER);
4805 }
4806 }
4807 return parts.join(PART_SEPARATOR);
4808 }
4809 /*
4810 Given parsed chunks from a real formatting string, generates an array of unit strings (like "day") that indicate
4811 in which regard two dates must be similar in order to share range formatting text.
4812 The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat.
4813 */
4814 function buildSameUnits(chunks) {
4815 var units = [];
4816 var i;
4817 var chunk;
4818 var tokenInfo;
4819 for (i = 0; i < chunks.length; i++) {
4820 chunk = chunks[i];
4821 if (chunk.token) {
4822 tokenInfo = largeTokenMap[chunk.token.charAt(0)];
4823 units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second
4824 }
4825 else if (chunk.maybe) {
4826 units.push.apply(units, // append
4827 buildSameUnits(chunk.maybe));
4828 }
4829 else {
4830 units.push(null);
4831 }
4832 }
4833 return units;
4834 }
4835 // Rendering to text
4836 // ---------------------------------------------------------------------------------------------------------------------
4837 /*
4838 Formats a date with a fake format string, post-processes the control characters, then returns.
4839 */
4840 function renderFakeFormatString(fakeFormatString, date) {
4841 return processMaybeMarkers(renderFakeFormatStringParts(fakeFormatString, date).join(''));
4842 }
4843 /*
4844 Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers.
4845 */
4846 function renderFakeFormatStringParts(fakeFormatString, date) {
4847 var parts = [];
4848 var fakeRender = moment_ext_1.oldMomentFormat(date, fakeFormatString);
4849 var fakeParts = fakeRender.split(PART_SEPARATOR);
4850 var i;
4851 var fakePart;
4852 for (i = 0; i < fakeParts.length; i++) {
4853 fakePart = fakeParts[i];
4854 if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) {
4855 parts.push(
4856 // the literal string IS the token's name.
4857 // call special token's registered function.
4858 specialTokens[fakePart.substring(1)](date));
4859 }
4860 else {
4861 parts.push(fakePart);
4862 }
4863 }
4864 return parts;
4865 }
4866 /*
4867 Accepts an almost-finally-formatted string and processes the "maybe" control characters, returning a new string.
4868 */
4869 function processMaybeMarkers(s) {
4870 return s.replace(MAYBE_REGEXP, function (m0, m1) {
4871 if (m1.match(/[1-9]/)) {
4872 return m1;
4873 }
4874 else {
4875 return '';
4876 }
4877 });
4878 }
4879 // Misc Utils
4880 // -------------------------------------------------------------------------------------------------
4881 /*
4882 Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string.
4883 */
4884 function queryMostGranularFormatUnit(formatStr) {
4885 var chunks = chunkFormatString(formatStr);
4886 var i;
4887 var chunk;
4888 var candidate;
4889 var best;
4890 for (i = 0; i < chunks.length; i++) {
4891 chunk = chunks[i];
4892 if (chunk.token) {
4893 candidate = largeTokenMap[chunk.token.charAt(0)];
4894 if (candidate) {
4895 if (!best || candidate.value > best.value) {
4896 best = candidate;
4897 }
4898 }
4899 }
4900 }
4901 if (best) {
4902 return best.unit;
4903 }
4904 return null;
4905 }
4906 exports.queryMostGranularFormatUnit = queryMostGranularFormatUnit;
4907
4908
4909 /***/ }),
4910 /* 48 */
4911 /***/ (function(module, exports, __webpack_require__) {
4912
4913 Object.defineProperty(exports, "__esModule", { value: true });
4914 var tslib_1 = __webpack_require__(2);
4915 var Class_1 = __webpack_require__(33);
4916 var EmitterMixin_1 = __webpack_require__(11);
4917 var ListenerMixin_1 = __webpack_require__(7);
4918 var Model = /** @class */ (function (_super) {
4919 tslib_1.__extends(Model, _super);
4920 function Model() {
4921 var _this = _super.call(this) || this;
4922 _this._watchers = {};
4923 _this._props = {};
4924 _this.applyGlobalWatchers();
4925 _this.constructed();
4926 return _this;
4927 }
4928 Model.watch = function (name) {
4929 var args = [];
4930 for (var _i = 1; _i < arguments.length; _i++) {
4931 args[_i - 1] = arguments[_i];
4932 }
4933 // subclasses should make a masked-copy of the superclass's map
4934 // TODO: write test
4935 if (!this.prototype.hasOwnProperty('_globalWatchArgs')) {
4936 this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs);
4937 }
4938 this.prototype._globalWatchArgs[name] = args;
4939 };
4940 Model.prototype.constructed = function () {
4941 // useful for monkeypatching. TODO: BaseClass?
4942 };
4943 Model.prototype.applyGlobalWatchers = function () {
4944 var map = this._globalWatchArgs;
4945 var name;
4946 for (name in map) {
4947 this.watch.apply(this, [name].concat(map[name]));
4948 }
4949 };
4950 Model.prototype.has = function (name) {
4951 return name in this._props;
4952 };
4953 Model.prototype.get = function (name) {
4954 if (name === undefined) {
4955 return this._props;
4956 }
4957 return this._props[name];
4958 };
4959 Model.prototype.set = function (name, val) {
4960 var newProps;
4961 if (typeof name === 'string') {
4962 newProps = {};
4963 newProps[name] = val === undefined ? null : val;
4964 }
4965 else {
4966 newProps = name;
4967 }
4968 this.setProps(newProps);
4969 };
4970 Model.prototype.reset = function (newProps) {
4971 var oldProps = this._props;
4972 var changeset = {}; // will have undefined's to signal unsets
4973 var name;
4974 for (name in oldProps) {
4975 changeset[name] = undefined;
4976 }
4977 for (name in newProps) {
4978 changeset[name] = newProps[name];
4979 }
4980 this.setProps(changeset);
4981 };
4982 Model.prototype.unset = function (name) {
4983 var newProps = {};
4984 var names;
4985 var i;
4986 if (typeof name === 'string') {
4987 names = [name];
4988 }
4989 else {
4990 names = name;
4991 }
4992 for (i = 0; i < names.length; i++) {
4993 newProps[names[i]] = undefined;
4994 }
4995 this.setProps(newProps);
4996 };
4997 Model.prototype.setProps = function (newProps) {
4998 var changedProps = {};
4999 var changedCnt = 0;
5000 var name;
5001 var val;
5002 for (name in newProps) {
5003 val = newProps[name];
5004 // a change in value?
5005 // if an object, don't check equality, because might have been mutated internally.
5006 // TODO: eventually enforce immutability.
5007 if (typeof val === 'object' ||
5008 val !== this._props[name]) {
5009 changedProps[name] = val;
5010 changedCnt++;
5011 }
5012 }
5013 if (changedCnt) {
5014 this.trigger('before:batchChange', changedProps);
5015 for (name in changedProps) {
5016 val = changedProps[name];
5017 this.trigger('before:change', name, val);
5018 this.trigger('before:change:' + name, val);
5019 }
5020 for (name in changedProps) {
5021 val = changedProps[name];
5022 if (val === undefined) {
5023 delete this._props[name];
5024 }
5025 else {
5026 this._props[name] = val;
5027 }
5028 this.trigger('change:' + name, val);
5029 this.trigger('change', name, val);
5030 }
5031 this.trigger('batchChange', changedProps);
5032 }
5033 };
5034 Model.prototype.watch = function (name, depList, startFunc, stopFunc) {
5035 var _this = this;
5036 this.unwatch(name);
5037 this._watchers[name] = this._watchDeps(depList, function (deps) {
5038 var res = startFunc.call(_this, deps);
5039 if (res && res.then) {
5040 _this.unset(name); // put in an unset state while resolving
5041 res.then(function (val) {
5042 _this.set(name, val);
5043 });
5044 }
5045 else {
5046 _this.set(name, res);
5047 }
5048 }, function (deps) {
5049 _this.unset(name);
5050 if (stopFunc) {
5051 stopFunc.call(_this, deps);
5052 }
5053 });
5054 };
5055 Model.prototype.unwatch = function (name) {
5056 var watcher = this._watchers[name];
5057 if (watcher) {
5058 delete this._watchers[name];
5059 watcher.teardown();
5060 }
5061 };
5062 Model.prototype._watchDeps = function (depList, startFunc, stopFunc) {
5063 var _this = this;
5064 var queuedChangeCnt = 0;
5065 var depCnt = depList.length;
5066 var satisfyCnt = 0;
5067 var values = {}; // what's passed as the `deps` arguments
5068 var bindTuples = []; // array of [ eventName, handlerFunc ] arrays
5069 var isCallingStop = false;
5070 var onBeforeDepChange = function (depName, val, isOptional) {
5071 queuedChangeCnt++;
5072 if (queuedChangeCnt === 1) {
5073 if (satisfyCnt === depCnt) {
5074 isCallingStop = true;
5075 stopFunc(values);
5076 isCallingStop = false;
5077 }
5078 }
5079 };
5080 var onDepChange = function (depName, val, isOptional) {
5081 if (val === undefined) {
5082 // required dependency that was previously set?
5083 if (!isOptional && values[depName] !== undefined) {
5084 satisfyCnt--;
5085 }
5086 delete values[depName];
5087 }
5088 else {
5089 // required dependency that was previously unset?
5090 if (!isOptional && values[depName] === undefined) {
5091 satisfyCnt++;
5092 }
5093 values[depName] = val;
5094 }
5095 queuedChangeCnt--;
5096 if (!queuedChangeCnt) {
5097 // now finally satisfied or satisfied all along?
5098 if (satisfyCnt === depCnt) {
5099 // if the stopFunc initiated another value change, ignore it.
5100 // it will be processed by another change event anyway.
5101 if (!isCallingStop) {
5102 startFunc(values);
5103 }
5104 }
5105 }
5106 };
5107 // intercept for .on() that remembers handlers
5108 var bind = function (eventName, handler) {
5109 _this.on(eventName, handler);
5110 bindTuples.push([eventName, handler]);
5111 };
5112 // listen to dependency changes
5113 depList.forEach(function (depName) {
5114 var isOptional = false;
5115 if (depName.charAt(0) === '?') {
5116 depName = depName.substring(1);
5117 isOptional = true;
5118 }
5119 bind('before:change:' + depName, function (val) {
5120 onBeforeDepChange(depName, val, isOptional);
5121 });
5122 bind('change:' + depName, function (val) {
5123 onDepChange(depName, val, isOptional);
5124 });
5125 });
5126 // process current dependency values
5127 depList.forEach(function (depName) {
5128 var isOptional = false;
5129 if (depName.charAt(0) === '?') {
5130 depName = depName.substring(1);
5131 isOptional = true;
5132 }
5133 if (_this.has(depName)) {
5134 values[depName] = _this.get(depName);
5135 satisfyCnt++;
5136 }
5137 else if (isOptional) {
5138 satisfyCnt++;
5139 }
5140 });
5141 // initially satisfied
5142 if (satisfyCnt === depCnt) {
5143 startFunc(values);
5144 }
5145 return {
5146 teardown: function () {
5147 // remove all handlers
5148 for (var i = 0; i < bindTuples.length; i++) {
5149 _this.off(bindTuples[i][0], bindTuples[i][1]);
5150 }
5151 bindTuples = null;
5152 // was satisfied, so call stopFunc
5153 if (satisfyCnt === depCnt) {
5154 stopFunc();
5155 }
5156 },
5157 flash: function () {
5158 if (satisfyCnt === depCnt) {
5159 stopFunc();
5160 startFunc(values);
5161 }
5162 }
5163 };
5164 };
5165 Model.prototype.flash = function (name) {
5166 var watcher = this._watchers[name];
5167 if (watcher) {
5168 watcher.flash();
5169 }
5170 };
5171 return Model;
5172 }(Class_1.default));
5173 exports.default = Model;
5174 Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch
5175 EmitterMixin_1.default.mixInto(Model);
5176 ListenerMixin_1.default.mixInto(Model);
5177
5178
5179 /***/ }),
5180 /* 49 */
5181 /***/ (function(module, exports, __webpack_require__) {
5182
5183 Object.defineProperty(exports, "__esModule", { value: true });
5184 var moment = __webpack_require__(0);
5185 var util_1 = __webpack_require__(4);
5186 var SingleEventDef_1 = __webpack_require__(13);
5187 var RecurringEventDef_1 = __webpack_require__(210);
5188 exports.default = {
5189 parse: function (eventInput, source) {
5190 if (util_1.isTimeString(eventInput.start) || moment.isDuration(eventInput.start) ||
5191 util_1.isTimeString(eventInput.end) || moment.isDuration(eventInput.end)) {
5192 return RecurringEventDef_1.default.parse(eventInput, source);
5193 }
5194 else {
5195 return SingleEventDef_1.default.parse(eventInput, source);
5196 }
5197 }
5198 };
5199
5200
5201 /***/ }),
5202 /* 50 */
5203 /***/ (function(module, exports, __webpack_require__) {
5204
5205 Object.defineProperty(exports, "__esModule", { value: true });
5206 var util_1 = __webpack_require__(4);
5207 var EventDateProfile_1 = __webpack_require__(17);
5208 var EventDefDateMutation = /** @class */ (function () {
5209 function EventDefDateMutation() {
5210 this.clearEnd = false;
5211 this.forceTimed = false;
5212 this.forceAllDay = false;
5213 }
5214 EventDefDateMutation.createFromDiff = function (dateProfile0, dateProfile1, largeUnit) {
5215 var clearEnd = dateProfile0.end && !dateProfile1.end;
5216 var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay();
5217 var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay();
5218 var dateDelta;
5219 var endDiff;
5220 var endDelta;
5221 var mutation;
5222 // subtracts the dates in the appropriate way, returning a duration
5223 function subtractDates(date1, date0) {
5224 if (largeUnit) {
5225 return util_1.diffByUnit(date1, date0, largeUnit); // poorly named
5226 }
5227 else if (dateProfile1.isAllDay()) {
5228 return util_1.diffDay(date1, date0); // poorly named
5229 }
5230 else {
5231 return util_1.diffDayTime(date1, date0); // poorly named
5232 }
5233 }
5234 dateDelta = subtractDates(dateProfile1.start, dateProfile0.start);
5235 if (dateProfile1.end) {
5236 // use unzonedRanges because dateProfile0.end might be null
5237 endDiff = subtractDates(dateProfile1.unzonedRange.getEnd(), dateProfile0.unzonedRange.getEnd());
5238 endDelta = endDiff.subtract(dateDelta);
5239 }
5240 mutation = new EventDefDateMutation();
5241 mutation.clearEnd = clearEnd;
5242 mutation.forceTimed = forceTimed;
5243 mutation.forceAllDay = forceAllDay;
5244 mutation.setDateDelta(dateDelta);
5245 mutation.setEndDelta(endDelta);
5246 return mutation;
5247 };
5248 /*
5249 returns an undo function.
5250 */
5251 EventDefDateMutation.prototype.buildNewDateProfile = function (eventDateProfile, calendar) {
5252 var start = eventDateProfile.start.clone();
5253 var end = null;
5254 var shouldRezone = false;
5255 if (eventDateProfile.end && !this.clearEnd) {
5256 end = eventDateProfile.end.clone();
5257 }
5258 else if (this.endDelta && !end) {
5259 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
5260 }
5261 if (this.forceTimed) {
5262 shouldRezone = true;
5263 if (!start.hasTime()) {
5264 start.time(0);
5265 }
5266 if (end && !end.hasTime()) {
5267 end.time(0);
5268 }
5269 }
5270 else if (this.forceAllDay) {
5271 if (start.hasTime()) {
5272 start.stripTime();
5273 }
5274 if (end && end.hasTime()) {
5275 end.stripTime();
5276 }
5277 }
5278 if (this.dateDelta) {
5279 shouldRezone = true;
5280 start.add(this.dateDelta);
5281 if (end) {
5282 end.add(this.dateDelta);
5283 }
5284 }
5285 // do this before adding startDelta to start, so we can work off of start
5286 if (this.endDelta) {
5287 shouldRezone = true;
5288 end.add(this.endDelta);
5289 }
5290 if (this.startDelta) {
5291 shouldRezone = true;
5292 start.add(this.startDelta);
5293 }
5294 if (shouldRezone) {
5295 start = calendar.applyTimezone(start);
5296 if (end) {
5297 end = calendar.applyTimezone(end);
5298 }
5299 }
5300 // TODO: okay to access calendar option?
5301 if (!end && calendar.opt('forceEventDuration')) {
5302 end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
5303 }
5304 return new EventDateProfile_1.default(start, end, calendar);
5305 };
5306 EventDefDateMutation.prototype.setDateDelta = function (dateDelta) {
5307 if (dateDelta && dateDelta.valueOf()) {
5308 this.dateDelta = dateDelta;
5309 }
5310 else {
5311 this.dateDelta = null;
5312 }
5313 };
5314 EventDefDateMutation.prototype.setStartDelta = function (startDelta) {
5315 if (startDelta && startDelta.valueOf()) {
5316 this.startDelta = startDelta;
5317 }
5318 else {
5319 this.startDelta = null;
5320 }
5321 };
5322 EventDefDateMutation.prototype.setEndDelta = function (endDelta) {
5323 if (endDelta && endDelta.valueOf()) {
5324 this.endDelta = endDelta;
5325 }
5326 else {
5327 this.endDelta = null;
5328 }
5329 };
5330 EventDefDateMutation.prototype.isEmpty = function () {
5331 return !this.clearEnd && !this.forceTimed && !this.forceAllDay &&
5332 !this.dateDelta && !this.startDelta && !this.endDelta;
5333 };
5334 return EventDefDateMutation;
5335 }());
5336 exports.default = EventDefDateMutation;
5337
5338
5339 /***/ }),
5340 /* 51 */
5341 /***/ (function(module, exports, __webpack_require__) {
5342
5343 Object.defineProperty(exports, "__esModule", { value: true });
5344 var StandardTheme_1 = __webpack_require__(213);
5345 var JqueryUiTheme_1 = __webpack_require__(214);
5346 var themeClassHash = {};
5347 function defineThemeSystem(themeName, themeClass) {
5348 themeClassHash[themeName] = themeClass;
5349 }
5350 exports.defineThemeSystem = defineThemeSystem;
5351 function getThemeSystemClass(themeSetting) {
5352 if (!themeSetting) {
5353 return StandardTheme_1.default;
5354 }
5355 else if (themeSetting === true) {
5356 return JqueryUiTheme_1.default;
5357 }
5358 else {
5359 return themeClassHash[themeSetting];
5360 }
5361 }
5362 exports.getThemeSystemClass = getThemeSystemClass;
5363
5364
5365 /***/ }),
5366 /* 52 */
5367 /***/ (function(module, exports, __webpack_require__) {
5368
5369 Object.defineProperty(exports, "__esModule", { value: true });
5370 var tslib_1 = __webpack_require__(2);
5371 var $ = __webpack_require__(3);
5372 var util_1 = __webpack_require__(4);
5373 var Promise_1 = __webpack_require__(20);
5374 var EventSource_1 = __webpack_require__(6);
5375 var SingleEventDef_1 = __webpack_require__(13);
5376 var ArrayEventSource = /** @class */ (function (_super) {
5377 tslib_1.__extends(ArrayEventSource, _super);
5378 function ArrayEventSource(calendar) {
5379 var _this = _super.call(this, calendar) || this;
5380 _this.eventDefs = []; // for if setRawEventDefs is never called
5381 return _this;
5382 }
5383 ArrayEventSource.parse = function (rawInput, calendar) {
5384 var rawProps;
5385 // normalize raw input
5386 if ($.isArray(rawInput.events)) {
5387 rawProps = rawInput;
5388 }
5389 else if ($.isArray(rawInput)) {
5390 rawProps = { events: rawInput };
5391 }
5392 if (rawProps) {
5393 return EventSource_1.default.parse.call(this, rawProps, calendar);
5394 }
5395 return false;
5396 };
5397 ArrayEventSource.prototype.setRawEventDefs = function (rawEventDefs) {
5398 this.rawEventDefs = rawEventDefs;
5399 this.eventDefs = this.parseEventDefs(rawEventDefs);
5400 };
5401 ArrayEventSource.prototype.fetch = function (start, end, timezone) {
5402 var eventDefs = this.eventDefs;
5403 var i;
5404 if (this.currentTimezone != null &&
5405 this.currentTimezone !== timezone) {
5406 for (i = 0; i < eventDefs.length; i++) {
5407 if (eventDefs[i] instanceof SingleEventDef_1.default) {
5408 eventDefs[i].rezone();
5409 }
5410 }
5411 }
5412 this.currentTimezone = timezone;
5413 return Promise_1.default.resolve(eventDefs);
5414 };
5415 ArrayEventSource.prototype.addEventDef = function (eventDef) {
5416 this.eventDefs.push(eventDef);
5417 };
5418 /*
5419 eventDefId already normalized to a string
5420 */
5421 ArrayEventSource.prototype.removeEventDefsById = function (eventDefId) {
5422 return util_1.removeMatching(this.eventDefs, function (eventDef) {
5423 return eventDef.id === eventDefId;
5424 });
5425 };
5426 ArrayEventSource.prototype.removeAllEventDefs = function () {
5427 this.eventDefs = [];
5428 };
5429 ArrayEventSource.prototype.getPrimitive = function () {
5430 return this.rawEventDefs;
5431 };
5432 ArrayEventSource.prototype.applyManualStandardProps = function (rawProps) {
5433 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
5434 this.setRawEventDefs(rawProps.events);
5435 return superSuccess;
5436 };
5437 return ArrayEventSource;
5438 }(EventSource_1.default));
5439 exports.default = ArrayEventSource;
5440 ArrayEventSource.defineStandardProps({
5441 events: false // don't automatically transfer
5442 });
5443
5444
5445 /***/ }),
5446 /* 53 */
5447 /***/ (function(module, exports, __webpack_require__) {
5448
5449 Object.defineProperty(exports, "__esModule", { value: true });
5450 var $ = __webpack_require__(3);
5451 var util_1 = __webpack_require__(4);
5452 /*
5453 A cache for the left/right/top/bottom/width/height values for one or more elements.
5454 Works with both offset (from topleft document) and position (from offsetParent).
5455
5456 options:
5457 - els
5458 - isHorizontal
5459 - isVertical
5460 */
5461 var CoordCache = /** @class */ (function () {
5462 function CoordCache(options) {
5463 this.isHorizontal = false; // whether to query for left/right/width
5464 this.isVertical = false; // whether to query for top/bottom/height
5465 this.els = $(options.els);
5466 this.isHorizontal = options.isHorizontal;
5467 this.isVertical = options.isVertical;
5468 this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null;
5469 }
5470 // Queries the els for coordinates and stores them.
5471 // Call this method before using and of the get* methods below.
5472 CoordCache.prototype.build = function () {
5473 var offsetParentEl = this.forcedOffsetParentEl;
5474 if (!offsetParentEl && this.els.length > 0) {
5475 offsetParentEl = this.els.eq(0).offsetParent();
5476 }
5477 this.origin = offsetParentEl ?
5478 offsetParentEl.offset() :
5479 null;
5480 this.boundingRect = this.queryBoundingRect();
5481 if (this.isHorizontal) {
5482 this.buildElHorizontals();
5483 }
5484 if (this.isVertical) {
5485 this.buildElVerticals();
5486 }
5487 };
5488 // Destroys all internal data about coordinates, freeing memory
5489 CoordCache.prototype.clear = function () {
5490 this.origin = null;
5491 this.boundingRect = null;
5492 this.lefts = null;
5493 this.rights = null;
5494 this.tops = null;
5495 this.bottoms = null;
5496 };
5497 // When called, if coord caches aren't built, builds them
5498 CoordCache.prototype.ensureBuilt = function () {
5499 if (!this.origin) {
5500 this.build();
5501 }
5502 };
5503 // Populates the left/right internal coordinate arrays
5504 CoordCache.prototype.buildElHorizontals = function () {
5505 var lefts = [];
5506 var rights = [];
5507 this.els.each(function (i, node) {
5508 var el = $(node);
5509 var left = el.offset().left;
5510 var width = el.outerWidth();
5511 lefts.push(left);
5512 rights.push(left + width);
5513 });
5514 this.lefts = lefts;
5515 this.rights = rights;
5516 };
5517 // Populates the top/bottom internal coordinate arrays
5518 CoordCache.prototype.buildElVerticals = function () {
5519 var tops = [];
5520 var bottoms = [];
5521 this.els.each(function (i, node) {
5522 var el = $(node);
5523 var top = el.offset().top;
5524 var height = el.outerHeight();
5525 tops.push(top);
5526 bottoms.push(top + height);
5527 });
5528 this.tops = tops;
5529 this.bottoms = bottoms;
5530 };
5531 // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
5532 // If no intersection is made, returns undefined.
5533 CoordCache.prototype.getHorizontalIndex = function (leftOffset) {
5534 this.ensureBuilt();
5535 var lefts = this.lefts;
5536 var rights = this.rights;
5537 var len = lefts.length;
5538 var i;
5539 for (i = 0; i < len; i++) {
5540 if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
5541 return i;
5542 }
5543 }
5544 };
5545 // Given a top offset (from document top), returns the index of the el that it vertically intersects.
5546 // If no intersection is made, returns undefined.
5547 CoordCache.prototype.getVerticalIndex = function (topOffset) {
5548 this.ensureBuilt();
5549 var tops = this.tops;
5550 var bottoms = this.bottoms;
5551 var len = tops.length;
5552 var i;
5553 for (i = 0; i < len; i++) {
5554 if (topOffset >= tops[i] && topOffset < bottoms[i]) {
5555 return i;
5556 }
5557 }
5558 };
5559 // Gets the left offset (from document left) of the element at the given index
5560 CoordCache.prototype.getLeftOffset = function (leftIndex) {
5561 this.ensureBuilt();
5562 return this.lefts[leftIndex];
5563 };
5564 // Gets the left position (from offsetParent left) of the element at the given index
5565 CoordCache.prototype.getLeftPosition = function (leftIndex) {
5566 this.ensureBuilt();
5567 return this.lefts[leftIndex] - this.origin.left;
5568 };
5569 // Gets the right offset (from document left) of the element at the given index.
5570 // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be.
5571 CoordCache.prototype.getRightOffset = function (leftIndex) {
5572 this.ensureBuilt();
5573 return this.rights[leftIndex];
5574 };
5575 // Gets the right position (from offsetParent left) of the element at the given index.
5576 // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be.
5577 CoordCache.prototype.getRightPosition = function (leftIndex) {
5578 this.ensureBuilt();
5579 return this.rights[leftIndex] - this.origin.left;
5580 };
5581 // Gets the width of the element at the given index
5582 CoordCache.prototype.getWidth = function (leftIndex) {
5583 this.ensureBuilt();
5584 return this.rights[leftIndex] - this.lefts[leftIndex];
5585 };
5586 // Gets the top offset (from document top) of the element at the given index
5587 CoordCache.prototype.getTopOffset = function (topIndex) {
5588 this.ensureBuilt();
5589 return this.tops[topIndex];
5590 };
5591 // Gets the top position (from offsetParent top) of the element at the given position
5592 CoordCache.prototype.getTopPosition = function (topIndex) {
5593 this.ensureBuilt();
5594 return this.tops[topIndex] - this.origin.top;
5595 };
5596 // Gets the bottom offset (from the document top) of the element at the given index.
5597 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
5598 CoordCache.prototype.getBottomOffset = function (topIndex) {
5599 this.ensureBuilt();
5600 return this.bottoms[topIndex];
5601 };
5602 // Gets the bottom position (from the offsetParent top) of the element at the given index.
5603 // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
5604 CoordCache.prototype.getBottomPosition = function (topIndex) {
5605 this.ensureBuilt();
5606 return this.bottoms[topIndex] - this.origin.top;
5607 };
5608 // Gets the height of the element at the given index
5609 CoordCache.prototype.getHeight = function (topIndex) {
5610 this.ensureBuilt();
5611 return this.bottoms[topIndex] - this.tops[topIndex];
5612 };
5613 // Bounding Rect
5614 // TODO: decouple this from CoordCache
5615 // Compute and return what the elements' bounding rectangle is, from the user's perspective.
5616 // Right now, only returns a rectangle if constrained by an overflow:scroll element.
5617 // Returns null if there are no elements
5618 CoordCache.prototype.queryBoundingRect = function () {
5619 var scrollParentEl;
5620 if (this.els.length > 0) {
5621 scrollParentEl = util_1.getScrollParent(this.els.eq(0));
5622 if (!scrollParentEl.is(document)) {
5623 return util_1.getClientRect(scrollParentEl);
5624 }
5625 }
5626 return null;
5627 };
5628 CoordCache.prototype.isPointInBounds = function (leftOffset, topOffset) {
5629 return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset);
5630 };
5631 CoordCache.prototype.isLeftInBounds = function (leftOffset) {
5632 return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right);
5633 };
5634 CoordCache.prototype.isTopInBounds = function (topOffset) {
5635 return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom);
5636 };
5637 return CoordCache;
5638 }());
5639 exports.default = CoordCache;
5640
5641
5642 /***/ }),
5643 /* 54 */
5644 /***/ (function(module, exports, __webpack_require__) {
5645
5646 Object.defineProperty(exports, "__esModule", { value: true });
5647 var $ = __webpack_require__(3);
5648 var util_1 = __webpack_require__(4);
5649 var ListenerMixin_1 = __webpack_require__(7);
5650 var GlobalEmitter_1 = __webpack_require__(21);
5651 /* Tracks a drag's mouse movement, firing various handlers
5652 ----------------------------------------------------------------------------------------------------------------------*/
5653 // TODO: use Emitter
5654 var DragListener = /** @class */ (function () {
5655 function DragListener(options) {
5656 this.isInteracting = false;
5657 this.isDistanceSurpassed = false;
5658 this.isDelayEnded = false;
5659 this.isDragging = false;
5660 this.isTouch = false;
5661 this.isGeneric = false; // initiated by 'dragstart' (jqui)
5662 this.shouldCancelTouchScroll = true;
5663 this.scrollAlwaysKills = false;
5664 this.isAutoScroll = false;
5665 // defaults
5666 this.scrollSensitivity = 30; // pixels from edge for scrolling to start
5667 this.scrollSpeed = 200; // pixels per second, at maximum speed
5668 this.scrollIntervalMs = 50; // millisecond wait between scroll increment
5669 this.options = options || {};
5670 }
5671 // Interaction (high-level)
5672 // -----------------------------------------------------------------------------------------------------------------
5673 DragListener.prototype.startInteraction = function (ev, extraOptions) {
5674 if (extraOptions === void 0) { extraOptions = {}; }
5675 if (ev.type === 'mousedown') {
5676 if (GlobalEmitter_1.default.get().shouldIgnoreMouse()) {
5677 return;
5678 }
5679 else if (!util_1.isPrimaryMouseButton(ev)) {
5680 return;
5681 }
5682 else {
5683 ev.preventDefault(); // prevents native selection in most browsers
5684 }
5685 }
5686 if (!this.isInteracting) {
5687 // process options
5688 this.delay = util_1.firstDefined(extraOptions.delay, this.options.delay, 0);
5689 this.minDistance = util_1.firstDefined(extraOptions.distance, this.options.distance, 0);
5690 this.subjectEl = this.options.subjectEl;
5691 util_1.preventSelection($('body'));
5692 this.isInteracting = true;
5693 this.isTouch = util_1.getEvIsTouch(ev);
5694 this.isGeneric = ev.type === 'dragstart';
5695 this.isDelayEnded = false;
5696 this.isDistanceSurpassed = false;
5697 this.originX = util_1.getEvX(ev);
5698 this.originY = util_1.getEvY(ev);
5699 this.scrollEl = util_1.getScrollParent($(ev.target));
5700 this.bindHandlers();
5701 this.initAutoScroll();
5702 this.handleInteractionStart(ev);
5703 this.startDelay(ev);
5704 if (!this.minDistance) {
5705 this.handleDistanceSurpassed(ev);
5706 }
5707 }
5708 };
5709 DragListener.prototype.handleInteractionStart = function (ev) {
5710 this.trigger('interactionStart', ev);
5711 };
5712 DragListener.prototype.endInteraction = function (ev, isCancelled) {
5713 if (this.isInteracting) {
5714 this.endDrag(ev);
5715 if (this.delayTimeoutId) {
5716 clearTimeout(this.delayTimeoutId);
5717 this.delayTimeoutId = null;
5718 }
5719 this.destroyAutoScroll();
5720 this.unbindHandlers();
5721 this.isInteracting = false;
5722 this.handleInteractionEnd(ev, isCancelled);
5723 util_1.allowSelection($('body'));
5724 }
5725 };
5726 DragListener.prototype.handleInteractionEnd = function (ev, isCancelled) {
5727 this.trigger('interactionEnd', ev, isCancelled || false);
5728 };
5729 // Binding To DOM
5730 // -----------------------------------------------------------------------------------------------------------------
5731 DragListener.prototype.bindHandlers = function () {
5732 // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart,
5733 // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly.
5734 var globalEmitter = GlobalEmitter_1.default.get();
5735 if (this.isGeneric) {
5736 this.listenTo($(document), {
5737 drag: this.handleMove,
5738 dragstop: this.endInteraction
5739 });
5740 }
5741 else if (this.isTouch) {
5742 this.listenTo(globalEmitter, {
5743 touchmove: this.handleTouchMove,
5744 touchend: this.endInteraction,
5745 scroll: this.handleTouchScroll
5746 });
5747 }
5748 else {
5749 this.listenTo(globalEmitter, {
5750 mousemove: this.handleMouseMove,
5751 mouseup: this.endInteraction
5752 });
5753 }
5754 this.listenTo(globalEmitter, {
5755 selectstart: util_1.preventDefault,
5756 contextmenu: util_1.preventDefault // long taps would open menu on Chrome dev tools
5757 });
5758 };
5759 DragListener.prototype.unbindHandlers = function () {
5760 this.stopListeningTo(GlobalEmitter_1.default.get());
5761 this.stopListeningTo($(document)); // for isGeneric
5762 };
5763 // Drag (high-level)
5764 // -----------------------------------------------------------------------------------------------------------------
5765 // extraOptions ignored if drag already started
5766 DragListener.prototype.startDrag = function (ev, extraOptions) {
5767 this.startInteraction(ev, extraOptions); // ensure interaction began
5768 if (!this.isDragging) {
5769 this.isDragging = true;
5770 this.handleDragStart(ev);
5771 }
5772 };
5773 DragListener.prototype.handleDragStart = function (ev) {
5774 this.trigger('dragStart', ev);
5775 };
5776 DragListener.prototype.handleMove = function (ev) {
5777 var dx = util_1.getEvX(ev) - this.originX;
5778 var dy = util_1.getEvY(ev) - this.originY;
5779 var minDistance = this.minDistance;
5780 var distanceSq; // current distance from the origin, squared
5781 if (!this.isDistanceSurpassed) {
5782 distanceSq = dx * dx + dy * dy;
5783 if (distanceSq >= minDistance * minDistance) {
5784 this.handleDistanceSurpassed(ev);
5785 }
5786 }
5787 if (this.isDragging) {
5788 this.handleDrag(dx, dy, ev);
5789 }
5790 };
5791 // Called while the mouse is being moved and when we know a legitimate drag is taking place
5792 DragListener.prototype.handleDrag = function (dx, dy, ev) {
5793 this.trigger('drag', dx, dy, ev);
5794 this.updateAutoScroll(ev); // will possibly cause scrolling
5795 };
5796 DragListener.prototype.endDrag = function (ev) {
5797 if (this.isDragging) {
5798 this.isDragging = false;
5799 this.handleDragEnd(ev);
5800 }
5801 };
5802 DragListener.prototype.handleDragEnd = function (ev) {
5803 this.trigger('dragEnd', ev);
5804 };
5805 // Delay
5806 // -----------------------------------------------------------------------------------------------------------------
5807 DragListener.prototype.startDelay = function (initialEv) {
5808 var _this = this;
5809 if (this.delay) {
5810 this.delayTimeoutId = setTimeout(function () {
5811 _this.handleDelayEnd(initialEv);
5812 }, this.delay);
5813 }
5814 else {
5815 this.handleDelayEnd(initialEv);
5816 }
5817 };
5818 DragListener.prototype.handleDelayEnd = function (initialEv) {
5819 this.isDelayEnded = true;
5820 if (this.isDistanceSurpassed) {
5821 this.startDrag(initialEv);
5822 }
5823 };
5824 // Distance
5825 // -----------------------------------------------------------------------------------------------------------------
5826 DragListener.prototype.handleDistanceSurpassed = function (ev) {
5827 this.isDistanceSurpassed = true;
5828 if (this.isDelayEnded) {
5829 this.startDrag(ev);
5830 }
5831 };
5832 // Mouse / Touch
5833 // -----------------------------------------------------------------------------------------------------------------
5834 DragListener.prototype.handleTouchMove = function (ev) {
5835 // prevent inertia and touchmove-scrolling while dragging
5836 if (this.isDragging && this.shouldCancelTouchScroll) {
5837 ev.preventDefault();
5838 }
5839 this.handleMove(ev);
5840 };
5841 DragListener.prototype.handleMouseMove = function (ev) {
5842 this.handleMove(ev);
5843 };
5844 // Scrolling (unrelated to auto-scroll)
5845 // -----------------------------------------------------------------------------------------------------------------
5846 DragListener.prototype.handleTouchScroll = function (ev) {
5847 // if the drag is being initiated by touch, but a scroll happens before
5848 // the drag-initiating delay is over, cancel the drag
5849 if (!this.isDragging || this.scrollAlwaysKills) {
5850 this.endInteraction(ev, true); // isCancelled=true
5851 }
5852 };
5853 // Utils
5854 // -----------------------------------------------------------------------------------------------------------------
5855 // Triggers a callback. Calls a function in the option hash of the same name.
5856 // Arguments beyond the first `name` are forwarded on.
5857 DragListener.prototype.trigger = function (name) {
5858 var args = [];
5859 for (var _i = 1; _i < arguments.length; _i++) {
5860 args[_i - 1] = arguments[_i];
5861 }
5862 if (this.options[name]) {
5863 this.options[name].apply(this, args);
5864 }
5865 // makes _methods callable by event name. TODO: kill this
5866 if (this['_' + name]) {
5867 this['_' + name].apply(this, args);
5868 }
5869 };
5870 // Auto-scroll
5871 // -----------------------------------------------------------------------------------------------------------------
5872 DragListener.prototype.initAutoScroll = function () {
5873 var scrollEl = this.scrollEl;
5874 this.isAutoScroll =
5875 this.options.scroll &&
5876 scrollEl &&
5877 !scrollEl.is(window) &&
5878 !scrollEl.is(document);
5879 if (this.isAutoScroll) {
5880 // debounce makes sure rapid calls don't happen
5881 this.listenTo(scrollEl, 'scroll', util_1.debounce(this.handleDebouncedScroll, 100));
5882 }
5883 };
5884 DragListener.prototype.destroyAutoScroll = function () {
5885 this.endAutoScroll(); // kill any animation loop
5886 // remove the scroll handler if there is a scrollEl
5887 if (this.isAutoScroll) {
5888 this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :(
5889 }
5890 };
5891 // Computes and stores the bounding rectangle of scrollEl
5892 DragListener.prototype.computeScrollBounds = function () {
5893 if (this.isAutoScroll) {
5894 this.scrollBounds = util_1.getOuterRect(this.scrollEl);
5895 // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars
5896 }
5897 };
5898 // Called when the dragging is in progress and scrolling should be updated
5899 DragListener.prototype.updateAutoScroll = function (ev) {
5900 var sensitivity = this.scrollSensitivity;
5901 var bounds = this.scrollBounds;
5902 var topCloseness;
5903 var bottomCloseness;
5904 var leftCloseness;
5905 var rightCloseness;
5906 var topVel = 0;
5907 var leftVel = 0;
5908 if (bounds) {
5909 // compute closeness to edges. valid range is from 0.0 - 1.0
5910 topCloseness = (sensitivity - (util_1.getEvY(ev) - bounds.top)) / sensitivity;
5911 bottomCloseness = (sensitivity - (bounds.bottom - util_1.getEvY(ev))) / sensitivity;
5912 leftCloseness = (sensitivity - (util_1.getEvX(ev) - bounds.left)) / sensitivity;
5913 rightCloseness = (sensitivity - (bounds.right - util_1.getEvX(ev))) / sensitivity;
5914 // translate vertical closeness into velocity.
5915 // mouse must be completely in bounds for velocity to happen.
5916 if (topCloseness >= 0 && topCloseness <= 1) {
5917 topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up
5918 }
5919 else if (bottomCloseness >= 0 && bottomCloseness <= 1) {
5920 topVel = bottomCloseness * this.scrollSpeed;
5921 }
5922 // translate horizontal closeness into velocity
5923 if (leftCloseness >= 0 && leftCloseness <= 1) {
5924 leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left
5925 }
5926 else if (rightCloseness >= 0 && rightCloseness <= 1) {
5927 leftVel = rightCloseness * this.scrollSpeed;
5928 }
5929 }
5930 this.setScrollVel(topVel, leftVel);
5931 };
5932 // Sets the speed-of-scrolling for the scrollEl
5933 DragListener.prototype.setScrollVel = function (topVel, leftVel) {
5934 this.scrollTopVel = topVel;
5935 this.scrollLeftVel = leftVel;
5936 this.constrainScrollVel(); // massages into realistic values
5937 // if there is non-zero velocity, and an animation loop hasn't already started, then START
5938 if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {
5939 this.scrollIntervalId = setInterval(util_1.proxy(this, 'scrollIntervalFunc'), // scope to `this`
5940 this.scrollIntervalMs);
5941 }
5942 };
5943 // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way
5944 DragListener.prototype.constrainScrollVel = function () {
5945 var el = this.scrollEl;
5946 if (this.scrollTopVel < 0) {
5947 if (el.scrollTop() <= 0) {
5948 this.scrollTopVel = 0;
5949 }
5950 }
5951 else if (this.scrollTopVel > 0) {
5952 if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) {
5953 this.scrollTopVel = 0;
5954 }
5955 }
5956 if (this.scrollLeftVel < 0) {
5957 if (el.scrollLeft() <= 0) {
5958 this.scrollLeftVel = 0;
5959 }
5960 }
5961 else if (this.scrollLeftVel > 0) {
5962 if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) {
5963 this.scrollLeftVel = 0;
5964 }
5965 }
5966 };
5967 // This function gets called during every iteration of the scrolling animation loop
5968 DragListener.prototype.scrollIntervalFunc = function () {
5969 var el = this.scrollEl;
5970 var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by
5971 // change the value of scrollEl's scroll
5972 if (this.scrollTopVel) {
5973 el.scrollTop(el.scrollTop() + this.scrollTopVel * frac);
5974 }
5975 if (this.scrollLeftVel) {
5976 el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);
5977 }
5978 this.constrainScrollVel(); // since the scroll values changed, recompute the velocities
5979 // if scrolled all the way, which causes the vels to be zero, stop the animation loop
5980 if (!this.scrollTopVel && !this.scrollLeftVel) {
5981 this.endAutoScroll();
5982 }
5983 };
5984 // Kills any existing scrolling animation loop
5985 DragListener.prototype.endAutoScroll = function () {
5986 if (this.scrollIntervalId) {
5987 clearInterval(this.scrollIntervalId);
5988 this.scrollIntervalId = null;
5989 this.handleScrollEnd();
5990 }
5991 };
5992 // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)
5993 DragListener.prototype.handleDebouncedScroll = function () {
5994 // recompute all coordinates, but *only* if this is *not* part of our scrolling animation
5995 if (!this.scrollIntervalId) {
5996 this.handleScrollEnd();
5997 }
5998 };
5999 DragListener.prototype.handleScrollEnd = function () {
6000 // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
6001 };
6002 return DragListener;
6003 }());
6004 exports.default = DragListener;
6005 ListenerMixin_1.default.mixInto(DragListener);
6006
6007
6008 /***/ }),
6009 /* 55 */
6010 /***/ (function(module, exports, __webpack_require__) {
6011
6012 Object.defineProperty(exports, "__esModule", { value: true });
6013 var tslib_1 = __webpack_require__(2);
6014 var util_1 = __webpack_require__(4);
6015 var Mixin_1 = __webpack_require__(14);
6016 /*
6017 A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns.
6018 Prerequisite: the object being mixed into needs to be a *Grid*
6019 */
6020 var DayTableMixin = /** @class */ (function (_super) {
6021 tslib_1.__extends(DayTableMixin, _super);
6022 function DayTableMixin() {
6023 return _super !== null && _super.apply(this, arguments) || this;
6024 }
6025 // Populates internal variables used for date calculation and rendering
6026 DayTableMixin.prototype.updateDayTable = function () {
6027 var t = this;
6028 var view = t.view;
6029 var calendar = view.calendar;
6030 var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true);
6031 var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true);
6032 var dayIndex = -1;
6033 var dayIndices = [];
6034 var dayDates = [];
6035 var daysPerRow;
6036 var firstDay;
6037 var rowCnt;
6038 while (date.isBefore(end)) {
6039 if (view.isHiddenDay(date)) {
6040 dayIndices.push(dayIndex + 0.5); // mark that it's between indices
6041 }
6042 else {
6043 dayIndex++;
6044 dayIndices.push(dayIndex);
6045 dayDates.push(date.clone());
6046 }
6047 date.add(1, 'days');
6048 }
6049 if (this.breakOnWeeks) {
6050 // count columns until the day-of-week repeats
6051 firstDay = dayDates[0].day();
6052 for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) {
6053 if (dayDates[daysPerRow].day() === firstDay) {
6054 break;
6055 }
6056 }
6057 rowCnt = Math.ceil(dayDates.length / daysPerRow);
6058 }
6059 else {
6060 rowCnt = 1;
6061 daysPerRow = dayDates.length;
6062 }
6063 this.dayDates = dayDates;
6064 this.dayIndices = dayIndices;
6065 this.daysPerRow = daysPerRow;
6066 this.rowCnt = rowCnt;
6067 this.updateDayTableCols();
6068 };
6069 // Computes and assigned the colCnt property and updates any options that may be computed from it
6070 DayTableMixin.prototype.updateDayTableCols = function () {
6071 this.colCnt = this.computeColCnt();
6072 this.colHeadFormat =
6073 this.opt('columnHeaderFormat') ||
6074 this.opt('columnFormat') || // deprecated
6075 this.computeColHeadFormat();
6076 };
6077 // Determines how many columns there should be in the table
6078 DayTableMixin.prototype.computeColCnt = function () {
6079 return this.daysPerRow;
6080 };
6081 // Computes the ambiguously-timed moment for the given cell
6082 DayTableMixin.prototype.getCellDate = function (row, col) {
6083 return this.dayDates[this.getCellDayIndex(row, col)].clone();
6084 };
6085 // Computes the ambiguously-timed date range for the given cell
6086 DayTableMixin.prototype.getCellRange = function (row, col) {
6087 var start = this.getCellDate(row, col);
6088 var end = start.clone().add(1, 'days');
6089 return { start: start, end: end };
6090 };
6091 // Returns the number of day cells, chronologically, from the first of the grid (0-based)
6092 DayTableMixin.prototype.getCellDayIndex = function (row, col) {
6093 return row * this.daysPerRow + this.getColDayIndex(col);
6094 };
6095 // Returns the numner of day cells, chronologically, from the first cell in *any given row*
6096 DayTableMixin.prototype.getColDayIndex = function (col) {
6097 if (this.isRTL) {
6098 return this.colCnt - 1 - col;
6099 }
6100 else {
6101 return col;
6102 }
6103 };
6104 // Given a date, returns its chronolocial cell-index from the first cell of the grid.
6105 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
6106 // If before the first offset, returns a negative number.
6107 // If after the last offset, returns an offset past the last cell offset.
6108 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
6109 DayTableMixin.prototype.getDateDayIndex = function (date) {
6110 var dayIndices = this.dayIndices;
6111 var dayOffset = date.diff(this.dayDates[0], 'days');
6112 if (dayOffset < 0) {
6113 return dayIndices[0] - 1;
6114 }
6115 else if (dayOffset >= dayIndices.length) {
6116 return dayIndices[dayIndices.length - 1] + 1;
6117 }
6118 else {
6119 return dayIndices[dayOffset];
6120 }
6121 };
6122 /* Options
6123 ------------------------------------------------------------------------------------------------------------------*/
6124 // Computes a default column header formatting string if `colFormat` is not explicitly defined
6125 DayTableMixin.prototype.computeColHeadFormat = function () {
6126 // if more than one week row, or if there are a lot of columns with not much space,
6127 // put just the day numbers will be in each cell
6128 if (this.rowCnt > 1 || this.colCnt > 10) {
6129 return 'ddd'; // "Sat"
6130 }
6131 else if (this.colCnt > 1) {
6132 return this.opt('dayOfMonthFormat'); // "Sat 12/10"
6133 }
6134 else {
6135 return 'dddd'; // "Saturday"
6136 }
6137 };
6138 /* Slicing
6139 ------------------------------------------------------------------------------------------------------------------*/
6140 // Slices up a date range into a segment for every week-row it intersects with
6141 DayTableMixin.prototype.sliceRangeByRow = function (unzonedRange) {
6142 var daysPerRow = this.daysPerRow;
6143 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
6144 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
6145 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
6146 var segs = [];
6147 var row;
6148 var rowFirst;
6149 var rowLast; // inclusive day-index range for current row
6150 var segFirst;
6151 var segLast; // inclusive day-index range for segment
6152 for (row = 0; row < this.rowCnt; row++) {
6153 rowFirst = row * daysPerRow;
6154 rowLast = rowFirst + daysPerRow - 1;
6155 // intersect segment's offset range with the row's
6156 segFirst = Math.max(rangeFirst, rowFirst);
6157 segLast = Math.min(rangeLast, rowLast);
6158 // deal with in-between indices
6159 segFirst = Math.ceil(segFirst); // in-between starts round to next cell
6160 segLast = Math.floor(segLast); // in-between ends round to prev cell
6161 if (segFirst <= segLast) {
6162 segs.push({
6163 row: row,
6164 // normalize to start of row
6165 firstRowDayIndex: segFirst - rowFirst,
6166 lastRowDayIndex: segLast - rowFirst,
6167 // must be matching integers to be the segment's start/end
6168 isStart: segFirst === rangeFirst,
6169 isEnd: segLast === rangeLast
6170 });
6171 }
6172 }
6173 return segs;
6174 };
6175 // Slices up a date range into a segment for every day-cell it intersects with.
6176 // TODO: make more DRY with sliceRangeByRow somehow.
6177 DayTableMixin.prototype.sliceRangeByDay = function (unzonedRange) {
6178 var daysPerRow = this.daysPerRow;
6179 var normalRange = this.view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
6180 var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
6181 var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
6182 var segs = [];
6183 var row;
6184 var rowFirst;
6185 var rowLast; // inclusive day-index range for current row
6186 var i;
6187 var segFirst;
6188 var segLast; // inclusive day-index range for segment
6189 for (row = 0; row < this.rowCnt; row++) {
6190 rowFirst = row * daysPerRow;
6191 rowLast = rowFirst + daysPerRow - 1;
6192 for (i = rowFirst; i <= rowLast; i++) {
6193 // intersect segment's offset range with the row's
6194 segFirst = Math.max(rangeFirst, i);
6195 segLast = Math.min(rangeLast, i);
6196 // deal with in-between indices
6197 segFirst = Math.ceil(segFirst); // in-between starts round to next cell
6198 segLast = Math.floor(segLast); // in-between ends round to prev cell
6199 if (segFirst <= segLast) {
6200 segs.push({
6201 row: row,
6202 // normalize to start of row
6203 firstRowDayIndex: segFirst - rowFirst,
6204 lastRowDayIndex: segLast - rowFirst,
6205 // must be matching integers to be the segment's start/end
6206 isStart: segFirst === rangeFirst,
6207 isEnd: segLast === rangeLast
6208 });
6209 }
6210 }
6211 }
6212 return segs;
6213 };
6214 /* Header Rendering
6215 ------------------------------------------------------------------------------------------------------------------*/
6216 DayTableMixin.prototype.renderHeadHtml = function () {
6217 var theme = this.view.calendar.theme;
6218 return '' +
6219 '<div class="fc-row ' + theme.getClass('headerRow') + '">' +
6220 '<table class="' + theme.getClass('tableGrid') + '">' +
6221 '<thead>' +
6222 this.renderHeadTrHtml() +
6223 '</thead>' +
6224 '</table>' +
6225 '</div>';
6226 };
6227 DayTableMixin.prototype.renderHeadIntroHtml = function () {
6228 return this.renderIntroHtml(); // fall back to generic
6229 };
6230 DayTableMixin.prototype.renderHeadTrHtml = function () {
6231 return '' +
6232 '<tr>' +
6233 (this.isRTL ? '' : this.renderHeadIntroHtml()) +
6234 this.renderHeadDateCellsHtml() +
6235 (this.isRTL ? this.renderHeadIntroHtml() : '') +
6236 '</tr>';
6237 };
6238 DayTableMixin.prototype.renderHeadDateCellsHtml = function () {
6239 var htmls = [];
6240 var col;
6241 var date;
6242 for (col = 0; col < this.colCnt; col++) {
6243 date = this.getCellDate(0, col);
6244 htmls.push(this.renderHeadDateCellHtml(date));
6245 }
6246 return htmls.join('');
6247 };
6248 // TODO: when internalApiVersion, accept an object for HTML attributes
6249 // (colspan should be no different)
6250 DayTableMixin.prototype.renderHeadDateCellHtml = function (date, colspan, otherAttrs) {
6251 var t = this;
6252 var view = t.view;
6253 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
6254 var classNames = [
6255 'fc-day-header',
6256 view.calendar.theme.getClass('widgetHeader')
6257 ];
6258 var innerHtml;
6259 if (typeof t.opt('columnHeaderHtml') === 'function') {
6260 innerHtml = t.opt('columnHeaderHtml')(date);
6261 }
6262 else if (typeof t.opt('columnHeaderText') === 'function') {
6263 innerHtml = util_1.htmlEscape(t.opt('columnHeaderText')(date));
6264 }
6265 else {
6266 innerHtml = util_1.htmlEscape(date.format(t.colHeadFormat));
6267 }
6268 // if only one row of days, the classNames on the header can represent the specific days beneath
6269 if (t.rowCnt === 1) {
6270 classNames = classNames.concat(
6271 // includes the day-of-week class
6272 // noThemeHighlight=true (don't highlight the header)
6273 t.getDayClasses(date, true));
6274 }
6275 else {
6276 classNames.push('fc-' + util_1.dayIDs[date.day()]); // only add the day-of-week class
6277 }
6278 return '' +
6279 '<th class="' + classNames.join(' ') + '"' +
6280 ((isDateValid && t.rowCnt) === 1 ?
6281 ' data-date="' + date.format('YYYY-MM-DD') + '"' :
6282 '') +
6283 (colspan > 1 ?
6284 ' colspan="' + colspan + '"' :
6285 '') +
6286 (otherAttrs ?
6287 ' ' + otherAttrs :
6288 '') +
6289 '>' +
6290 (isDateValid ?
6291 // don't make a link if the heading could represent multiple days, or if there's only one day (forceOff)
6292 view.buildGotoAnchorHtml({ date: date, forceOff: t.rowCnt > 1 || t.colCnt === 1 }, innerHtml) :
6293 // if not valid, display text, but no link
6294 innerHtml) +
6295 '</th>';
6296 };
6297 /* Background Rendering
6298 ------------------------------------------------------------------------------------------------------------------*/
6299 DayTableMixin.prototype.renderBgTrHtml = function (row) {
6300 return '' +
6301 '<tr>' +
6302 (this.isRTL ? '' : this.renderBgIntroHtml(row)) +
6303 this.renderBgCellsHtml(row) +
6304 (this.isRTL ? this.renderBgIntroHtml(row) : '') +
6305 '</tr>';
6306 };
6307 DayTableMixin.prototype.renderBgIntroHtml = function (row) {
6308 return this.renderIntroHtml(); // fall back to generic
6309 };
6310 DayTableMixin.prototype.renderBgCellsHtml = function (row) {
6311 var htmls = [];
6312 var col;
6313 var date;
6314 for (col = 0; col < this.colCnt; col++) {
6315 date = this.getCellDate(row, col);
6316 htmls.push(this.renderBgCellHtml(date));
6317 }
6318 return htmls.join('');
6319 };
6320 DayTableMixin.prototype.renderBgCellHtml = function (date, otherAttrs) {
6321 var t = this;
6322 var view = t.view;
6323 var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
6324 var classes = t.getDayClasses(date);
6325 classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent'));
6326 return '<td class="' + classes.join(' ') + '"' +
6327 (isDateValid ?
6328 ' data-date="' + date.format('YYYY-MM-DD') + '"' : // if date has a time, won't format it
6329 '') +
6330 (otherAttrs ?
6331 ' ' + otherAttrs :
6332 '') +
6333 '></td>';
6334 };
6335 /* Generic
6336 ------------------------------------------------------------------------------------------------------------------*/
6337 DayTableMixin.prototype.renderIntroHtml = function () {
6338 // Generates the default HTML intro for any row. User classes should override
6339 };
6340 // TODO: a generic method for dealing with <tr>, RTL, intro
6341 // when increment internalApiVersion
6342 // wrapTr (scheduler)
6343 /* Utils
6344 ------------------------------------------------------------------------------------------------------------------*/
6345 // Applies the generic "intro" and "outro" HTML to the given cells.
6346 // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
6347 DayTableMixin.prototype.bookendCells = function (trEl) {
6348 var introHtml = this.renderIntroHtml();
6349 if (introHtml) {
6350 if (this.isRTL) {
6351 trEl.append(introHtml);
6352 }
6353 else {
6354 trEl.prepend(introHtml);
6355 }
6356 }
6357 };
6358 return DayTableMixin;
6359 }(Mixin_1.default));
6360 exports.default = DayTableMixin;
6361
6362
6363 /***/ }),
6364 /* 56 */
6365 /***/ (function(module, exports) {
6366
6367 Object.defineProperty(exports, "__esModule", { value: true });
6368 var BusinessHourRenderer = /** @class */ (function () {
6369 /*
6370 component implements:
6371 - eventRangesToEventFootprints
6372 - eventFootprintsToSegs
6373 */
6374 function BusinessHourRenderer(component, fillRenderer) {
6375 this.component = component;
6376 this.fillRenderer = fillRenderer;
6377 }
6378 BusinessHourRenderer.prototype.render = function (businessHourGenerator) {
6379 var component = this.component;
6380 var unzonedRange = component._getDateProfile().activeUnzonedRange;
6381 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(component.hasAllDayBusinessHours, unzonedRange);
6382 var eventFootprints = eventInstanceGroup ?
6383 component.eventRangesToEventFootprints(eventInstanceGroup.sliceRenderRanges(unzonedRange)) :
6384 [];
6385 this.renderEventFootprints(eventFootprints);
6386 };
6387 BusinessHourRenderer.prototype.renderEventFootprints = function (eventFootprints) {
6388 var segs = this.component.eventFootprintsToSegs(eventFootprints);
6389 this.renderSegs(segs);
6390 this.segs = segs;
6391 };
6392 BusinessHourRenderer.prototype.renderSegs = function (segs) {
6393 if (this.fillRenderer) {
6394 this.fillRenderer.renderSegs('businessHours', segs, {
6395 getClasses: function (seg) {
6396 return ['fc-nonbusiness', 'fc-bgevent'];
6397 }
6398 });
6399 }
6400 };
6401 BusinessHourRenderer.prototype.unrender = function () {
6402 if (this.fillRenderer) {
6403 this.fillRenderer.unrender('businessHours');
6404 }
6405 this.segs = null;
6406 };
6407 BusinessHourRenderer.prototype.getSegs = function () {
6408 return this.segs || [];
6409 };
6410 return BusinessHourRenderer;
6411 }());
6412 exports.default = BusinessHourRenderer;
6413
6414
6415 /***/ }),
6416 /* 57 */
6417 /***/ (function(module, exports, __webpack_require__) {
6418
6419 Object.defineProperty(exports, "__esModule", { value: true });
6420 var $ = __webpack_require__(3);
6421 var util_1 = __webpack_require__(4);
6422 var FillRenderer = /** @class */ (function () {
6423 function FillRenderer(component) {
6424 this.fillSegTag = 'div';
6425 this.component = component;
6426 this.elsByFill = {};
6427 }
6428 FillRenderer.prototype.renderFootprint = function (type, componentFootprint, props) {
6429 this.renderSegs(type, this.component.componentFootprintToSegs(componentFootprint), props);
6430 };
6431 FillRenderer.prototype.renderSegs = function (type, segs, props) {
6432 var els;
6433 segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs
6434 els = this.attachSegEls(type, segs);
6435 if (els) {
6436 this.reportEls(type, els);
6437 }
6438 return segs;
6439 };
6440 // Unrenders a specific type of fill that is currently rendered on the grid
6441 FillRenderer.prototype.unrender = function (type) {
6442 var el = this.elsByFill[type];
6443 if (el) {
6444 el.remove();
6445 delete this.elsByFill[type];
6446 }
6447 };
6448 // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
6449 // Only returns segments that successfully rendered.
6450 FillRenderer.prototype.buildSegEls = function (type, segs, props) {
6451 var _this = this;
6452 var html = '';
6453 var renderedSegs = [];
6454 var i;
6455 if (segs.length) {
6456 // build a large concatenation of segment HTML
6457 for (i = 0; i < segs.length; i++) {
6458 html += this.buildSegHtml(type, segs[i], props);
6459 }
6460 // Grab individual elements from the combined HTML string. Use each as the default rendering.
6461 // Then, compute the 'el' for each segment.
6462 $(html).each(function (i, node) {
6463 var seg = segs[i];
6464 var el = $(node);
6465 // allow custom filter methods per-type
6466 if (props.filterEl) {
6467 el = props.filterEl(seg, el);
6468 }
6469 if (el) {
6470 el = $(el); // allow custom filter to return raw DOM node
6471 // correct element type? (would be bad if a non-TD were inserted into a table for example)
6472 if (el.is(_this.fillSegTag)) {
6473 seg.el = el;
6474 renderedSegs.push(seg);
6475 }
6476 }
6477 });
6478 }
6479 return renderedSegs;
6480 };
6481 // Builds the HTML needed for one fill segment. Generic enough to work with different types.
6482 FillRenderer.prototype.buildSegHtml = function (type, seg, props) {
6483 // custom hooks per-type
6484 var classes = props.getClasses ? props.getClasses(seg) : [];
6485 var css = util_1.cssToStr(props.getCss ? props.getCss(seg) : {});
6486 return '<' + this.fillSegTag +
6487 (classes.length ? ' class="' + classes.join(' ') + '"' : '') +
6488 (css ? ' style="' + css + '"' : '') +
6489 ' />';
6490 };
6491 // Should return wrapping DOM structure
6492 FillRenderer.prototype.attachSegEls = function (type, segs) {
6493 // subclasses must implement
6494 };
6495 FillRenderer.prototype.reportEls = function (type, nodes) {
6496 if (this.elsByFill[type]) {
6497 this.elsByFill[type] = this.elsByFill[type].add(nodes);
6498 }
6499 else {
6500 this.elsByFill[type] = $(nodes);
6501 }
6502 };
6503 return FillRenderer;
6504 }());
6505 exports.default = FillRenderer;
6506
6507
6508 /***/ }),
6509 /* 58 */
6510 /***/ (function(module, exports, __webpack_require__) {
6511
6512 Object.defineProperty(exports, "__esModule", { value: true });
6513 var SingleEventDef_1 = __webpack_require__(13);
6514 var EventFootprint_1 = __webpack_require__(36);
6515 var EventSource_1 = __webpack_require__(6);
6516 var HelperRenderer = /** @class */ (function () {
6517 function HelperRenderer(component, eventRenderer) {
6518 this.view = component._getView();
6519 this.component = component;
6520 this.eventRenderer = eventRenderer;
6521 }
6522 HelperRenderer.prototype.renderComponentFootprint = function (componentFootprint) {
6523 this.renderEventFootprints([
6524 this.fabricateEventFootprint(componentFootprint)
6525 ]);
6526 };
6527 HelperRenderer.prototype.renderEventDraggingFootprints = function (eventFootprints, sourceSeg, isTouch) {
6528 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-dragging', isTouch ? null : this.view.opt('dragOpacity'));
6529 };
6530 HelperRenderer.prototype.renderEventResizingFootprints = function (eventFootprints, sourceSeg, isTouch) {
6531 this.renderEventFootprints(eventFootprints, sourceSeg, 'fc-resizing');
6532 };
6533 HelperRenderer.prototype.renderEventFootprints = function (eventFootprints, sourceSeg, extraClassNames, opacity) {
6534 var segs = this.component.eventFootprintsToSegs(eventFootprints);
6535 var classNames = 'fc-helper ' + (extraClassNames || '');
6536 var i;
6537 // assigns each seg's el and returns a subset of segs that were rendered
6538 segs = this.eventRenderer.renderFgSegEls(segs);
6539 for (i = 0; i < segs.length; i++) {
6540 segs[i].el.addClass(classNames);
6541 }
6542 if (opacity != null) {
6543 for (i = 0; i < segs.length; i++) {
6544 segs[i].el.css('opacity', opacity);
6545 }
6546 }
6547 this.helperEls = this.renderSegs(segs, sourceSeg);
6548 };
6549 /*
6550 Must return all mock event elements
6551 */
6552 HelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
6553 // Subclasses must implement
6554 };
6555 HelperRenderer.prototype.unrender = function () {
6556 if (this.helperEls) {
6557 this.helperEls.remove();
6558 this.helperEls = null;
6559 }
6560 };
6561 HelperRenderer.prototype.fabricateEventFootprint = function (componentFootprint) {
6562 var calendar = this.view.calendar;
6563 var eventDateProfile = calendar.footprintToDateProfile(componentFootprint);
6564 var dummyEvent = new SingleEventDef_1.default(new EventSource_1.default(calendar));
6565 var dummyInstance;
6566 dummyEvent.dateProfile = eventDateProfile;
6567 dummyInstance = dummyEvent.buildInstance();
6568 return new EventFootprint_1.default(componentFootprint, dummyEvent, dummyInstance);
6569 };
6570 return HelperRenderer;
6571 }());
6572 exports.default = HelperRenderer;
6573
6574
6575 /***/ }),
6576 /* 59 */
6577 /***/ (function(module, exports, __webpack_require__) {
6578
6579 Object.defineProperty(exports, "__esModule", { value: true });
6580 var tslib_1 = __webpack_require__(2);
6581 var GlobalEmitter_1 = __webpack_require__(21);
6582 var Interaction_1 = __webpack_require__(15);
6583 var EventPointing = /** @class */ (function (_super) {
6584 tslib_1.__extends(EventPointing, _super);
6585 function EventPointing() {
6586 return _super !== null && _super.apply(this, arguments) || this;
6587 }
6588 /*
6589 component must implement:
6590 - publiclyTrigger
6591 */
6592 EventPointing.prototype.bindToEl = function (el) {
6593 var component = this.component;
6594 component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this));
6595 component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this));
6596 component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this));
6597 };
6598 EventPointing.prototype.handleClick = function (seg, ev) {
6599 var res = this.component.publiclyTrigger('eventClick', {
6600 context: seg.el[0],
6601 args: [seg.footprint.getEventLegacy(), ev, this.view]
6602 });
6603 if (res === false) {
6604 ev.preventDefault();
6605 }
6606 };
6607 // Updates internal state and triggers handlers for when an event element is moused over
6608 EventPointing.prototype.handleMouseover = function (seg, ev) {
6609 if (!GlobalEmitter_1.default.get().shouldIgnoreMouse() &&
6610 !this.mousedOverSeg) {
6611 this.mousedOverSeg = seg;
6612 // TODO: move to EventSelecting's responsibility
6613 if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
6614 seg.el.addClass('fc-allow-mouse-resize');
6615 }
6616 this.component.publiclyTrigger('eventMouseover', {
6617 context: seg.el[0],
6618 args: [seg.footprint.getEventLegacy(), ev, this.view]
6619 });
6620 }
6621 };
6622 // Updates internal state and triggers handlers for when an event element is moused out.
6623 // Can be given no arguments, in which case it will mouseout the segment that was previously moused over.
6624 EventPointing.prototype.handleMouseout = function (seg, ev) {
6625 if (this.mousedOverSeg) {
6626 this.mousedOverSeg = null;
6627 // TODO: move to EventSelecting's responsibility
6628 if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
6629 seg.el.removeClass('fc-allow-mouse-resize');
6630 }
6631 this.component.publiclyTrigger('eventMouseout', {
6632 context: seg.el[0],
6633 args: [
6634 seg.footprint.getEventLegacy(),
6635 ev || {},
6636 this.view
6637 ]
6638 });
6639 }
6640 };
6641 EventPointing.prototype.end = function () {
6642 if (this.mousedOverSeg) {
6643 this.handleMouseout(this.mousedOverSeg);
6644 }
6645 };
6646 return EventPointing;
6647 }(Interaction_1.default));
6648 exports.default = EventPointing;
6649
6650
6651 /***/ }),
6652 /* 60 */
6653 /***/ (function(module, exports, __webpack_require__) {
6654
6655 Object.defineProperty(exports, "__esModule", { value: true });
6656 var tslib_1 = __webpack_require__(2);
6657 var Mixin_1 = __webpack_require__(14);
6658 var DateClicking_1 = __webpack_require__(245);
6659 var DateSelecting_1 = __webpack_require__(225);
6660 var EventPointing_1 = __webpack_require__(59);
6661 var EventDragging_1 = __webpack_require__(224);
6662 var EventResizing_1 = __webpack_require__(223);
6663 var ExternalDropping_1 = __webpack_require__(222);
6664 var StandardInteractionsMixin = /** @class */ (function (_super) {
6665 tslib_1.__extends(StandardInteractionsMixin, _super);
6666 function StandardInteractionsMixin() {
6667 return _super !== null && _super.apply(this, arguments) || this;
6668 }
6669 return StandardInteractionsMixin;
6670 }(Mixin_1.default));
6671 exports.default = StandardInteractionsMixin;
6672 StandardInteractionsMixin.prototype.dateClickingClass = DateClicking_1.default;
6673 StandardInteractionsMixin.prototype.dateSelectingClass = DateSelecting_1.default;
6674 StandardInteractionsMixin.prototype.eventPointingClass = EventPointing_1.default;
6675 StandardInteractionsMixin.prototype.eventDraggingClass = EventDragging_1.default;
6676 StandardInteractionsMixin.prototype.eventResizingClass = EventResizing_1.default;
6677 StandardInteractionsMixin.prototype.externalDroppingClass = ExternalDropping_1.default;
6678
6679
6680 /***/ }),
6681 /* 61 */
6682 /***/ (function(module, exports, __webpack_require__) {
6683
6684 Object.defineProperty(exports, "__esModule", { value: true });
6685 var tslib_1 = __webpack_require__(2);
6686 var $ = __webpack_require__(3);
6687 var util_1 = __webpack_require__(4);
6688 var CoordCache_1 = __webpack_require__(53);
6689 var Popover_1 = __webpack_require__(249);
6690 var UnzonedRange_1 = __webpack_require__(5);
6691 var ComponentFootprint_1 = __webpack_require__(12);
6692 var EventFootprint_1 = __webpack_require__(36);
6693 var BusinessHourRenderer_1 = __webpack_require__(56);
6694 var StandardInteractionsMixin_1 = __webpack_require__(60);
6695 var InteractiveDateComponent_1 = __webpack_require__(40);
6696 var DayTableMixin_1 = __webpack_require__(55);
6697 var DayGridEventRenderer_1 = __webpack_require__(250);
6698 var DayGridHelperRenderer_1 = __webpack_require__(251);
6699 var DayGridFillRenderer_1 = __webpack_require__(252);
6700 /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
6701 ----------------------------------------------------------------------------------------------------------------------*/
6702 var DayGrid = /** @class */ (function (_super) {
6703 tslib_1.__extends(DayGrid, _super);
6704 function DayGrid(view) {
6705 var _this = _super.call(this, view) || this;
6706 _this.cellWeekNumbersVisible = false; // display week numbers in day cell?
6707 _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
6708 // isRigid determines whether the individual rows should ignore the contents and be a constant height.
6709 // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.
6710 _this.isRigid = false;
6711 _this.hasAllDayBusinessHours = true;
6712 return _this;
6713 }
6714 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
6715 DayGrid.prototype.componentFootprintToSegs = function (componentFootprint) {
6716 var segs = this.sliceRangeByRow(componentFootprint.unzonedRange);
6717 var i;
6718 var seg;
6719 for (i = 0; i < segs.length; i++) {
6720 seg = segs[i];
6721 if (this.isRTL) {
6722 seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex;
6723 seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex;
6724 }
6725 else {
6726 seg.leftCol = seg.firstRowDayIndex;
6727 seg.rightCol = seg.lastRowDayIndex;
6728 }
6729 }
6730 return segs;
6731 };
6732 /* Date Rendering
6733 ------------------------------------------------------------------------------------------------------------------*/
6734 DayGrid.prototype.renderDates = function (dateProfile) {
6735 this.dateProfile = dateProfile;
6736 this.updateDayTable();
6737 this.renderGrid();
6738 };
6739 DayGrid.prototype.unrenderDates = function () {
6740 this.removeSegPopover();
6741 };
6742 // Renders the rows and columns into the component's `this.el`, which should already be assigned.
6743 DayGrid.prototype.renderGrid = function () {
6744 var view = this.view;
6745 var rowCnt = this.rowCnt;
6746 var colCnt = this.colCnt;
6747 var html = '';
6748 var row;
6749 var col;
6750 if (this.headContainerEl) {
6751 this.headContainerEl.html(this.renderHeadHtml());
6752 }
6753 for (row = 0; row < rowCnt; row++) {
6754 html += this.renderDayRowHtml(row, this.isRigid);
6755 }
6756 this.el.html(html);
6757 this.rowEls = this.el.find('.fc-row');
6758 this.cellEls = this.el.find('.fc-day, .fc-disabled-day');
6759 this.rowCoordCache = new CoordCache_1.default({
6760 els: this.rowEls,
6761 isVertical: true
6762 });
6763 this.colCoordCache = new CoordCache_1.default({
6764 els: this.cellEls.slice(0, this.colCnt),
6765 isHorizontal: true
6766 });
6767 // trigger dayRender with each cell's element
6768 for (row = 0; row < rowCnt; row++) {
6769 for (col = 0; col < colCnt; col++) {
6770 this.publiclyTrigger('dayRender', {
6771 context: view,
6772 args: [
6773 this.getCellDate(row, col),
6774 this.getCellEl(row, col),
6775 view
6776 ]
6777 });
6778 }
6779 }
6780 };
6781 // Generates the HTML for a single row, which is a div that wraps a table.
6782 // `row` is the row number.
6783 DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
6784 var theme = this.view.calendar.theme;
6785 var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
6786 if (isRigid) {
6787 classes.push('fc-rigid');
6788 }
6789 return '' +
6790 '<div class="' + classes.join(' ') + '">' +
6791 '<div class="fc-bg">' +
6792 '<table class="' + theme.getClass('tableGrid') + '">' +
6793 this.renderBgTrHtml(row) +
6794 '</table>' +
6795 '</div>' +
6796 '<div class="fc-content-skeleton">' +
6797 '<table>' +
6798 (this.getIsNumbersVisible() ?
6799 '<thead>' +
6800 this.renderNumberTrHtml(row) +
6801 '</thead>' :
6802 '') +
6803 '</table>' +
6804 '</div>' +
6805 '</div>';
6806 };
6807 DayGrid.prototype.getIsNumbersVisible = function () {
6808 return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible;
6809 };
6810 DayGrid.prototype.getIsDayNumbersVisible = function () {
6811 return this.rowCnt > 1;
6812 };
6813 /* Grid Number Rendering
6814 ------------------------------------------------------------------------------------------------------------------*/
6815 DayGrid.prototype.renderNumberTrHtml = function (row) {
6816 return '' +
6817 '<tr>' +
6818 (this.isRTL ? '' : this.renderNumberIntroHtml(row)) +
6819 this.renderNumberCellsHtml(row) +
6820 (this.isRTL ? this.renderNumberIntroHtml(row) : '') +
6821 '</tr>';
6822 };
6823 DayGrid.prototype.renderNumberIntroHtml = function (row) {
6824 return this.renderIntroHtml();
6825 };
6826 DayGrid.prototype.renderNumberCellsHtml = function (row) {
6827 var htmls = [];
6828 var col;
6829 var date;
6830 for (col = 0; col < this.colCnt; col++) {
6831 date = this.getCellDate(row, col);
6832 htmls.push(this.renderNumberCellHtml(date));
6833 }
6834 return htmls.join('');
6835 };
6836 // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
6837 // The number row will only exist if either day numbers or week numbers are turned on.
6838 DayGrid.prototype.renderNumberCellHtml = function (date) {
6839 var view = this.view;
6840 var html = '';
6841 var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
6842 var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
6843 var classes;
6844 var weekCalcFirstDoW;
6845 if (!isDayNumberVisible && !this.cellWeekNumbersVisible) {
6846 // no numbers in day cell (week number must be along the side)
6847 return '<td/>'; // will create an empty space above events :(
6848 }
6849 classes = this.getDayClasses(date);
6850 classes.unshift('fc-day-top');
6851 if (this.cellWeekNumbersVisible) {
6852 // To determine the day of week number change under ISO, we cannot
6853 // rely on moment.js methods such as firstDayOfWeek() or weekday(),
6854 // because they rely on the locale's dow (possibly overridden by
6855 // our firstDay option), which may not be Monday. We cannot change
6856 // dow, because that would affect the calendar start day as well.
6857 if (date._locale._fullCalendar_weekCalc === 'ISO') {
6858 weekCalcFirstDoW = 1; // Monday by ISO 8601 definition
6859 }
6860 else {
6861 weekCalcFirstDoW = date._locale.firstDayOfWeek();
6862 }
6863 }
6864 html += '<td class="' + classes.join(' ') + '"' +
6865 (isDateValid ?
6866 ' data-date="' + date.format() + '"' :
6867 '') +
6868 '>';
6869 if (this.cellWeekNumbersVisible && (date.day() === weekCalcFirstDoW)) {
6870 html += view.buildGotoAnchorHtml({ date: date, type: 'week' }, { 'class': 'fc-week-number' }, date.format('w') // inner HTML
6871 );
6872 }
6873 if (isDayNumberVisible) {
6874 html += view.buildGotoAnchorHtml(date, { 'class': 'fc-day-number' }, date.format('D') // inner HTML
6875 );
6876 }
6877 html += '</td>';
6878 return html;
6879 };
6880 /* Hit System
6881 ------------------------------------------------------------------------------------------------------------------*/
6882 DayGrid.prototype.prepareHits = function () {
6883 this.colCoordCache.build();
6884 this.rowCoordCache.build();
6885 this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
6886 };
6887 DayGrid.prototype.releaseHits = function () {
6888 this.colCoordCache.clear();
6889 this.rowCoordCache.clear();
6890 };
6891 DayGrid.prototype.queryHit = function (leftOffset, topOffset) {
6892 if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) {
6893 var col = this.colCoordCache.getHorizontalIndex(leftOffset);
6894 var row = this.rowCoordCache.getVerticalIndex(topOffset);
6895 if (row != null && col != null) {
6896 return this.getCellHit(row, col);
6897 }
6898 }
6899 };
6900 DayGrid.prototype.getHitFootprint = function (hit) {
6901 var range = this.getCellRange(hit.row, hit.col);
6902 return new ComponentFootprint_1.default(new UnzonedRange_1.default(range.start, range.end), true // all-day?
6903 );
6904 };
6905 DayGrid.prototype.getHitEl = function (hit) {
6906 return this.getCellEl(hit.row, hit.col);
6907 };
6908 /* Cell System
6909 ------------------------------------------------------------------------------------------------------------------*/
6910 // FYI: the first column is the leftmost column, regardless of date
6911 DayGrid.prototype.getCellHit = function (row, col) {
6912 return {
6913 row: row,
6914 col: col,
6915 component: this,
6916 left: this.colCoordCache.getLeftOffset(col),
6917 right: this.colCoordCache.getRightOffset(col),
6918 top: this.rowCoordCache.getTopOffset(row),
6919 bottom: this.rowCoordCache.getBottomOffset(row)
6920 };
6921 };
6922 DayGrid.prototype.getCellEl = function (row, col) {
6923 return this.cellEls.eq(row * this.colCnt + col);
6924 };
6925 /* Event Rendering
6926 ------------------------------------------------------------------------------------------------------------------*/
6927 // Unrenders all events currently rendered on the grid
6928 DayGrid.prototype.executeEventUnrender = function () {
6929 this.removeSegPopover(); // removes the "more.." events popover
6930 _super.prototype.executeEventUnrender.call(this);
6931 };
6932 // Retrieves all rendered segment objects currently rendered on the grid
6933 DayGrid.prototype.getOwnEventSegs = function () {
6934 // append the segments from the "more..." popover
6935 return _super.prototype.getOwnEventSegs.call(this).concat(this.popoverSegs || []);
6936 };
6937 /* Event Drag Visualization
6938 ------------------------------------------------------------------------------------------------------------------*/
6939 // Renders a visual indication of an event or external element being dragged.
6940 // `eventLocation` has zoned start and end (optional)
6941 DayGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
6942 var i;
6943 for (i = 0; i < eventFootprints.length; i++) {
6944 this.renderHighlight(eventFootprints[i].componentFootprint);
6945 }
6946 // render drags from OTHER components as helpers
6947 if (eventFootprints.length && seg && seg.component !== this) {
6948 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
6949 return true; // signal helpers rendered
6950 }
6951 };
6952 // Unrenders any visual indication of a hovering event
6953 DayGrid.prototype.unrenderDrag = function () {
6954 this.unrenderHighlight();
6955 this.helperRenderer.unrender();
6956 };
6957 /* Event Resize Visualization
6958 ------------------------------------------------------------------------------------------------------------------*/
6959 // Renders a visual indication of an event being resized
6960 DayGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
6961 var i;
6962 for (i = 0; i < eventFootprints.length; i++) {
6963 this.renderHighlight(eventFootprints[i].componentFootprint);
6964 }
6965 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
6966 };
6967 // Unrenders a visual indication of an event being resized
6968 DayGrid.prototype.unrenderEventResize = function () {
6969 this.unrenderHighlight();
6970 this.helperRenderer.unrender();
6971 };
6972 /* More+ Link Popover
6973 ------------------------------------------------------------------------------------------------------------------*/
6974 DayGrid.prototype.removeSegPopover = function () {
6975 if (this.segPopover) {
6976 this.segPopover.hide(); // in handler, will call segPopover's removeElement
6977 }
6978 };
6979 // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
6980 // `levelLimit` can be false (don't limit), a number, or true (should be computed).
6981 DayGrid.prototype.limitRows = function (levelLimit) {
6982 var rowStructs = this.eventRenderer.rowStructs || [];
6983 var row; // row #
6984 var rowLevelLimit;
6985 for (row = 0; row < rowStructs.length; row++) {
6986 this.unlimitRow(row);
6987 if (!levelLimit) {
6988 rowLevelLimit = false;
6989 }
6990 else if (typeof levelLimit === 'number') {
6991 rowLevelLimit = levelLimit;
6992 }
6993 else {
6994 rowLevelLimit = this.computeRowLevelLimit(row);
6995 }
6996 if (rowLevelLimit !== false) {
6997 this.limitRow(row, rowLevelLimit);
6998 }
6999 }
7000 };
7001 // Computes the number of levels a row will accomodate without going outside its bounds.
7002 // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
7003 // `row` is the row number.
7004 DayGrid.prototype.computeRowLevelLimit = function (row) {
7005 var rowEl = this.rowEls.eq(row); // the containing "fake" row div
7006 var rowHeight = rowEl.height(); // TODO: cache somehow?
7007 var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children();
7008 var i;
7009 var trEl;
7010 var trHeight;
7011 function iterInnerHeights(i, childNode) {
7012 trHeight = Math.max(trHeight, $(childNode).outerHeight());
7013 }
7014 // Reveal one level <tr> at a time and stop when we find one out of bounds
7015 for (i = 0; i < trEls.length; i++) {
7016 trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)
7017 // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,
7018 // so instead, find the tallest inner content element.
7019 trHeight = 0;
7020 trEl.find('> td > :first-child').each(iterInnerHeights);
7021 if (trEl.position().top + trHeight > rowHeight) {
7022 return i;
7023 }
7024 }
7025 return false; // should not limit at all
7026 };
7027 // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
7028 // `row` is the row number.
7029 // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
7030 DayGrid.prototype.limitRow = function (row, levelLimit) {
7031 var _this = this;
7032 var rowStruct = this.eventRenderer.rowStructs[row];
7033 var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
7034 var col = 0; // col #, left-to-right (not chronologically)
7035 var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
7036 var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row
7037 var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
7038 var i;
7039 var seg;
7040 var segsBelow; // array of segment objects below `seg` in the current `col`
7041 var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
7042 var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
7043 var td;
7044 var rowspan;
7045 var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
7046 var j;
7047 var moreTd;
7048 var moreWrap;
7049 var moreLink;
7050 // Iterates through empty level cells and places "more" links inside if need be
7051 var emptyCellsUntil = function (endCol) {
7052 while (col < endCol) {
7053 segsBelow = _this.getCellSegs(row, col, levelLimit);
7054 if (segsBelow.length) {
7055 td = cellMatrix[levelLimit - 1][col];
7056 moreLink = _this.renderMoreLink(row, col, segsBelow);
7057 moreWrap = $('<div/>').append(moreLink);
7058 td.append(moreWrap);
7059 moreNodes.push(moreWrap[0]);
7060 }
7061 col++;
7062 }
7063 };
7064 if (levelLimit && levelLimit < rowStruct.segLevels.length) {
7065 levelSegs = rowStruct.segLevels[levelLimit - 1];
7066 cellMatrix = rowStruct.cellMatrix;
7067 limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit
7068 .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array
7069 // iterate though segments in the last allowable level
7070 for (i = 0; i < levelSegs.length; i++) {
7071 seg = levelSegs[i];
7072 emptyCellsUntil(seg.leftCol); // process empty cells before the segment
7073 // determine *all* segments below `seg` that occupy the same columns
7074 colSegsBelow = [];
7075 totalSegsBelow = 0;
7076 while (col <= seg.rightCol) {
7077 segsBelow = this.getCellSegs(row, col, levelLimit);
7078 colSegsBelow.push(segsBelow);
7079 totalSegsBelow += segsBelow.length;
7080 col++;
7081 }
7082 if (totalSegsBelow) {
7083 td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell
7084 rowspan = td.attr('rowspan') || 1;
7085 segMoreNodes = [];
7086 // make a replacement <td> for each column the segment occupies. will be one for each colspan
7087 for (j = 0; j < colSegsBelow.length; j++) {
7088 moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan);
7089 segsBelow = colSegsBelow[j];
7090 moreLink = this.renderMoreLink(row, seg.leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
7091 );
7092 moreWrap = $('<div/>').append(moreLink);
7093 moreTd.append(moreWrap);
7094 segMoreNodes.push(moreTd[0]);
7095 moreNodes.push(moreTd[0]);
7096 }
7097 td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements
7098 limitedNodes.push(td[0]);
7099 }
7100 }
7101 emptyCellsUntil(this.colCnt); // finish off the level
7102 rowStruct.moreEls = $(moreNodes); // for easy undoing later
7103 rowStruct.limitedEls = $(limitedNodes); // for easy undoing later
7104 }
7105 };
7106 // Reveals all levels and removes all "more"-related elements for a grid's row.
7107 // `row` is a row number.
7108 DayGrid.prototype.unlimitRow = function (row) {
7109 var rowStruct = this.eventRenderer.rowStructs[row];
7110 if (rowStruct.moreEls) {
7111 rowStruct.moreEls.remove();
7112 rowStruct.moreEls = null;
7113 }
7114 if (rowStruct.limitedEls) {
7115 rowStruct.limitedEls.removeClass('fc-limited');
7116 rowStruct.limitedEls = null;
7117 }
7118 };
7119 // Renders an <a> element that represents hidden event element for a cell.
7120 // Responsible for attaching click handler as well.
7121 DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
7122 var _this = this;
7123 var view = this.view;
7124 return $('<a class="fc-more"/>')
7125 .text(this.getMoreLinkText(hiddenSegs.length))
7126 .on('click', function (ev) {
7127 var clickOption = _this.opt('eventLimitClick');
7128 var date = _this.getCellDate(row, col);
7129 var moreEl = $(ev.currentTarget);
7130 var dayEl = _this.getCellEl(row, col);
7131 var allSegs = _this.getCellSegs(row, col);
7132 // rescope the segments to be within the cell's date
7133 var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
7134 var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
7135 if (typeof clickOption === 'function') {
7136 // the returned value can be an atomic option
7137 clickOption = _this.publiclyTrigger('eventLimitClick', {
7138 context: view,
7139 args: [
7140 {
7141 date: date.clone(),
7142 dayEl: dayEl,
7143 moreEl: moreEl,
7144 segs: reslicedAllSegs,
7145 hiddenSegs: reslicedHiddenSegs
7146 },
7147 ev,
7148 view
7149 ]
7150 });
7151 }
7152 if (clickOption === 'popover') {
7153 _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
7154 }
7155 else if (typeof clickOption === 'string') {
7156 view.calendar.zoomTo(date, clickOption);
7157 }
7158 });
7159 };
7160 // Reveals the popover that displays all events within a cell
7161 DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
7162 var _this = this;
7163 var view = this.view;
7164 var moreWrap = moreLink.parent(); // the <div> wrapper around the <a>
7165 var topEl; // the element we want to match the top coordinate of
7166 var options;
7167 if (this.rowCnt === 1) {
7168 topEl = view.el; // will cause the popover to cover any sort of header
7169 }
7170 else {
7171 topEl = this.rowEls.eq(row); // will align with top of row
7172 }
7173 options = {
7174 className: 'fc-more-popover ' + view.calendar.theme.getClass('popover'),
7175 content: this.renderSegPopoverContent(row, col, segs),
7176 parentEl: view.el,
7177 top: topEl.offset().top,
7178 autoHide: true,
7179 viewportConstrain: this.opt('popoverViewportConstrain'),
7180 hide: function () {
7181 // kill everything when the popover is hidden
7182 // notify events to be removed
7183 if (_this.popoverSegs) {
7184 _this.triggerBeforeEventSegsDestroyed(_this.popoverSegs);
7185 }
7186 _this.segPopover.removeElement();
7187 _this.segPopover = null;
7188 _this.popoverSegs = null;
7189 }
7190 };
7191 // Determine horizontal coordinate.
7192 // We use the moreWrap instead of the <td> to avoid border confusion.
7193 if (this.isRTL) {
7194 options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border
7195 }
7196 else {
7197 options.left = moreWrap.offset().left - 1; // -1 to be over cell border
7198 }
7199 this.segPopover = new Popover_1.default(options);
7200 this.segPopover.show();
7201 // the popover doesn't live within the grid's container element, and thus won't get the event
7202 // delegated-handlers for free. attach event-related handlers to the popover.
7203 this.bindAllSegHandlersToEl(this.segPopover.el);
7204 this.triggerAfterEventSegsRendered(segs);
7205 };
7206 // Builds the inner DOM contents of the segment popover
7207 DayGrid.prototype.renderSegPopoverContent = function (row, col, segs) {
7208 var view = this.view;
7209 var theme = view.calendar.theme;
7210 var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat'));
7211 var content = $('<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
7212 '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
7213 '<span class="fc-title">' +
7214 util_1.htmlEscape(title) +
7215 '</span>' +
7216 '<div class="fc-clear"/>' +
7217 '</div>' +
7218 '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
7219 '<div class="fc-event-container"></div>' +
7220 '</div>');
7221 var segContainer = content.find('.fc-event-container');
7222 var i;
7223 // render each seg's `el` and only return the visible segs
7224 segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true
7225 this.popoverSegs = segs;
7226 for (i = 0; i < segs.length; i++) {
7227 // because segments in the popover are not part of a grid coordinate system, provide a hint to any
7228 // grids that want to do drag-n-drop about which cell it came from
7229 this.hitsNeeded();
7230 segs[i].hit = this.getCellHit(row, col);
7231 this.hitsNotNeeded();
7232 segContainer.append(segs[i].el);
7233 }
7234 return content;
7235 };
7236 // Given the events within an array of segment objects, reslice them to be in a single day
7237 DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
7238 var dayStart = dayDate.clone();
7239 var dayEnd = dayStart.clone().add(1, 'days');
7240 var dayRange = new UnzonedRange_1.default(dayStart, dayEnd);
7241 var newSegs = [];
7242 var i;
7243 var seg;
7244 var slicedRange;
7245 for (i = 0; i < segs.length; i++) {
7246 seg = segs[i];
7247 slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange);
7248 if (slicedRange) {
7249 newSegs.push($.extend({}, seg, {
7250 footprint: new EventFootprint_1.default(new ComponentFootprint_1.default(slicedRange, seg.footprint.componentFootprint.isAllDay), seg.footprint.eventDef, seg.footprint.eventInstance),
7251 isStart: seg.isStart && slicedRange.isStart,
7252 isEnd: seg.isEnd && slicedRange.isEnd
7253 }));
7254 }
7255 }
7256 // force an order because eventsToSegs doesn't guarantee one
7257 // TODO: research if still needed
7258 this.eventRenderer.sortEventSegs(newSegs);
7259 return newSegs;
7260 };
7261 // Generates the text that should be inside a "more" link, given the number of events it represents
7262 DayGrid.prototype.getMoreLinkText = function (num) {
7263 var opt = this.opt('eventLimitText');
7264 if (typeof opt === 'function') {
7265 return opt(num);
7266 }
7267 else {
7268 return '+' + num + ' ' + opt;
7269 }
7270 };
7271 // Returns segments within a given cell.
7272 // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
7273 DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
7274 var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
7275 var level = startLevel || 0;
7276 var segs = [];
7277 var seg;
7278 while (level < segMatrix.length) {
7279 seg = segMatrix[level][col];
7280 if (seg) {
7281 segs.push(seg);
7282 }
7283 level++;
7284 }
7285 return segs;
7286 };
7287 return DayGrid;
7288 }(InteractiveDateComponent_1.default));
7289 exports.default = DayGrid;
7290 DayGrid.prototype.eventRendererClass = DayGridEventRenderer_1.default;
7291 DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default;
7292 DayGrid.prototype.helperRendererClass = DayGridHelperRenderer_1.default;
7293 DayGrid.prototype.fillRendererClass = DayGridFillRenderer_1.default;
7294 StandardInteractionsMixin_1.default.mixInto(DayGrid);
7295 DayTableMixin_1.default.mixInto(DayGrid);
7296
7297
7298 /***/ }),
7299 /* 62 */
7300 /***/ (function(module, exports, __webpack_require__) {
7301
7302 Object.defineProperty(exports, "__esModule", { value: true });
7303 var tslib_1 = __webpack_require__(2);
7304 var $ = __webpack_require__(3);
7305 var util_1 = __webpack_require__(4);
7306 var Scroller_1 = __webpack_require__(39);
7307 var View_1 = __webpack_require__(41);
7308 var BasicViewDateProfileGenerator_1 = __webpack_require__(228);
7309 var DayGrid_1 = __webpack_require__(61);
7310 /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
7311 ----------------------------------------------------------------------------------------------------------------------*/
7312 // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
7313 // It is responsible for managing width/height.
7314 var BasicView = /** @class */ (function (_super) {
7315 tslib_1.__extends(BasicView, _super);
7316 function BasicView(calendar, viewSpec) {
7317 var _this = _super.call(this, calendar, viewSpec) || this;
7318 _this.dayGrid = _this.instantiateDayGrid();
7319 _this.dayGrid.isRigid = _this.hasRigidRows();
7320 if (_this.opt('weekNumbers')) {
7321 if (_this.opt('weekNumbersWithinDays')) {
7322 _this.dayGrid.cellWeekNumbersVisible = true;
7323 _this.dayGrid.colWeekNumbersVisible = false;
7324 }
7325 else {
7326 _this.dayGrid.cellWeekNumbersVisible = false;
7327 _this.dayGrid.colWeekNumbersVisible = true;
7328 }
7329 }
7330 _this.addChild(_this.dayGrid);
7331 _this.scroller = new Scroller_1.default({
7332 overflowX: 'hidden',
7333 overflowY: 'auto'
7334 });
7335 return _this;
7336 }
7337 // Generates the DayGrid object this view needs. Draws from this.dayGridClass
7338 BasicView.prototype.instantiateDayGrid = function () {
7339 // generate a subclass on the fly with BasicView-specific behavior
7340 // TODO: cache this subclass
7341 var subclass = makeDayGridSubclass(this.dayGridClass);
7342 return new subclass(this);
7343 };
7344 BasicView.prototype.executeDateRender = function (dateProfile) {
7345 this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit);
7346 _super.prototype.executeDateRender.call(this, dateProfile);
7347 };
7348 BasicView.prototype.renderSkeleton = function () {
7349 var dayGridContainerEl;
7350 var dayGridEl;
7351 this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml());
7352 this.scroller.render();
7353 dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container');
7354 dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl);
7355 this.el.find('.fc-body > tr > td').append(dayGridContainerEl);
7356 this.dayGrid.headContainerEl = this.el.find('.fc-head-container');
7357 this.dayGrid.setElement(dayGridEl);
7358 };
7359 BasicView.prototype.unrenderSkeleton = function () {
7360 this.dayGrid.removeElement();
7361 this.scroller.destroy();
7362 };
7363 // Builds the HTML skeleton for the view.
7364 // The day-grid component will render inside of a container defined by this HTML.
7365 BasicView.prototype.renderSkeletonHtml = function () {
7366 var theme = this.calendar.theme;
7367 return '' +
7368 '<table class="' + theme.getClass('tableGrid') + '">' +
7369 (this.opt('columnHeader') ?
7370 '<thead class="fc-head">' +
7371 '<tr>' +
7372 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
7373 '</tr>' +
7374 '</thead>' :
7375 '') +
7376 '<tbody class="fc-body">' +
7377 '<tr>' +
7378 '<td class="' + theme.getClass('widgetContent') + '"></td>' +
7379 '</tr>' +
7380 '</tbody>' +
7381 '</table>';
7382 };
7383 // Generates an HTML attribute string for setting the width of the week number column, if it is known
7384 BasicView.prototype.weekNumberStyleAttr = function () {
7385 if (this.weekNumberWidth != null) {
7386 return 'style="width:' + this.weekNumberWidth + 'px"';
7387 }
7388 return '';
7389 };
7390 // Determines whether each row should have a constant height
7391 BasicView.prototype.hasRigidRows = function () {
7392 var eventLimit = this.opt('eventLimit');
7393 return eventLimit && typeof eventLimit !== 'number';
7394 };
7395 /* Dimensions
7396 ------------------------------------------------------------------------------------------------------------------*/
7397 // Refreshes the horizontal dimensions of the view
7398 BasicView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
7399 var eventLimit = this.opt('eventLimit');
7400 var headRowEl = this.dayGrid.headContainerEl.find('.fc-row');
7401 var scrollerHeight;
7402 var scrollbarWidths;
7403 // hack to give the view some height prior to dayGrid's columns being rendered
7404 // TODO: separate setting height from scroller VS dayGrid.
7405 if (!this.dayGrid.rowEls) {
7406 if (!isAuto) {
7407 scrollerHeight = this.computeScrollerHeight(totalHeight);
7408 this.scroller.setHeight(scrollerHeight);
7409 }
7410 return;
7411 }
7412 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
7413 if (this.dayGrid.colWeekNumbersVisible) {
7414 // Make sure all week number cells running down the side have the same width.
7415 // Record the width for cells created later.
7416 this.weekNumberWidth = util_1.matchCellWidths(this.el.find('.fc-week-number'));
7417 }
7418 // reset all heights to be natural
7419 this.scroller.clear();
7420 util_1.uncompensateScroll(headRowEl);
7421 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
7422 // is the event limit a constant level number?
7423 if (eventLimit && typeof eventLimit === 'number') {
7424 this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
7425 }
7426 // distribute the height to the rows
7427 // (totalHeight is a "recommended" value if isAuto)
7428 scrollerHeight = this.computeScrollerHeight(totalHeight);
7429 this.setGridHeight(scrollerHeight, isAuto);
7430 // is the event limit dynamically calculated?
7431 if (eventLimit && typeof eventLimit !== 'number') {
7432 this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
7433 }
7434 if (!isAuto) {
7435 this.scroller.setHeight(scrollerHeight);
7436 scrollbarWidths = this.scroller.getScrollbarWidths();
7437 if (scrollbarWidths.left || scrollbarWidths.right) {
7438 util_1.compensateScroll(headRowEl, scrollbarWidths);
7439 // doing the scrollbar compensation might have created text overflow which created more height. redo
7440 scrollerHeight = this.computeScrollerHeight(totalHeight);
7441 this.scroller.setHeight(scrollerHeight);
7442 }
7443 // guarantees the same scrollbar widths
7444 this.scroller.lockOverflow(scrollbarWidths);
7445 }
7446 };
7447 // given a desired total height of the view, returns what the height of the scroller should be
7448 BasicView.prototype.computeScrollerHeight = function (totalHeight) {
7449 return totalHeight -
7450 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
7451 };
7452 // Sets the height of just the DayGrid component in this view
7453 BasicView.prototype.setGridHeight = function (height, isAuto) {
7454 if (isAuto) {
7455 util_1.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
7456 }
7457 else {
7458 util_1.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
7459 }
7460 };
7461 /* Scroll
7462 ------------------------------------------------------------------------------------------------------------------*/
7463 BasicView.prototype.computeInitialDateScroll = function () {
7464 return { top: 0 };
7465 };
7466 BasicView.prototype.queryDateScroll = function () {
7467 return { top: this.scroller.getScrollTop() };
7468 };
7469 BasicView.prototype.applyDateScroll = function (scroll) {
7470 if (scroll.top !== undefined) {
7471 this.scroller.setScrollTop(scroll.top);
7472 }
7473 };
7474 return BasicView;
7475 }(View_1.default));
7476 exports.default = BasicView;
7477 BasicView.prototype.dateProfileGeneratorClass = BasicViewDateProfileGenerator_1.default;
7478 BasicView.prototype.dayGridClass = DayGrid_1.default;
7479 // customize the rendering behavior of BasicView's dayGrid
7480 function makeDayGridSubclass(SuperClass) {
7481 return /** @class */ (function (_super) {
7482 tslib_1.__extends(SubClass, _super);
7483 function SubClass() {
7484 var _this = _super !== null && _super.apply(this, arguments) || this;
7485 _this.colWeekNumbersVisible = false; // display week numbers along the side?
7486 return _this;
7487 }
7488 // Generates the HTML that will go before the day-of week header cells
7489 SubClass.prototype.renderHeadIntroHtml = function () {
7490 var view = this.view;
7491 if (this.colWeekNumbersVisible) {
7492 return '' +
7493 '<th class="fc-week-number ' + view.calendar.theme.getClass('widgetHeader') + '" ' + view.weekNumberStyleAttr() + '>' +
7494 '<span>' + // needed for matchCellWidths
7495 util_1.htmlEscape(this.opt('weekNumberTitle')) +
7496 '</span>' +
7497 '</th>';
7498 }
7499 return '';
7500 };
7501 // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
7502 SubClass.prototype.renderNumberIntroHtml = function (row) {
7503 var view = this.view;
7504 var weekStart = this.getCellDate(row, 0);
7505 if (this.colWeekNumbersVisible) {
7506 return '' +
7507 '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' +
7508 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
7509 { date: weekStart, type: 'week', forceOff: this.colCnt === 1 }, weekStart.format('w') // inner HTML
7510 ) +
7511 '</td>';
7512 }
7513 return '';
7514 };
7515 // Generates the HTML that goes before the day bg cells for each day-row
7516 SubClass.prototype.renderBgIntroHtml = function () {
7517 var view = this.view;
7518 if (this.colWeekNumbersVisible) {
7519 return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' +
7520 view.weekNumberStyleAttr() + '></td>';
7521 }
7522 return '';
7523 };
7524 // Generates the HTML that goes before every other type of row generated by DayGrid.
7525 // Affects helper-skeleton and highlight-skeleton rows.
7526 SubClass.prototype.renderIntroHtml = function () {
7527 var view = this.view;
7528 if (this.colWeekNumbersVisible) {
7529 return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>';
7530 }
7531 return '';
7532 };
7533 SubClass.prototype.getIsNumbersVisible = function () {
7534 return DayGrid_1.default.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible;
7535 };
7536 return SubClass;
7537 }(SuperClass));
7538 }
7539
7540
7541 /***/ }),
7542 /* 63 */,
7543 /* 64 */,
7544 /* 65 */,
7545 /* 66 */,
7546 /* 67 */,
7547 /* 68 */,
7548 /* 69 */,
7549 /* 70 */,
7550 /* 71 */,
7551 /* 72 */,
7552 /* 73 */,
7553 /* 74 */,
7554 /* 75 */,
7555 /* 76 */,
7556 /* 77 */,
7557 /* 78 */,
7558 /* 79 */,
7559 /* 80 */,
7560 /* 81 */,
7561 /* 82 */,
7562 /* 83 */,
7563 /* 84 */,
7564 /* 85 */,
7565 /* 86 */,
7566 /* 87 */,
7567 /* 88 */,
7568 /* 89 */,
7569 /* 90 */,
7570 /* 91 */,
7571 /* 92 */,
7572 /* 93 */,
7573 /* 94 */,
7574 /* 95 */,
7575 /* 96 */,
7576 /* 97 */,
7577 /* 98 */,
7578 /* 99 */,
7579 /* 100 */,
7580 /* 101 */,
7581 /* 102 */,
7582 /* 103 */,
7583 /* 104 */,
7584 /* 105 */,
7585 /* 106 */,
7586 /* 107 */,
7587 /* 108 */,
7588 /* 109 */,
7589 /* 110 */,
7590 /* 111 */,
7591 /* 112 */,
7592 /* 113 */,
7593 /* 114 */,
7594 /* 115 */,
7595 /* 116 */,
7596 /* 117 */,
7597 /* 118 */,
7598 /* 119 */,
7599 /* 120 */,
7600 /* 121 */,
7601 /* 122 */,
7602 /* 123 */,
7603 /* 124 */,
7604 /* 125 */,
7605 /* 126 */,
7606 /* 127 */,
7607 /* 128 */,
7608 /* 129 */,
7609 /* 130 */,
7610 /* 131 */,
7611 /* 132 */,
7612 /* 133 */,
7613 /* 134 */,
7614 /* 135 */,
7615 /* 136 */,
7616 /* 137 */,
7617 /* 138 */,
7618 /* 139 */,
7619 /* 140 */,
7620 /* 141 */,
7621 /* 142 */,
7622 /* 143 */,
7623 /* 144 */,
7624 /* 145 */,
7625 /* 146 */,
7626 /* 147 */,
7627 /* 148 */,
7628 /* 149 */,
7629 /* 150 */,
7630 /* 151 */,
7631 /* 152 */,
7632 /* 153 */,
7633 /* 154 */,
7634 /* 155 */,
7635 /* 156 */,
7636 /* 157 */,
7637 /* 158 */,
7638 /* 159 */,
7639 /* 160 */,
7640 /* 161 */,
7641 /* 162 */,
7642 /* 163 */,
7643 /* 164 */,
7644 /* 165 */,
7645 /* 166 */,
7646 /* 167 */,
7647 /* 168 */,
7648 /* 169 */,
7649 /* 170 */,
7650 /* 171 */,
7651 /* 172 */,
7652 /* 173 */,
7653 /* 174 */,
7654 /* 175 */,
7655 /* 176 */,
7656 /* 177 */,
7657 /* 178 */,
7658 /* 179 */,
7659 /* 180 */,
7660 /* 181 */,
7661 /* 182 */,
7662 /* 183 */,
7663 /* 184 */,
7664 /* 185 */,
7665 /* 186 */,
7666 /* 187 */,
7667 /* 188 */,
7668 /* 189 */,
7669 /* 190 */,
7670 /* 191 */,
7671 /* 192 */,
7672 /* 193 */,
7673 /* 194 */,
7674 /* 195 */,
7675 /* 196 */,
7676 /* 197 */,
7677 /* 198 */,
7678 /* 199 */,
7679 /* 200 */,
7680 /* 201 */,
7681 /* 202 */,
7682 /* 203 */,
7683 /* 204 */,
7684 /* 205 */,
7685 /* 206 */,
7686 /* 207 */
7687 /***/ (function(module, exports, __webpack_require__) {
7688
7689 Object.defineProperty(exports, "__esModule", { value: true });
7690 var UnzonedRange_1 = __webpack_require__(5);
7691 var ComponentFootprint_1 = __webpack_require__(12);
7692 var EventDefParser_1 = __webpack_require__(49);
7693 var EventSource_1 = __webpack_require__(6);
7694 var util_1 = __webpack_require__(35);
7695 var Constraints = /** @class */ (function () {
7696 function Constraints(eventManager, _calendar) {
7697 this.eventManager = eventManager;
7698 this._calendar = _calendar;
7699 }
7700 Constraints.prototype.opt = function (name) {
7701 return this._calendar.opt(name);
7702 };
7703 /*
7704 determines if eventInstanceGroup is allowed,
7705 in relation to other EVENTS and business hours.
7706 */
7707 Constraints.prototype.isEventInstanceGroupAllowed = function (eventInstanceGroup) {
7708 var eventDef = eventInstanceGroup.getEventDef();
7709 var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
7710 var i;
7711 var peerEventInstances = this.getPeerEventInstances(eventDef);
7712 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange);
7713 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
7714 var constraintVal = eventDef.getConstraint();
7715 var overlapVal = eventDef.getOverlap();
7716 var eventAllowFunc = this.opt('eventAllow');
7717 for (i = 0; i < eventFootprints.length; i++) {
7718 if (!this.isFootprintAllowed(eventFootprints[i].componentFootprint, peerEventFootprints, constraintVal, overlapVal, eventFootprints[i].eventInstance)) {
7719 return false;
7720 }
7721 }
7722 if (eventAllowFunc) {
7723 for (i = 0; i < eventFootprints.length; i++) {
7724 if (eventAllowFunc(eventFootprints[i].componentFootprint.toLegacy(this._calendar), eventFootprints[i].getEventLegacy()) === false) {
7725 return false;
7726 }
7727 }
7728 }
7729 return true;
7730 };
7731 Constraints.prototype.getPeerEventInstances = function (eventDef) {
7732 return this.eventManager.getEventInstancesWithoutId(eventDef.id);
7733 };
7734 Constraints.prototype.isSelectionFootprintAllowed = function (componentFootprint) {
7735 var peerEventInstances = this.eventManager.getEventInstances();
7736 var peerEventRanges = peerEventInstances.map(util_1.eventInstanceToEventRange);
7737 var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
7738 var selectAllowFunc;
7739 if (this.isFootprintAllowed(componentFootprint, peerEventFootprints, this.opt('selectConstraint'), this.opt('selectOverlap'))) {
7740 selectAllowFunc = this.opt('selectAllow');
7741 if (selectAllowFunc) {
7742 return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false;
7743 }
7744 else {
7745 return true;
7746 }
7747 }
7748 return false;
7749 };
7750 Constraints.prototype.isFootprintAllowed = function (componentFootprint, peerEventFootprints, constraintVal, overlapVal, subjectEventInstance // optional
7751 ) {
7752 var constraintFootprints; // ComponentFootprint[]
7753 var overlapEventFootprints; // EventFootprint[]
7754 if (constraintVal != null) {
7755 constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay);
7756 if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) {
7757 return false;
7758 }
7759 }
7760 overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint);
7761 if (overlapVal === false) {
7762 if (overlapEventFootprints.length) {
7763 return false;
7764 }
7765 }
7766 else if (typeof overlapVal === 'function') {
7767 if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) {
7768 return false;
7769 }
7770 }
7771 if (subjectEventInstance) {
7772 if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) {
7773 return false;
7774 }
7775 }
7776 return true;
7777 };
7778 // Constraint
7779 // ------------------------------------------------------------------------------------------------
7780 Constraints.prototype.isFootprintWithinConstraints = function (componentFootprint, constraintFootprints) {
7781 var i;
7782 for (i = 0; i < constraintFootprints.length; i++) {
7783 if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) {
7784 return true;
7785 }
7786 }
7787 return false;
7788 };
7789 Constraints.prototype.constraintValToFootprints = function (constraintVal, isAllDay) {
7790 var eventInstances;
7791 if (constraintVal === 'businessHours') {
7792 return this.buildCurrentBusinessFootprints(isAllDay);
7793 }
7794 else if (typeof constraintVal === 'object') {
7795 eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events
7796 if (!eventInstances) {
7797 return this.parseFootprints(constraintVal);
7798 }
7799 else {
7800 return this.eventInstancesToFootprints(eventInstances);
7801 }
7802 }
7803 else if (constraintVal != null) {
7804 eventInstances = this.eventManager.getEventInstancesWithId(constraintVal);
7805 return this.eventInstancesToFootprints(eventInstances);
7806 }
7807 };
7808 // returns ComponentFootprint[]
7809 // uses current view's range
7810 Constraints.prototype.buildCurrentBusinessFootprints = function (isAllDay) {
7811 var view = this._calendar.view;
7812 var businessHourGenerator = view.get('businessHourGenerator');
7813 var unzonedRange = view.dateProfile.activeUnzonedRange;
7814 var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange);
7815 if (eventInstanceGroup) {
7816 return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances);
7817 }
7818 else {
7819 return [];
7820 }
7821 };
7822 // conversion util
7823 Constraints.prototype.eventInstancesToFootprints = function (eventInstances) {
7824 var eventRanges = eventInstances.map(util_1.eventInstanceToEventRange);
7825 var eventFootprints = this.eventRangesToEventFootprints(eventRanges);
7826 return eventFootprints.map(util_1.eventFootprintToComponentFootprint);
7827 };
7828 // Overlap
7829 // ------------------------------------------------------------------------------------------------
7830 Constraints.prototype.collectOverlapEventFootprints = function (peerEventFootprints, targetFootprint) {
7831 var overlapEventFootprints = [];
7832 var i;
7833 for (i = 0; i < peerEventFootprints.length; i++) {
7834 if (this.footprintsIntersect(targetFootprint, peerEventFootprints[i].componentFootprint)) {
7835 overlapEventFootprints.push(peerEventFootprints[i]);
7836 }
7837 }
7838 return overlapEventFootprints;
7839 };
7840 // Conversion: eventDefs -> eventInstances -> eventRanges -> eventFootprints -> componentFootprints
7841 // ------------------------------------------------------------------------------------------------
7842 // NOTE: this might seem like repetitive code with the Grid class, however, this code is related to
7843 // constraints whereas the Grid code is related to rendering. Each approach might want to convert
7844 // eventRanges -> eventFootprints in a different way. Regardless, there are opportunities to make
7845 // this more DRY.
7846 /*
7847 Returns false on invalid input.
7848 */
7849 Constraints.prototype.parseEventDefToInstances = function (eventInput) {
7850 var eventManager = this.eventManager;
7851 var eventDef = EventDefParser_1.default.parse(eventInput, new EventSource_1.default(this._calendar));
7852 if (!eventDef) {
7853 return false;
7854 }
7855 return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange);
7856 };
7857 Constraints.prototype.eventRangesToEventFootprints = function (eventRanges) {
7858 var i;
7859 var eventFootprints = [];
7860 for (i = 0; i < eventRanges.length; i++) {
7861 eventFootprints.push.apply(// footprints
7862 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i]));
7863 }
7864 return eventFootprints;
7865 };
7866 Constraints.prototype.eventRangeToEventFootprints = function (eventRange) {
7867 return [util_1.eventRangeToEventFootprint(eventRange)];
7868 };
7869 /*
7870 Parses footprints directly.
7871 Very similar to EventDateProfile::parse :(
7872 */
7873 Constraints.prototype.parseFootprints = function (rawInput) {
7874 var start;
7875 var end;
7876 if (rawInput.start) {
7877 start = this._calendar.moment(rawInput.start);
7878 if (!start.isValid()) {
7879 start = null;
7880 }
7881 }
7882 if (rawInput.end) {
7883 end = this._calendar.moment(rawInput.end);
7884 if (!end.isValid()) {
7885 end = null;
7886 }
7887 }
7888 return [
7889 new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay
7890 )
7891 ];
7892 };
7893 // Footprint Utils
7894 // ----------------------------------------------------------------------------------------
7895 Constraints.prototype.footprintContainsFootprint = function (outerFootprint, innerFootprint) {
7896 return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange);
7897 };
7898 Constraints.prototype.footprintsIntersect = function (footprint0, footprint1) {
7899 return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange);
7900 };
7901 return Constraints;
7902 }());
7903 exports.default = Constraints;
7904 // optional subjectEventInstance
7905 function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) {
7906 var i;
7907 for (i = 0; i < overlapEventFootprints.length; i++) {
7908 if (!overlapFunc(overlapEventFootprints[i].eventInstance.toLegacy(), subjectEventInstance ? subjectEventInstance.toLegacy() : null)) {
7909 return false;
7910 }
7911 }
7912 return true;
7913 }
7914 function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) {
7915 var subjectLegacyInstance = subjectEventInstance.toLegacy();
7916 var i;
7917 var overlapEventInstance;
7918 var overlapEventDef;
7919 var overlapVal;
7920 for (i = 0; i < overlapEventFootprints.length; i++) {
7921 overlapEventInstance = overlapEventFootprints[i].eventInstance;
7922 overlapEventDef = overlapEventInstance.def;
7923 // don't need to pass in calendar, because don't want to consider global eventOverlap property,
7924 // because we already considered that earlier in the process.
7925 overlapVal = overlapEventDef.getOverlap();
7926 if (overlapVal === false) {
7927 return false;
7928 }
7929 else if (typeof overlapVal === 'function') {
7930 if (!overlapVal(overlapEventInstance.toLegacy(), subjectLegacyInstance)) {
7931 return false;
7932 }
7933 }
7934 }
7935 return true;
7936 }
7937
7938
7939 /***/ }),
7940 /* 208 */
7941 /***/ (function(module, exports, __webpack_require__) {
7942
7943 /*
7944 USAGE:
7945 import { default as ParsableModelMixin, ParsableModelInterface } from './ParsableModelMixin'
7946 in class:
7947 applyProps: ParsableModelInterface['applyProps']
7948 applyManualStandardProps: ParsableModelInterface['applyManualStandardProps']
7949 applyMiscProps: ParsableModelInterface['applyMiscProps']
7950 isStandardProp: ParsableModelInterface['isStandardProp']
7951 static defineStandardProps = ParsableModelMixin.defineStandardProps
7952 static copyVerbatimStandardProps = ParsableModelMixin.copyVerbatimStandardProps
7953 after class:
7954 ParsableModelMixin.mixInto(TheClass)
7955 */
7956 Object.defineProperty(exports, "__esModule", { value: true });
7957 var tslib_1 = __webpack_require__(2);
7958 var util_1 = __webpack_require__(4);
7959 var Mixin_1 = __webpack_require__(14);
7960 var ParsableModelMixin = /** @class */ (function (_super) {
7961 tslib_1.__extends(ParsableModelMixin, _super);
7962 function ParsableModelMixin() {
7963 return _super !== null && _super.apply(this, arguments) || this;
7964 }
7965 ParsableModelMixin.defineStandardProps = function (propDefs) {
7966 var proto = this.prototype;
7967 if (!proto.hasOwnProperty('standardPropMap')) {
7968 proto.standardPropMap = Object.create(proto.standardPropMap);
7969 }
7970 util_1.copyOwnProps(propDefs, proto.standardPropMap);
7971 };
7972 ParsableModelMixin.copyVerbatimStandardProps = function (src, dest) {
7973 var map = this.prototype.standardPropMap;
7974 var propName;
7975 for (propName in map) {
7976 if (src[propName] != null && // in the src object?
7977 map[propName] === true // false means "copy verbatim"
7978 ) {
7979 dest[propName] = src[propName];
7980 }
7981 }
7982 };
7983 /*
7984 Returns true/false for success.
7985 Meant to be only called ONCE, at object creation.
7986 */
7987 ParsableModelMixin.prototype.applyProps = function (rawProps) {
7988 var standardPropMap = this.standardPropMap;
7989 var manualProps = {};
7990 var miscProps = {};
7991 var propName;
7992 for (propName in rawProps) {
7993 if (standardPropMap[propName] === true) {
7994 this[propName] = rawProps[propName];
7995 }
7996 else if (standardPropMap[propName] === false) {
7997 manualProps[propName] = rawProps[propName];
7998 }
7999 else {
8000 miscProps[propName] = rawProps[propName];
8001 }
8002 }
8003 this.applyMiscProps(miscProps);
8004 return this.applyManualStandardProps(manualProps);
8005 };
8006 /*
8007 If subclasses override, they must call this supermethod and return the boolean response.
8008 Meant to be only called ONCE, at object creation.
8009 */
8010 ParsableModelMixin.prototype.applyManualStandardProps = function (rawProps) {
8011 return true;
8012 };
8013 /*
8014 Can be called even after initial object creation.
8015 */
8016 ParsableModelMixin.prototype.applyMiscProps = function (rawProps) {
8017 // subclasses can implement
8018 };
8019 /*
8020 TODO: why is this a method when defineStandardProps is static
8021 */
8022 ParsableModelMixin.prototype.isStandardProp = function (propName) {
8023 return propName in this.standardPropMap;
8024 };
8025 return ParsableModelMixin;
8026 }(Mixin_1.default));
8027 exports.default = ParsableModelMixin;
8028 ParsableModelMixin.prototype.standardPropMap = {}; // will be cloned by defineStandardProps
8029
8030
8031 /***/ }),
8032 /* 209 */
8033 /***/ (function(module, exports) {
8034
8035 Object.defineProperty(exports, "__esModule", { value: true });
8036 var EventInstance = /** @class */ (function () {
8037 function EventInstance(def, dateProfile) {
8038 this.def = def;
8039 this.dateProfile = dateProfile;
8040 }
8041 EventInstance.prototype.toLegacy = function () {
8042 var dateProfile = this.dateProfile;
8043 var obj = this.def.toLegacy();
8044 obj.start = dateProfile.start.clone();
8045 obj.end = dateProfile.end ? dateProfile.end.clone() : null;
8046 return obj;
8047 };
8048 return EventInstance;
8049 }());
8050 exports.default = EventInstance;
8051
8052
8053 /***/ }),
8054 /* 210 */
8055 /***/ (function(module, exports, __webpack_require__) {
8056
8057 Object.defineProperty(exports, "__esModule", { value: true });
8058 var tslib_1 = __webpack_require__(2);
8059 var $ = __webpack_require__(3);
8060 var moment = __webpack_require__(0);
8061 var EventDef_1 = __webpack_require__(34);
8062 var EventInstance_1 = __webpack_require__(209);
8063 var EventDateProfile_1 = __webpack_require__(17);
8064 var RecurringEventDef = /** @class */ (function (_super) {
8065 tslib_1.__extends(RecurringEventDef, _super);
8066 function RecurringEventDef() {
8067 return _super !== null && _super.apply(this, arguments) || this;
8068 }
8069 RecurringEventDef.prototype.isAllDay = function () {
8070 return !this.startTime && !this.endTime;
8071 };
8072 RecurringEventDef.prototype.buildInstances = function (unzonedRange) {
8073 var calendar = this.source.calendar;
8074 var unzonedDate = unzonedRange.getStart();
8075 var unzonedEnd = unzonedRange.getEnd();
8076 var zonedDayStart;
8077 var instanceStart;
8078 var instanceEnd;
8079 var instances = [];
8080 while (unzonedDate.isBefore(unzonedEnd)) {
8081 // if everyday, or this particular day-of-week
8082 if (!this.dowHash || this.dowHash[unzonedDate.day()]) {
8083 zonedDayStart = calendar.applyTimezone(unzonedDate);
8084 instanceStart = zonedDayStart.clone();
8085 instanceEnd = null;
8086 if (this.startTime) {
8087 instanceStart.time(this.startTime);
8088 }
8089 else {
8090 instanceStart.stripTime();
8091 }
8092 if (this.endTime) {
8093 instanceEnd = zonedDayStart.clone().time(this.endTime);
8094 }
8095 instances.push(new EventInstance_1.default(this, // definition
8096 new EventDateProfile_1.default(instanceStart, instanceEnd, calendar)));
8097 }
8098 unzonedDate.add(1, 'days');
8099 }
8100 return instances;
8101 };
8102 RecurringEventDef.prototype.setDow = function (dowNumbers) {
8103 if (!this.dowHash) {
8104 this.dowHash = {};
8105 }
8106 for (var i = 0; i < dowNumbers.length; i++) {
8107 this.dowHash[dowNumbers[i]] = true;
8108 }
8109 };
8110 RecurringEventDef.prototype.clone = function () {
8111 var def = _super.prototype.clone.call(this);
8112 if (def.startTime) {
8113 def.startTime = moment.duration(this.startTime);
8114 }
8115 if (def.endTime) {
8116 def.endTime = moment.duration(this.endTime);
8117 }
8118 if (this.dowHash) {
8119 def.dowHash = $.extend({}, this.dowHash);
8120 }
8121 return def;
8122 };
8123 return RecurringEventDef;
8124 }(EventDef_1.default));
8125 exports.default = RecurringEventDef;
8126 /*
8127 HACK to work with TypeScript mixins
8128 NOTE: if super-method fails, should still attempt to apply
8129 */
8130 RecurringEventDef.prototype.applyProps = function (rawProps) {
8131 var superSuccess = EventDef_1.default.prototype.applyProps.call(this, rawProps);
8132 if (rawProps.start) {
8133 this.startTime = moment.duration(rawProps.start);
8134 }
8135 if (rawProps.end) {
8136 this.endTime = moment.duration(rawProps.end);
8137 }
8138 if (rawProps.dow) {
8139 this.setDow(rawProps.dow);
8140 }
8141 return superSuccess;
8142 };
8143 // Parsing
8144 // ---------------------------------------------------------------------------------------------------------------------
8145 RecurringEventDef.defineStandardProps({
8146 start: false,
8147 end: false,
8148 dow: false
8149 });
8150
8151
8152 /***/ }),
8153 /* 211 */
8154 /***/ (function(module, exports) {
8155
8156 Object.defineProperty(exports, "__esModule", { value: true });
8157 var EventRange = /** @class */ (function () {
8158 function EventRange(unzonedRange, eventDef, eventInstance) {
8159 this.unzonedRange = unzonedRange;
8160 this.eventDef = eventDef;
8161 if (eventInstance) {
8162 this.eventInstance = eventInstance;
8163 }
8164 }
8165 return EventRange;
8166 }());
8167 exports.default = EventRange;
8168
8169
8170 /***/ }),
8171 /* 212 */
8172 /***/ (function(module, exports, __webpack_require__) {
8173
8174 Object.defineProperty(exports, "__esModule", { value: true });
8175 var $ = __webpack_require__(3);
8176 var util_1 = __webpack_require__(35);
8177 var EventInstanceGroup_1 = __webpack_require__(18);
8178 var RecurringEventDef_1 = __webpack_require__(210);
8179 var EventSource_1 = __webpack_require__(6);
8180 var BUSINESS_HOUR_EVENT_DEFAULTS = {
8181 start: '09:00',
8182 end: '17:00',
8183 dow: [1, 2, 3, 4, 5],
8184 rendering: 'inverse-background'
8185 // classNames are defined in businessHoursSegClasses
8186 };
8187 var BusinessHourGenerator = /** @class */ (function () {
8188 function BusinessHourGenerator(rawComplexDef, calendar) {
8189 this.rawComplexDef = rawComplexDef;
8190 this.calendar = calendar;
8191 }
8192 BusinessHourGenerator.prototype.buildEventInstanceGroup = function (isAllDay, unzonedRange) {
8193 var eventDefs = this.buildEventDefs(isAllDay);
8194 var eventInstanceGroup;
8195 if (eventDefs.length) {
8196 eventInstanceGroup = new EventInstanceGroup_1.default(util_1.eventDefsToEventInstances(eventDefs, unzonedRange));
8197 // so that inverse-background rendering can happen even when no eventRanges in view
8198 eventInstanceGroup.explicitEventDef = eventDefs[0];
8199 return eventInstanceGroup;
8200 }
8201 };
8202 BusinessHourGenerator.prototype.buildEventDefs = function (isAllDay) {
8203 var rawComplexDef = this.rawComplexDef;
8204 var rawDefs = [];
8205 var requireDow = false;
8206 var i;
8207 var defs = [];
8208 if (rawComplexDef === true) {
8209 rawDefs = [{}]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
8210 }
8211 else if ($.isPlainObject(rawComplexDef)) {
8212 rawDefs = [rawComplexDef];
8213 }
8214 else if ($.isArray(rawComplexDef)) {
8215 rawDefs = rawComplexDef;
8216 requireDow = true; // every sub-definition NEEDS a day-of-week
8217 }
8218 for (i = 0; i < rawDefs.length; i++) {
8219 if (!requireDow || rawDefs[i].dow) {
8220 defs.push(this.buildEventDef(isAllDay, rawDefs[i]));
8221 }
8222 }
8223 return defs;
8224 };
8225 BusinessHourGenerator.prototype.buildEventDef = function (isAllDay, rawDef) {
8226 var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef);
8227 if (isAllDay) {
8228 fullRawDef.start = null;
8229 fullRawDef.end = null;
8230 }
8231 return RecurringEventDef_1.default.parse(fullRawDef, new EventSource_1.default(this.calendar) // dummy source
8232 );
8233 };
8234 return BusinessHourGenerator;
8235 }());
8236 exports.default = BusinessHourGenerator;
8237
8238
8239 /***/ }),
8240 /* 213 */
8241 /***/ (function(module, exports, __webpack_require__) {
8242
8243 Object.defineProperty(exports, "__esModule", { value: true });
8244 var tslib_1 = __webpack_require__(2);
8245 var Theme_1 = __webpack_require__(19);
8246 var StandardTheme = /** @class */ (function (_super) {
8247 tslib_1.__extends(StandardTheme, _super);
8248 function StandardTheme() {
8249 return _super !== null && _super.apply(this, arguments) || this;
8250 }
8251 return StandardTheme;
8252 }(Theme_1.default));
8253 exports.default = StandardTheme;
8254 StandardTheme.prototype.classes = {
8255 widget: 'fc-unthemed',
8256 widgetHeader: 'fc-widget-header',
8257 widgetContent: 'fc-widget-content',
8258 buttonGroup: 'fc-button-group',
8259 button: 'fc-button',
8260 cornerLeft: 'fc-corner-left',
8261 cornerRight: 'fc-corner-right',
8262 stateDefault: 'fc-state-default',
8263 stateActive: 'fc-state-active',
8264 stateDisabled: 'fc-state-disabled',
8265 stateHover: 'fc-state-hover',
8266 stateDown: 'fc-state-down',
8267 popoverHeader: 'fc-widget-header',
8268 popoverContent: 'fc-widget-content',
8269 // day grid
8270 headerRow: 'fc-widget-header',
8271 dayRow: 'fc-widget-content',
8272 // list view
8273 listView: 'fc-widget-content'
8274 };
8275 StandardTheme.prototype.baseIconClass = 'fc-icon';
8276 StandardTheme.prototype.iconClasses = {
8277 close: 'fc-icon-x',
8278 prev: 'fc-icon-left-single-arrow',
8279 next: 'fc-icon-right-single-arrow',
8280 prevYear: 'fc-icon-left-double-arrow',
8281 nextYear: 'fc-icon-right-double-arrow'
8282 };
8283 StandardTheme.prototype.iconOverrideOption = 'buttonIcons';
8284 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
8285 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
8286
8287
8288 /***/ }),
8289 /* 214 */
8290 /***/ (function(module, exports, __webpack_require__) {
8291
8292 Object.defineProperty(exports, "__esModule", { value: true });
8293 var tslib_1 = __webpack_require__(2);
8294 var Theme_1 = __webpack_require__(19);
8295 var JqueryUiTheme = /** @class */ (function (_super) {
8296 tslib_1.__extends(JqueryUiTheme, _super);
8297 function JqueryUiTheme() {
8298 return _super !== null && _super.apply(this, arguments) || this;
8299 }
8300 return JqueryUiTheme;
8301 }(Theme_1.default));
8302 exports.default = JqueryUiTheme;
8303 JqueryUiTheme.prototype.classes = {
8304 widget: 'ui-widget',
8305 widgetHeader: 'ui-widget-header',
8306 widgetContent: 'ui-widget-content',
8307 buttonGroup: 'fc-button-group',
8308 button: 'ui-button',
8309 cornerLeft: 'ui-corner-left',
8310 cornerRight: 'ui-corner-right',
8311 stateDefault: 'ui-state-default',
8312 stateActive: 'ui-state-active',
8313 stateDisabled: 'ui-state-disabled',
8314 stateHover: 'ui-state-hover',
8315 stateDown: 'ui-state-down',
8316 today: 'ui-state-highlight',
8317 popoverHeader: 'ui-widget-header',
8318 popoverContent: 'ui-widget-content',
8319 // day grid
8320 headerRow: 'ui-widget-header',
8321 dayRow: 'ui-widget-content',
8322 // list view
8323 listView: 'ui-widget-content'
8324 };
8325 JqueryUiTheme.prototype.baseIconClass = 'ui-icon';
8326 JqueryUiTheme.prototype.iconClasses = {
8327 close: 'ui-icon-closethick',
8328 prev: 'ui-icon-circle-triangle-w',
8329 next: 'ui-icon-circle-triangle-e',
8330 prevYear: 'ui-icon-seek-prev',
8331 nextYear: 'ui-icon-seek-next'
8332 };
8333 JqueryUiTheme.prototype.iconOverrideOption = 'themeButtonIcons';
8334 JqueryUiTheme.prototype.iconOverrideCustomButtonOption = 'themeIcon';
8335 JqueryUiTheme.prototype.iconOverridePrefix = 'ui-icon-';
8336
8337
8338 /***/ }),
8339 /* 215 */
8340 /***/ (function(module, exports, __webpack_require__) {
8341
8342 Object.defineProperty(exports, "__esModule", { value: true });
8343 var tslib_1 = __webpack_require__(2);
8344 var $ = __webpack_require__(3);
8345 var Promise_1 = __webpack_require__(20);
8346 var EventSource_1 = __webpack_require__(6);
8347 var FuncEventSource = /** @class */ (function (_super) {
8348 tslib_1.__extends(FuncEventSource, _super);
8349 function FuncEventSource() {
8350 return _super !== null && _super.apply(this, arguments) || this;
8351 }
8352 FuncEventSource.parse = function (rawInput, calendar) {
8353 var rawProps;
8354 // normalize raw input
8355 if ($.isFunction(rawInput.events)) {
8356 rawProps = rawInput;
8357 }
8358 else if ($.isFunction(rawInput)) {
8359 rawProps = { events: rawInput };
8360 }
8361 if (rawProps) {
8362 return EventSource_1.default.parse.call(this, rawProps, calendar);
8363 }
8364 return false;
8365 };
8366 FuncEventSource.prototype.fetch = function (start, end, timezone) {
8367 var _this = this;
8368 this.calendar.pushLoading();
8369 return Promise_1.default.construct(function (onResolve) {
8370 _this.func.call(_this.calendar, start.clone(), end.clone(), timezone, function (rawEventDefs) {
8371 _this.calendar.popLoading();
8372 onResolve(_this.parseEventDefs(rawEventDefs));
8373 });
8374 });
8375 };
8376 FuncEventSource.prototype.getPrimitive = function () {
8377 return this.func;
8378 };
8379 FuncEventSource.prototype.applyManualStandardProps = function (rawProps) {
8380 var superSuccess = _super.prototype.applyManualStandardProps.call(this, rawProps);
8381 this.func = rawProps.events;
8382 return superSuccess;
8383 };
8384 return FuncEventSource;
8385 }(EventSource_1.default));
8386 exports.default = FuncEventSource;
8387 FuncEventSource.defineStandardProps({
8388 events: false // don't automatically transfer
8389 });
8390
8391
8392 /***/ }),
8393 /* 216 */
8394 /***/ (function(module, exports, __webpack_require__) {
8395
8396 Object.defineProperty(exports, "__esModule", { value: true });
8397 var tslib_1 = __webpack_require__(2);
8398 var $ = __webpack_require__(3);
8399 var util_1 = __webpack_require__(4);
8400 var Promise_1 = __webpack_require__(20);
8401 var EventSource_1 = __webpack_require__(6);
8402 var JsonFeedEventSource = /** @class */ (function (_super) {
8403 tslib_1.__extends(JsonFeedEventSource, _super);
8404 function JsonFeedEventSource() {
8405 return _super !== null && _super.apply(this, arguments) || this;
8406 }
8407 JsonFeedEventSource.parse = function (rawInput, calendar) {
8408 var rawProps;
8409 // normalize raw input
8410 if (typeof rawInput.url === 'string') {
8411 rawProps = rawInput;
8412 }
8413 else if (typeof rawInput === 'string') {
8414 rawProps = { url: rawInput };
8415 }
8416 if (rawProps) {
8417 return EventSource_1.default.parse.call(this, rawProps, calendar);
8418 }
8419 return false;
8420 };
8421 JsonFeedEventSource.prototype.fetch = function (start, end, timezone) {
8422 var _this = this;
8423 var ajaxSettings = this.ajaxSettings;
8424 var onSuccess = ajaxSettings.success;
8425 var onError = ajaxSettings.error;
8426 var requestParams = this.buildRequestParams(start, end, timezone);
8427 // todo: eventually handle the promise's then,
8428 // don't intercept success/error
8429 // tho will be a breaking API change
8430 this.calendar.pushLoading();
8431 return Promise_1.default.construct(function (onResolve, onReject) {
8432 $.ajax($.extend({}, // destination
8433 JsonFeedEventSource.AJAX_DEFAULTS, ajaxSettings, {
8434 url: _this.url,
8435 data: requestParams,
8436 success: function (rawEventDefs, status, xhr) {
8437 var callbackRes;
8438 _this.calendar.popLoading();
8439 if (rawEventDefs) {
8440 callbackRes = util_1.applyAll(onSuccess, _this, [rawEventDefs, status, xhr]); // redirect `this`
8441 if ($.isArray(callbackRes)) {
8442 rawEventDefs = callbackRes;
8443 }
8444 onResolve(_this.parseEventDefs(rawEventDefs));
8445 }
8446 else {
8447 onReject();
8448 }
8449 },
8450 error: function (xhr, statusText, errorThrown) {
8451 _this.calendar.popLoading();
8452 util_1.applyAll(onError, _this, [xhr, statusText, errorThrown]); // redirect `this`
8453 onReject();
8454 }
8455 }));
8456 });
8457 };
8458 JsonFeedEventSource.prototype.buildRequestParams = function (start, end, timezone) {
8459 var calendar = this.calendar;
8460 var ajaxSettings = this.ajaxSettings;
8461 var startParam;
8462 var endParam;
8463 var timezoneParam;
8464 var customRequestParams;
8465 var params = {};
8466 startParam = this.startParam;
8467 if (startParam == null) {
8468 startParam = calendar.opt('startParam');
8469 }
8470 endParam = this.endParam;
8471 if (endParam == null) {
8472 endParam = calendar.opt('endParam');
8473 }
8474 timezoneParam = this.timezoneParam;
8475 if (timezoneParam == null) {
8476 timezoneParam = calendar.opt('timezoneParam');
8477 }
8478 // retrieve any outbound GET/POST $.ajax data from the options
8479 if ($.isFunction(ajaxSettings.data)) {
8480 // supplied as a function that returns a key/value object
8481 customRequestParams = ajaxSettings.data();
8482 }
8483 else {
8484 // probably supplied as a straight key/value object
8485 customRequestParams = ajaxSettings.data || {};
8486 }
8487 $.extend(params, customRequestParams);
8488 params[startParam] = start.format();
8489 params[endParam] = end.format();
8490 if (timezone && timezone !== 'local') {
8491 params[timezoneParam] = timezone;
8492 }
8493 return params;
8494 };
8495 JsonFeedEventSource.prototype.getPrimitive = function () {
8496 return this.url;
8497 };
8498 JsonFeedEventSource.prototype.applyMiscProps = function (rawProps) {
8499 this.ajaxSettings = rawProps;
8500 };
8501 JsonFeedEventSource.AJAX_DEFAULTS = {
8502 dataType: 'json',
8503 cache: false
8504 };
8505 return JsonFeedEventSource;
8506 }(EventSource_1.default));
8507 exports.default = JsonFeedEventSource;
8508 JsonFeedEventSource.defineStandardProps({
8509 // automatically transfer (true)...
8510 url: true,
8511 startParam: true,
8512 endParam: true,
8513 timezoneParam: true
8514 });
8515
8516
8517 /***/ }),
8518 /* 217 */
8519 /***/ (function(module, exports, __webpack_require__) {
8520
8521 Object.defineProperty(exports, "__esModule", { value: true });
8522 var EmitterMixin_1 = __webpack_require__(11);
8523 var TaskQueue = /** @class */ (function () {
8524 function TaskQueue() {
8525 this.q = [];
8526 this.isPaused = false;
8527 this.isRunning = false;
8528 }
8529 TaskQueue.prototype.queue = function () {
8530 var args = [];
8531 for (var _i = 0; _i < arguments.length; _i++) {
8532 args[_i] = arguments[_i];
8533 }
8534 this.q.push.apply(this.q, args); // append
8535 this.tryStart();
8536 };
8537 TaskQueue.prototype.pause = function () {
8538 this.isPaused = true;
8539 };
8540 TaskQueue.prototype.resume = function () {
8541 this.isPaused = false;
8542 this.tryStart();
8543 };
8544 TaskQueue.prototype.getIsIdle = function () {
8545 return !this.isRunning && !this.isPaused;
8546 };
8547 TaskQueue.prototype.tryStart = function () {
8548 if (!this.isRunning && this.canRunNext()) {
8549 this.isRunning = true;
8550 this.trigger('start');
8551 this.runRemaining();
8552 }
8553 };
8554 TaskQueue.prototype.canRunNext = function () {
8555 return !this.isPaused && this.q.length;
8556 };
8557 TaskQueue.prototype.runRemaining = function () {
8558 var _this = this;
8559 var task;
8560 var res;
8561 do {
8562 task = this.q.shift(); // always freshly reference q. might have been reassigned.
8563 res = this.runTask(task);
8564 if (res && res.then) {
8565 res.then(function () {
8566 if (_this.canRunNext()) {
8567 _this.runRemaining();
8568 }
8569 });
8570 return; // prevent marking as stopped
8571 }
8572 } while (this.canRunNext());
8573 this.trigger('stop'); // not really a 'stop' ... more of a 'drained'
8574 this.isRunning = false;
8575 // if 'stop' handler added more tasks.... TODO: write test for this
8576 this.tryStart();
8577 };
8578 TaskQueue.prototype.runTask = function (task) {
8579 return task(); // task *is* the function, but subclasses can change the format of a task
8580 };
8581 return TaskQueue;
8582 }());
8583 exports.default = TaskQueue;
8584 EmitterMixin_1.default.mixInto(TaskQueue);
8585
8586
8587 /***/ }),
8588 /* 218 */
8589 /***/ (function(module, exports, __webpack_require__) {
8590
8591 Object.defineProperty(exports, "__esModule", { value: true });
8592 var tslib_1 = __webpack_require__(2);
8593 var TaskQueue_1 = __webpack_require__(217);
8594 var RenderQueue = /** @class */ (function (_super) {
8595 tslib_1.__extends(RenderQueue, _super);
8596 function RenderQueue(waitsByNamespace) {
8597 var _this = _super.call(this) || this;
8598 _this.waitsByNamespace = waitsByNamespace || {};
8599 return _this;
8600 }
8601 RenderQueue.prototype.queue = function (taskFunc, namespace, type) {
8602 var task = {
8603 func: taskFunc,
8604 namespace: namespace,
8605 type: type
8606 };
8607 var waitMs;
8608 if (namespace) {
8609 waitMs = this.waitsByNamespace[namespace];
8610 }
8611 if (this.waitNamespace) {
8612 if (namespace === this.waitNamespace && waitMs != null) {
8613 this.delayWait(waitMs);
8614 }
8615 else {
8616 this.clearWait();
8617 this.tryStart();
8618 }
8619 }
8620 if (this.compoundTask(task)) {
8621 if (!this.waitNamespace && waitMs != null) {
8622 this.startWait(namespace, waitMs);
8623 }
8624 else {
8625 this.tryStart();
8626 }
8627 }
8628 };
8629 RenderQueue.prototype.startWait = function (namespace, waitMs) {
8630 this.waitNamespace = namespace;
8631 this.spawnWait(waitMs);
8632 };
8633 RenderQueue.prototype.delayWait = function (waitMs) {
8634 clearTimeout(this.waitId);
8635 this.spawnWait(waitMs);
8636 };
8637 RenderQueue.prototype.spawnWait = function (waitMs) {
8638 var _this = this;
8639 this.waitId = setTimeout(function () {
8640 _this.waitNamespace = null;
8641 _this.tryStart();
8642 }, waitMs);
8643 };
8644 RenderQueue.prototype.clearWait = function () {
8645 if (this.waitNamespace) {
8646 clearTimeout(this.waitId);
8647 this.waitId = null;
8648 this.waitNamespace = null;
8649 }
8650 };
8651 RenderQueue.prototype.canRunNext = function () {
8652 if (!_super.prototype.canRunNext.call(this)) {
8653 return false;
8654 }
8655 // waiting for a certain namespace to stop receiving tasks?
8656 if (this.waitNamespace) {
8657 var q = this.q;
8658 // if there was a different namespace task in the meantime,
8659 // that forces all previously-waiting tasks to suddenly execute.
8660 // TODO: find a way to do this in constant time.
8661 for (var i = 0; i < q.length; i++) {
8662 if (q[i].namespace !== this.waitNamespace) {
8663 return true; // allow execution
8664 }
8665 }
8666 return false;
8667 }
8668 return true;
8669 };
8670 RenderQueue.prototype.runTask = function (task) {
8671 task.func();
8672 };
8673 RenderQueue.prototype.compoundTask = function (newTask) {
8674 var q = this.q;
8675 var shouldAppend = true;
8676 var i;
8677 var task;
8678 if (newTask.namespace && newTask.type === 'destroy') {
8679 // remove all init/add/remove ops with same namespace, regardless of order
8680 for (i = q.length - 1; i >= 0; i--) {
8681 task = q[i];
8682 switch (task.type) {
8683 case 'init':
8684 shouldAppend = false;
8685 // the latest destroy is cancelled out by not doing the init
8686 /* falls through */
8687 case 'add':
8688 /* falls through */
8689 case 'remove':
8690 q.splice(i, 1); // remove task
8691 }
8692 }
8693 }
8694 if (shouldAppend) {
8695 q.push(newTask);
8696 }
8697 return shouldAppend;
8698 };
8699 return RenderQueue;
8700 }(TaskQueue_1.default));
8701 exports.default = RenderQueue;
8702
8703
8704 /***/ }),
8705 /* 219 */
8706 /***/ (function(module, exports, __webpack_require__) {
8707
8708 Object.defineProperty(exports, "__esModule", { value: true });
8709 var tslib_1 = __webpack_require__(2);
8710 var $ = __webpack_require__(3);
8711 var moment = __webpack_require__(0);
8712 var util_1 = __webpack_require__(4);
8713 var moment_ext_1 = __webpack_require__(10);
8714 var date_formatting_1 = __webpack_require__(47);
8715 var Component_1 = __webpack_require__(237);
8716 var util_2 = __webpack_require__(35);
8717 var DateComponent = /** @class */ (function (_super) {
8718 tslib_1.__extends(DateComponent, _super);
8719 function DateComponent(_view, _options) {
8720 var _this = _super.call(this) || this;
8721 _this.isRTL = false; // frequently accessed options
8722 _this.hitsNeededDepth = 0; // necessary because multiple callers might need the same hits
8723 _this.hasAllDayBusinessHours = false; // TODO: unify with largeUnit and isTimeScale?
8724 _this.isDatesRendered = false;
8725 // hack to set options prior to the this.opt calls
8726 if (_view) {
8727 _this['view'] = _view;
8728 }
8729 if (_options) {
8730 _this['options'] = _options;
8731 }
8732 _this.uid = String(DateComponent.guid++);
8733 _this.childrenByUid = {};
8734 _this.nextDayThreshold = moment.duration(_this.opt('nextDayThreshold'));
8735 _this.isRTL = _this.opt('isRTL');
8736 if (_this.fillRendererClass) {
8737 _this.fillRenderer = new _this.fillRendererClass(_this);
8738 }
8739 if (_this.eventRendererClass) {
8740 _this.eventRenderer = new _this.eventRendererClass(_this, _this.fillRenderer);
8741 }
8742 if (_this.helperRendererClass && _this.eventRenderer) {
8743 _this.helperRenderer = new _this.helperRendererClass(_this, _this.eventRenderer);
8744 }
8745 if (_this.businessHourRendererClass && _this.fillRenderer) {
8746 _this.businessHourRenderer = new _this.businessHourRendererClass(_this, _this.fillRenderer);
8747 }
8748 return _this;
8749 }
8750 DateComponent.prototype.addChild = function (child) {
8751 if (!this.childrenByUid[child.uid]) {
8752 this.childrenByUid[child.uid] = child;
8753 return true;
8754 }
8755 return false;
8756 };
8757 DateComponent.prototype.removeChild = function (child) {
8758 if (this.childrenByUid[child.uid]) {
8759 delete this.childrenByUid[child.uid];
8760 return true;
8761 }
8762 return false;
8763 };
8764 // TODO: only do if isInDom?
8765 // TODO: make part of Component, along with children/batch-render system?
8766 DateComponent.prototype.updateSize = function (totalHeight, isAuto, isResize) {
8767 this.callChildren('updateSize', arguments);
8768 };
8769 // Options
8770 // -----------------------------------------------------------------------------------------------------------------
8771 DateComponent.prototype.opt = function (name) {
8772 return this._getView().opt(name); // default implementation
8773 };
8774 DateComponent.prototype.publiclyTrigger = function () {
8775 var args = [];
8776 for (var _i = 0; _i < arguments.length; _i++) {
8777 args[_i] = arguments[_i];
8778 }
8779 var calendar = this._getCalendar();
8780 return calendar.publiclyTrigger.apply(calendar, args);
8781 };
8782 DateComponent.prototype.hasPublicHandlers = function () {
8783 var args = [];
8784 for (var _i = 0; _i < arguments.length; _i++) {
8785 args[_i] = arguments[_i];
8786 }
8787 var calendar = this._getCalendar();
8788 return calendar.hasPublicHandlers.apply(calendar, args);
8789 };
8790 // Date
8791 // -----------------------------------------------------------------------------------------------------------------
8792 DateComponent.prototype.executeDateRender = function (dateProfile) {
8793 this.dateProfile = dateProfile; // for rendering
8794 this.renderDates(dateProfile);
8795 this.isDatesRendered = true;
8796 this.callChildren('executeDateRender', arguments);
8797 };
8798 DateComponent.prototype.executeDateUnrender = function () {
8799 this.callChildren('executeDateUnrender', arguments);
8800 this.dateProfile = null;
8801 this.unrenderDates();
8802 this.isDatesRendered = false;
8803 };
8804 // date-cell content only
8805 DateComponent.prototype.renderDates = function (dateProfile) {
8806 // subclasses should implement
8807 };
8808 // date-cell content only
8809 DateComponent.prototype.unrenderDates = function () {
8810 // subclasses should override
8811 };
8812 // Now-Indicator
8813 // -----------------------------------------------------------------------------------------------------------------
8814 // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator
8815 // should be refreshed. If something falsy is returned, no time indicator is rendered at all.
8816 DateComponent.prototype.getNowIndicatorUnit = function () {
8817 // subclasses should implement
8818 };
8819 // Renders a current time indicator at the given datetime
8820 DateComponent.prototype.renderNowIndicator = function (date) {
8821 this.callChildren('renderNowIndicator', arguments);
8822 };
8823 // Undoes the rendering actions from renderNowIndicator
8824 DateComponent.prototype.unrenderNowIndicator = function () {
8825 this.callChildren('unrenderNowIndicator', arguments);
8826 };
8827 // Business Hours
8828 // ---------------------------------------------------------------------------------------------------------------
8829 DateComponent.prototype.renderBusinessHours = function (businessHourGenerator) {
8830 if (this.businessHourRenderer) {
8831 this.businessHourRenderer.render(businessHourGenerator);
8832 }
8833 this.callChildren('renderBusinessHours', arguments);
8834 };
8835 // Unrenders previously-rendered business-hours
8836 DateComponent.prototype.unrenderBusinessHours = function () {
8837 this.callChildren('unrenderBusinessHours', arguments);
8838 if (this.businessHourRenderer) {
8839 this.businessHourRenderer.unrender();
8840 }
8841 };
8842 // Event Displaying
8843 // -----------------------------------------------------------------------------------------------------------------
8844 DateComponent.prototype.executeEventRender = function (eventsPayload) {
8845 if (this.eventRenderer) {
8846 this.eventRenderer.rangeUpdated(); // poorly named now
8847 this.eventRenderer.render(eventsPayload);
8848 }
8849 else if (this['renderEvents']) {
8850 this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload));
8851 }
8852 this.callChildren('executeEventRender', arguments);
8853 };
8854 DateComponent.prototype.executeEventUnrender = function () {
8855 this.callChildren('executeEventUnrender', arguments);
8856 if (this.eventRenderer) {
8857 this.eventRenderer.unrender();
8858 }
8859 else if (this['destroyEvents']) {
8860 this['destroyEvents']();
8861 }
8862 };
8863 DateComponent.prototype.getBusinessHourSegs = function () {
8864 var segs = this.getOwnBusinessHourSegs();
8865 this.iterChildren(function (child) {
8866 segs.push.apply(segs, child.getBusinessHourSegs());
8867 });
8868 return segs;
8869 };
8870 DateComponent.prototype.getOwnBusinessHourSegs = function () {
8871 if (this.businessHourRenderer) {
8872 return this.businessHourRenderer.getSegs();
8873 }
8874 return [];
8875 };
8876 DateComponent.prototype.getEventSegs = function () {
8877 var segs = this.getOwnEventSegs();
8878 this.iterChildren(function (child) {
8879 segs.push.apply(segs, child.getEventSegs());
8880 });
8881 return segs;
8882 };
8883 DateComponent.prototype.getOwnEventSegs = function () {
8884 if (this.eventRenderer) {
8885 return this.eventRenderer.getSegs();
8886 }
8887 return [];
8888 };
8889 // Event Rendering Triggering
8890 // -----------------------------------------------------------------------------------------------------------------
8891 DateComponent.prototype.triggerAfterEventsRendered = function () {
8892 this.triggerAfterEventSegsRendered(this.getEventSegs());
8893 this.publiclyTrigger('eventAfterAllRender', {
8894 context: this,
8895 args: [this]
8896 });
8897 };
8898 DateComponent.prototype.triggerAfterEventSegsRendered = function (segs) {
8899 var _this = this;
8900 // an optimization, because getEventLegacy is expensive
8901 if (this.hasPublicHandlers('eventAfterRender')) {
8902 segs.forEach(function (seg) {
8903 var legacy;
8904 if (seg.el) {
8905 legacy = seg.footprint.getEventLegacy();
8906 _this.publiclyTrigger('eventAfterRender', {
8907 context: legacy,
8908 args: [legacy, seg.el, _this]
8909 });
8910 }
8911 });
8912 }
8913 };
8914 DateComponent.prototype.triggerBeforeEventsDestroyed = function () {
8915 this.triggerBeforeEventSegsDestroyed(this.getEventSegs());
8916 };
8917 DateComponent.prototype.triggerBeforeEventSegsDestroyed = function (segs) {
8918 var _this = this;
8919 if (this.hasPublicHandlers('eventDestroy')) {
8920 segs.forEach(function (seg) {
8921 var legacy;
8922 if (seg.el) {
8923 legacy = seg.footprint.getEventLegacy();
8924 _this.publiclyTrigger('eventDestroy', {
8925 context: legacy,
8926 args: [legacy, seg.el, _this]
8927 });
8928 }
8929 });
8930 }
8931 };
8932 // Event Rendering Utils
8933 // -----------------------------------------------------------------------------------------------------------------
8934 // Hides all rendered event segments linked to the given event
8935 // RECURSIVE with subcomponents
8936 DateComponent.prototype.showEventsWithId = function (eventDefId) {
8937 this.getEventSegs().forEach(function (seg) {
8938 if (seg.footprint.eventDef.id === eventDefId &&
8939 seg.el // necessary?
8940 ) {
8941 seg.el.css('visibility', '');
8942 }
8943 });
8944 this.callChildren('showEventsWithId', arguments);
8945 };
8946 // Shows all rendered event segments linked to the given event
8947 // RECURSIVE with subcomponents
8948 DateComponent.prototype.hideEventsWithId = function (eventDefId) {
8949 this.getEventSegs().forEach(function (seg) {
8950 if (seg.footprint.eventDef.id === eventDefId &&
8951 seg.el // necessary?
8952 ) {
8953 seg.el.css('visibility', 'hidden');
8954 }
8955 });
8956 this.callChildren('hideEventsWithId', arguments);
8957 };
8958 // Drag-n-Drop Rendering (for both events and external elements)
8959 // ---------------------------------------------------------------------------------------------------------------
8960 // Renders a visual indication of a event or external-element drag over the given drop zone.
8961 // If an external-element, seg will be `null`.
8962 // Must return elements used for any mock events.
8963 DateComponent.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
8964 var renderedHelper = false;
8965 this.iterChildren(function (child) {
8966 if (child.renderDrag(eventFootprints, seg, isTouch)) {
8967 renderedHelper = true;
8968 }
8969 });
8970 return renderedHelper;
8971 };
8972 // Unrenders a visual indication of an event or external-element being dragged.
8973 DateComponent.prototype.unrenderDrag = function () {
8974 this.callChildren('unrenderDrag', arguments);
8975 };
8976 // Event Resizing
8977 // ---------------------------------------------------------------------------------------------------------------
8978 // Renders a visual indication of an event being resized.
8979 DateComponent.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
8980 this.callChildren('renderEventResize', arguments);
8981 };
8982 // Unrenders a visual indication of an event being resized.
8983 DateComponent.prototype.unrenderEventResize = function () {
8984 this.callChildren('unrenderEventResize', arguments);
8985 };
8986 // Selection
8987 // ---------------------------------------------------------------------------------------------------------------
8988 // Renders a visual indication of the selection
8989 // TODO: rename to `renderSelection` after legacy is gone
8990 DateComponent.prototype.renderSelectionFootprint = function (componentFootprint) {
8991 this.renderHighlight(componentFootprint);
8992 this.callChildren('renderSelectionFootprint', arguments);
8993 };
8994 // Unrenders a visual indication of selection
8995 DateComponent.prototype.unrenderSelection = function () {
8996 this.unrenderHighlight();
8997 this.callChildren('unrenderSelection', arguments);
8998 };
8999 // Highlight
9000 // ---------------------------------------------------------------------------------------------------------------
9001 // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data)
9002 DateComponent.prototype.renderHighlight = function (componentFootprint) {
9003 if (this.fillRenderer) {
9004 this.fillRenderer.renderFootprint('highlight', componentFootprint, {
9005 getClasses: function () {
9006 return ['fc-highlight'];
9007 }
9008 });
9009 }
9010 this.callChildren('renderHighlight', arguments);
9011 };
9012 // Unrenders the emphasis on a date range
9013 DateComponent.prototype.unrenderHighlight = function () {
9014 if (this.fillRenderer) {
9015 this.fillRenderer.unrender('highlight');
9016 }
9017 this.callChildren('unrenderHighlight', arguments);
9018 };
9019 // Hit Areas
9020 // ---------------------------------------------------------------------------------------------------------------
9021 // just because all DateComponents support this interface
9022 // doesn't mean they need to have their own internal coord system. they can defer to sub-components.
9023 DateComponent.prototype.hitsNeeded = function () {
9024 if (!(this.hitsNeededDepth++)) {
9025 this.prepareHits();
9026 }
9027 this.callChildren('hitsNeeded', arguments);
9028 };
9029 DateComponent.prototype.hitsNotNeeded = function () {
9030 if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) {
9031 this.releaseHits();
9032 }
9033 this.callChildren('hitsNotNeeded', arguments);
9034 };
9035 DateComponent.prototype.prepareHits = function () {
9036 // subclasses can implement
9037 };
9038 DateComponent.prototype.releaseHits = function () {
9039 // subclasses can implement
9040 };
9041 // Given coordinates from the topleft of the document, return data about the date-related area underneath.
9042 // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged).
9043 // Must have a `grid` property, a reference to this current grid. TODO: avoid this
9044 // The returned object will be processed by getHitFootprint and getHitEl.
9045 DateComponent.prototype.queryHit = function (leftOffset, topOffset) {
9046 var childrenByUid = this.childrenByUid;
9047 var uid;
9048 var hit;
9049 for (uid in childrenByUid) {
9050 hit = childrenByUid[uid].queryHit(leftOffset, topOffset);
9051 if (hit) {
9052 break;
9053 }
9054 }
9055 return hit;
9056 };
9057 DateComponent.prototype.getSafeHitFootprint = function (hit) {
9058 var footprint = this.getHitFootprint(hit);
9059 if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) {
9060 return null;
9061 }
9062 return footprint;
9063 };
9064 DateComponent.prototype.getHitFootprint = function (hit) {
9065 // what about being abstract!?
9066 };
9067 // Given position-level information about a date-related area within the grid,
9068 // should return a jQuery element that best represents it. passed to dayClick callback.
9069 DateComponent.prototype.getHitEl = function (hit) {
9070 // what about being abstract!?
9071 };
9072 /* Converting eventRange -> eventFootprint
9073 ------------------------------------------------------------------------------------------------------------------*/
9074 DateComponent.prototype.eventRangesToEventFootprints = function (eventRanges) {
9075 var eventFootprints = [];
9076 var i;
9077 for (i = 0; i < eventRanges.length; i++) {
9078 eventFootprints.push.apply(// append
9079 eventFootprints, this.eventRangeToEventFootprints(eventRanges[i]));
9080 }
9081 return eventFootprints;
9082 };
9083 DateComponent.prototype.eventRangeToEventFootprints = function (eventRange) {
9084 return [util_2.eventRangeToEventFootprint(eventRange)];
9085 };
9086 /* Converting componentFootprint/eventFootprint -> segs
9087 ------------------------------------------------------------------------------------------------------------------*/
9088 DateComponent.prototype.eventFootprintsToSegs = function (eventFootprints) {
9089 var segs = [];
9090 var i;
9091 for (i = 0; i < eventFootprints.length; i++) {
9092 segs.push.apply(segs, this.eventFootprintToSegs(eventFootprints[i]));
9093 }
9094 return segs;
9095 };
9096 // Given an event's span (unzoned start/end and other misc data), and the event itself,
9097 // slices into segments and attaches event-derived properties to them.
9098 // eventSpan - { start, end, isStart, isEnd, otherthings... }
9099 DateComponent.prototype.eventFootprintToSegs = function (eventFootprint) {
9100 var unzonedRange = eventFootprint.componentFootprint.unzonedRange;
9101 var segs;
9102 var i;
9103 var seg;
9104 segs = this.componentFootprintToSegs(eventFootprint.componentFootprint);
9105 for (i = 0; i < segs.length; i++) {
9106 seg = segs[i];
9107 if (!unzonedRange.isStart) {
9108 seg.isStart = false;
9109 }
9110 if (!unzonedRange.isEnd) {
9111 seg.isEnd = false;
9112 }
9113 seg.footprint = eventFootprint;
9114 // TODO: rename to seg.eventFootprint
9115 }
9116 return segs;
9117 };
9118 DateComponent.prototype.componentFootprintToSegs = function (componentFootprint) {
9119 return [];
9120 };
9121 // Utils
9122 // ---------------------------------------------------------------------------------------------------------------
9123 DateComponent.prototype.callChildren = function (methodName, args) {
9124 this.iterChildren(function (child) {
9125 child[methodName].apply(child, args);
9126 });
9127 };
9128 DateComponent.prototype.iterChildren = function (func) {
9129 var childrenByUid = this.childrenByUid;
9130 var uid;
9131 for (uid in childrenByUid) {
9132 func(childrenByUid[uid]);
9133 }
9134 };
9135 DateComponent.prototype._getCalendar = function () {
9136 var t = this;
9137 return t.calendar || t.view.calendar;
9138 };
9139 DateComponent.prototype._getView = function () {
9140 return this.view;
9141 };
9142 DateComponent.prototype._getDateProfile = function () {
9143 return this._getView().get('dateProfile');
9144 };
9145 // Generates HTML for an anchor to another view into the calendar.
9146 // Will either generate an <a> tag or a non-clickable <span> tag, depending on enabled settings.
9147 // `gotoOptions` can either be a moment input, or an object with the form:
9148 // { date, type, forceOff }
9149 // `type` is a view-type like "day" or "week". default value is "day".
9150 // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
9151 DateComponent.prototype.buildGotoAnchorHtml = function (gotoOptions, attrs, innerHtml) {
9152 var date;
9153 var type;
9154 var forceOff;
9155 var finalOptions;
9156 if ($.isPlainObject(gotoOptions)) {
9157 date = gotoOptions.date;
9158 type = gotoOptions.type;
9159 forceOff = gotoOptions.forceOff;
9160 }
9161 else {
9162 date = gotoOptions; // a single moment input
9163 }
9164 date = moment_ext_1.default(date); // if a string, parse it
9165 finalOptions = {
9166 date: date.format('YYYY-MM-DD'),
9167 type: type || 'day'
9168 };
9169 if (typeof attrs === 'string') {
9170 innerHtml = attrs;
9171 attrs = null;
9172 }
9173 attrs = attrs ? ' ' + util_1.attrsToStr(attrs) : ''; // will have a leading space
9174 innerHtml = innerHtml || '';
9175 if (!forceOff && this.opt('navLinks')) {
9176 return '<a' + attrs +
9177 ' data-goto="' + util_1.htmlEscape(JSON.stringify(finalOptions)) + '">' +
9178 innerHtml +
9179 '</a>';
9180 }
9181 else {
9182 return '<span' + attrs + '>' +
9183 innerHtml +
9184 '</span>';
9185 }
9186 };
9187 DateComponent.prototype.getAllDayHtml = function () {
9188 return this.opt('allDayHtml') || util_1.htmlEscape(this.opt('allDayText'));
9189 };
9190 // Computes HTML classNames for a single-day element
9191 DateComponent.prototype.getDayClasses = function (date, noThemeHighlight) {
9192 var view = this._getView();
9193 var classes = [];
9194 var today;
9195 if (!this.dateProfile.activeUnzonedRange.containsDate(date)) {
9196 classes.push('fc-disabled-day'); // TODO: jQuery UI theme?
9197 }
9198 else {
9199 classes.push('fc-' + util_1.dayIDs[date.day()]);
9200 if (view.isDateInOtherMonth(date, this.dateProfile)) {
9201 classes.push('fc-other-month');
9202 }
9203 today = view.calendar.getNow();
9204 if (date.isSame(today, 'day')) {
9205 classes.push('fc-today');
9206 if (noThemeHighlight !== true) {
9207 classes.push(view.calendar.theme.getClass('today'));
9208 }
9209 }
9210 else if (date < today) {
9211 classes.push('fc-past');
9212 }
9213 else {
9214 classes.push('fc-future');
9215 }
9216 }
9217 return classes;
9218 };
9219 // Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
9220 // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
9221 // The timezones of the dates within `range` will be respected.
9222 DateComponent.prototype.formatRange = function (range, isAllDay, formatStr, separator) {
9223 var end = range.end;
9224 if (isAllDay) {
9225 end = end.clone().subtract(1); // convert to inclusive. last ms of previous day
9226 }
9227 return date_formatting_1.formatRange(range.start, end, formatStr, separator, this.isRTL);
9228 };
9229 // Compute the number of the give units in the "current" range.
9230 // Will return a floating-point number. Won't round.
9231 DateComponent.prototype.currentRangeAs = function (unit) {
9232 return this._getDateProfile().currentUnzonedRange.as(unit);
9233 };
9234 // Returns the date range of the full days the given range visually appears to occupy.
9235 // Returns a plain object with start/end, NOT an UnzonedRange!
9236 DateComponent.prototype.computeDayRange = function (unzonedRange) {
9237 var calendar = this._getCalendar();
9238 var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts
9239 var end = calendar.msToUtcMoment(unzonedRange.endMs);
9240 var endTimeMS = +end.time(); // # of milliseconds into `endDay`
9241 var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends
9242 // If the end time is actually inclusively part of the next day and is equal to or
9243 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
9244 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
9245 if (endTimeMS && endTimeMS >= this.nextDayThreshold) {
9246 endDay.add(1, 'days');
9247 }
9248 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
9249 if (endDay <= startDay) {
9250 endDay = startDay.clone().add(1, 'days');
9251 }
9252 return { start: startDay, end: endDay };
9253 };
9254 // Does the given range visually appear to occupy more than one day?
9255 DateComponent.prototype.isMultiDayRange = function (unzonedRange) {
9256 var dayRange = this.computeDayRange(unzonedRange);
9257 return dayRange.end.diff(dayRange.start, 'days') > 1;
9258 };
9259 DateComponent.guid = 0; // TODO: better system for this?
9260 return DateComponent;
9261 }(Component_1.default));
9262 exports.default = DateComponent;
9263 // legacy
9264 function convertEventsPayloadToLegacyArray(eventsPayload) {
9265 var eventDefId;
9266 var eventInstances;
9267 var legacyEvents = [];
9268 var i;
9269 for (eventDefId in eventsPayload) {
9270 eventInstances = eventsPayload[eventDefId].eventInstances;
9271 for (i = 0; i < eventInstances.length; i++) {
9272 legacyEvents.push(eventInstances[i].toLegacy());
9273 }
9274 }
9275 return legacyEvents;
9276 }
9277
9278
9279 /***/ }),
9280 /* 220 */
9281 /***/ (function(module, exports, __webpack_require__) {
9282
9283 Object.defineProperty(exports, "__esModule", { value: true });
9284 var $ = __webpack_require__(3);
9285 var moment = __webpack_require__(0);
9286 var util_1 = __webpack_require__(4);
9287 var options_1 = __webpack_require__(32);
9288 var Iterator_1 = __webpack_require__(238);
9289 var GlobalEmitter_1 = __webpack_require__(21);
9290 var EmitterMixin_1 = __webpack_require__(11);
9291 var ListenerMixin_1 = __webpack_require__(7);
9292 var Toolbar_1 = __webpack_require__(239);
9293 var OptionsManager_1 = __webpack_require__(240);
9294 var ViewSpecManager_1 = __webpack_require__(241);
9295 var Constraints_1 = __webpack_require__(207);
9296 var locale_1 = __webpack_require__(31);
9297 var moment_ext_1 = __webpack_require__(10);
9298 var UnzonedRange_1 = __webpack_require__(5);
9299 var ComponentFootprint_1 = __webpack_require__(12);
9300 var EventDateProfile_1 = __webpack_require__(17);
9301 var EventManager_1 = __webpack_require__(242);
9302 var BusinessHourGenerator_1 = __webpack_require__(212);
9303 var EventSourceParser_1 = __webpack_require__(38);
9304 var EventDefParser_1 = __webpack_require__(49);
9305 var SingleEventDef_1 = __webpack_require__(13);
9306 var EventDefMutation_1 = __webpack_require__(37);
9307 var EventSource_1 = __webpack_require__(6);
9308 var ThemeRegistry_1 = __webpack_require__(51);
9309 var Calendar = /** @class */ (function () {
9310 function Calendar(el, overrides) {
9311 this.loadingLevel = 0; // number of simultaneous loading tasks
9312 this.ignoreUpdateViewSize = 0;
9313 this.freezeContentHeightDepth = 0;
9314 // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection.
9315 // unneeded() is called in destroy.
9316 GlobalEmitter_1.default.needed();
9317 this.el = el;
9318 this.viewsByType = {};
9319 this.optionsManager = new OptionsManager_1.default(this, overrides);
9320 this.viewSpecManager = new ViewSpecManager_1.default(this.optionsManager, this);
9321 this.initMomentInternals(); // needs to happen after options hash initialized
9322 this.initCurrentDate();
9323 this.initEventManager();
9324 this.constraints = new Constraints_1.default(this.eventManager, this);
9325 this.constructed();
9326 }
9327 Calendar.prototype.constructed = function () {
9328 // useful for monkeypatching. used?
9329 };
9330 Calendar.prototype.getView = function () {
9331 return this.view;
9332 };
9333 Calendar.prototype.publiclyTrigger = function (name, triggerInfo) {
9334 var optHandler = this.opt(name);
9335 var context;
9336 var args;
9337 if ($.isPlainObject(triggerInfo)) {
9338 context = triggerInfo.context;
9339 args = triggerInfo.args;
9340 }
9341 else if ($.isArray(triggerInfo)) {
9342 args = triggerInfo;
9343 }
9344 if (context == null) {
9345 context = this.el[0]; // fallback context
9346 }
9347 if (!args) {
9348 args = [];
9349 }
9350 this.triggerWith(name, context, args); // Emitter's method
9351 if (optHandler) {
9352 return optHandler.apply(context, args);
9353 }
9354 };
9355 Calendar.prototype.hasPublicHandlers = function (name) {
9356 return this.hasHandlers(name) ||
9357 this.opt(name); // handler specified in options
9358 };
9359 // Options Public API
9360 // -----------------------------------------------------------------------------------------------------------------
9361 // public getter/setter
9362 Calendar.prototype.option = function (name, value) {
9363 var newOptionHash;
9364 if (typeof name === 'string') {
9365 if (value === undefined) {
9366 return this.optionsManager.get(name);
9367 }
9368 else {
9369 newOptionHash = {};
9370 newOptionHash[name] = value;
9371 this.optionsManager.add(newOptionHash);
9372 }
9373 }
9374 else if (typeof name === 'object') {
9375 this.optionsManager.add(name);
9376 }
9377 };
9378 // private getter
9379 Calendar.prototype.opt = function (name) {
9380 return this.optionsManager.get(name);
9381 };
9382 // View
9383 // -----------------------------------------------------------------------------------------------------------------
9384 // Given a view name for a custom view or a standard view, creates a ready-to-go View object
9385 Calendar.prototype.instantiateView = function (viewType) {
9386 var spec = this.viewSpecManager.getViewSpec(viewType);
9387 if (!spec) {
9388 throw new Error("View type \"" + viewType + "\" is not valid");
9389 }
9390 return new spec['class'](this, spec);
9391 };
9392 // Returns a boolean about whether the view is okay to instantiate at some point
9393 Calendar.prototype.isValidViewType = function (viewType) {
9394 return Boolean(this.viewSpecManager.getViewSpec(viewType));
9395 };
9396 Calendar.prototype.changeView = function (viewName, dateOrRange) {
9397 if (dateOrRange) {
9398 if (dateOrRange.start && dateOrRange.end) {
9399 this.optionsManager.recordOverrides({
9400 visibleRange: dateOrRange
9401 });
9402 }
9403 else {
9404 this.currentDate = this.moment(dateOrRange).stripZone(); // just like gotoDate
9405 }
9406 }
9407 this.renderView(viewName);
9408 };
9409 // Forces navigation to a view for the given date.
9410 // `viewType` can be a specific view name or a generic one like "week" or "day".
9411 Calendar.prototype.zoomTo = function (newDate, viewType) {
9412 var spec;
9413 viewType = viewType || 'day'; // day is default zoom
9414 spec = this.viewSpecManager.getViewSpec(viewType) ||
9415 this.viewSpecManager.getUnitViewSpec(viewType);
9416 this.currentDate = newDate.clone();
9417 this.renderView(spec ? spec.type : null);
9418 };
9419 // Current Date
9420 // -----------------------------------------------------------------------------------------------------------------
9421 Calendar.prototype.initCurrentDate = function () {
9422 var defaultDateInput = this.opt('defaultDate');
9423 // compute the initial ambig-timezone date
9424 if (defaultDateInput != null) {
9425 this.currentDate = this.moment(defaultDateInput).stripZone();
9426 }
9427 else {
9428 this.currentDate = this.getNow(); // getNow already returns unzoned
9429 }
9430 };
9431 Calendar.prototype.prev = function () {
9432 var view = this.view;
9433 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile'));
9434 if (prevInfo.isValid) {
9435 this.currentDate = prevInfo.date;
9436 this.renderView();
9437 }
9438 };
9439 Calendar.prototype.next = function () {
9440 var view = this.view;
9441 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile'));
9442 if (nextInfo.isValid) {
9443 this.currentDate = nextInfo.date;
9444 this.renderView();
9445 }
9446 };
9447 Calendar.prototype.prevYear = function () {
9448 this.currentDate.add(-1, 'years');
9449 this.renderView();
9450 };
9451 Calendar.prototype.nextYear = function () {
9452 this.currentDate.add(1, 'years');
9453 this.renderView();
9454 };
9455 Calendar.prototype.today = function () {
9456 this.currentDate = this.getNow(); // should deny like prev/next?
9457 this.renderView();
9458 };
9459 Calendar.prototype.gotoDate = function (zonedDateInput) {
9460 this.currentDate = this.moment(zonedDateInput).stripZone();
9461 this.renderView();
9462 };
9463 Calendar.prototype.incrementDate = function (delta) {
9464 this.currentDate.add(moment.duration(delta));
9465 this.renderView();
9466 };
9467 // for external API
9468 Calendar.prototype.getDate = function () {
9469 return this.applyTimezone(this.currentDate); // infuse the calendar's timezone
9470 };
9471 // Loading Triggering
9472 // -----------------------------------------------------------------------------------------------------------------
9473 // Should be called when any type of async data fetching begins
9474 Calendar.prototype.pushLoading = function () {
9475 if (!(this.loadingLevel++)) {
9476 this.publiclyTrigger('loading', [true, this.view]);
9477 }
9478 };
9479 // Should be called when any type of async data fetching completes
9480 Calendar.prototype.popLoading = function () {
9481 if (!(--this.loadingLevel)) {
9482 this.publiclyTrigger('loading', [false, this.view]);
9483 }
9484 };
9485 // High-level Rendering
9486 // -----------------------------------------------------------------------------------
9487 Calendar.prototype.render = function () {
9488 if (!this.contentEl) {
9489 this.initialRender();
9490 }
9491 else if (this.elementVisible()) {
9492 // mainly for the public API
9493 this.calcSize();
9494 this.updateViewSize();
9495 }
9496 };
9497 Calendar.prototype.initialRender = function () {
9498 var _this = this;
9499 var el = this.el;
9500 el.addClass('fc');
9501 // event delegation for nav links
9502 el.on('click.fc', 'a[data-goto]', function (ev) {
9503 var anchorEl = $(ev.currentTarget);
9504 var gotoOptions = anchorEl.data('goto'); // will automatically parse JSON
9505 var date = _this.moment(gotoOptions.date);
9506 var viewType = gotoOptions.type;
9507 // property like "navLinkDayClick". might be a string or a function
9508 var customAction = _this.view.opt('navLink' + util_1.capitaliseFirstLetter(viewType) + 'Click');
9509 if (typeof customAction === 'function') {
9510 customAction(date, ev);
9511 }
9512 else {
9513 if (typeof customAction === 'string') {
9514 viewType = customAction;
9515 }
9516 _this.zoomTo(date, viewType);
9517 }
9518 });
9519 // called immediately, and upon option change
9520 this.optionsManager.watch('settingTheme', ['?theme', '?themeSystem'], function (opts) {
9521 var themeClass = ThemeRegistry_1.getThemeSystemClass(opts.themeSystem || opts.theme);
9522 var theme = new themeClass(_this.optionsManager);
9523 var widgetClass = theme.getClass('widget');
9524 _this.theme = theme;
9525 if (widgetClass) {
9526 el.addClass(widgetClass);
9527 }
9528 }, function () {
9529 var widgetClass = _this.theme.getClass('widget');
9530 _this.theme = null;
9531 if (widgetClass) {
9532 el.removeClass(widgetClass);
9533 }
9534 });
9535 this.optionsManager.watch('settingBusinessHourGenerator', ['?businessHours'], function (deps) {
9536 _this.businessHourGenerator = new BusinessHourGenerator_1.default(deps.businessHours, _this);
9537 if (_this.view) {
9538 _this.view.set('businessHourGenerator', _this.businessHourGenerator);
9539 }
9540 }, function () {
9541 _this.businessHourGenerator = null;
9542 });
9543 // called immediately, and upon option change.
9544 // HACK: locale often affects isRTL, so we explicitly listen to that too.
9545 this.optionsManager.watch('applyingDirClasses', ['?isRTL', '?locale'], function (opts) {
9546 el.toggleClass('fc-ltr', !opts.isRTL);
9547 el.toggleClass('fc-rtl', opts.isRTL);
9548 });
9549 this.contentEl = $("<div class='fc-view-container'/>").prependTo(el);
9550 this.initToolbars();
9551 this.renderHeader();
9552 this.renderFooter();
9553 this.renderView(this.opt('defaultView'));
9554 if (this.opt('handleWindowResize')) {
9555 $(window).resize(this.windowResizeProxy = util_1.debounce(// prevents rapid calls
9556 this.windowResize.bind(this), this.opt('windowResizeDelay')));
9557 }
9558 };
9559 Calendar.prototype.destroy = function () {
9560 if (this.view) {
9561 this.clearView();
9562 }
9563 this.toolbarsManager.proxyCall('removeElement');
9564 this.contentEl.remove();
9565 this.el.removeClass('fc fc-ltr fc-rtl');
9566 // removes theme-related root className
9567 this.optionsManager.unwatch('settingTheme');
9568 this.optionsManager.unwatch('settingBusinessHourGenerator');
9569 this.el.off('.fc'); // unbind nav link handlers
9570 if (this.windowResizeProxy) {
9571 $(window).unbind('resize', this.windowResizeProxy);
9572 this.windowResizeProxy = null;
9573 }
9574 GlobalEmitter_1.default.unneeded();
9575 };
9576 Calendar.prototype.elementVisible = function () {
9577 return this.el.is(':visible');
9578 };
9579 // Render Queue
9580 // -----------------------------------------------------------------------------------------------------------------
9581 Calendar.prototype.bindViewHandlers = function (view) {
9582 var _this = this;
9583 view.watch('titleForCalendar', ['title'], function (deps) {
9584 if (view === _this.view) {
9585 _this.setToolbarsTitle(deps.title);
9586 }
9587 });
9588 view.watch('dateProfileForCalendar', ['dateProfile'], function (deps) {
9589 if (view === _this.view) {
9590 _this.currentDate = deps.dateProfile.date; // might have been constrained by view dates
9591 _this.updateToolbarButtons(deps.dateProfile);
9592 }
9593 });
9594 };
9595 Calendar.prototype.unbindViewHandlers = function (view) {
9596 view.unwatch('titleForCalendar');
9597 view.unwatch('dateProfileForCalendar');
9598 };
9599 // View Rendering
9600 // -----------------------------------------------------------------------------------
9601 // Renders a view because of a date change, view-type change, or for the first time.
9602 // If not given a viewType, keep the current view but render different dates.
9603 // Accepts an optional scroll state to restore to.
9604 Calendar.prototype.renderView = function (viewType) {
9605 var oldView = this.view;
9606 var newView;
9607 this.freezeContentHeight();
9608 if (oldView && viewType && oldView.type !== viewType) {
9609 this.clearView();
9610 }
9611 // if viewType changed, or the view was never created, create a fresh view
9612 if (!this.view && viewType) {
9613 newView = this.view =
9614 this.viewsByType[viewType] ||
9615 (this.viewsByType[viewType] = this.instantiateView(viewType));
9616 this.bindViewHandlers(newView);
9617 newView.startBatchRender(); // so that setElement+setDate rendering are joined
9618 newView.setElement($("<div class='fc-view fc-" + viewType + "-view' />").appendTo(this.contentEl));
9619 this.toolbarsManager.proxyCall('activateButton', viewType);
9620 }
9621 if (this.view) {
9622 // prevent unnecessary change firing
9623 if (this.view.get('businessHourGenerator') !== this.businessHourGenerator) {
9624 this.view.set('businessHourGenerator', this.businessHourGenerator);
9625 }
9626 this.view.setDate(this.currentDate);
9627 if (newView) {
9628 newView.stopBatchRender();
9629 }
9630 }
9631 this.thawContentHeight();
9632 };
9633 // Unrenders the current view and reflects this change in the Header.
9634 // Unregsiters the `view`, but does not remove from viewByType hash.
9635 Calendar.prototype.clearView = function () {
9636 var currentView = this.view;
9637 this.toolbarsManager.proxyCall('deactivateButton', currentView.type);
9638 this.unbindViewHandlers(currentView);
9639 currentView.removeElement();
9640 currentView.unsetDate(); // so bindViewHandlers doesn't fire with old values next time
9641 this.view = null;
9642 };
9643 // Destroys the view, including the view object. Then, re-instantiates it and renders it.
9644 // Maintains the same scroll state.
9645 // TODO: maintain any other user-manipulated state.
9646 Calendar.prototype.reinitView = function () {
9647 var oldView = this.view;
9648 var scroll = oldView.queryScroll(); // wouldn't be so complicated if Calendar owned the scroll
9649 this.freezeContentHeight();
9650 this.clearView();
9651 this.calcSize();
9652 this.renderView(oldView.type); // needs the type to freshly render
9653 this.view.applyScroll(scroll);
9654 this.thawContentHeight();
9655 };
9656 // Resizing
9657 // -----------------------------------------------------------------------------------
9658 Calendar.prototype.getSuggestedViewHeight = function () {
9659 if (this.suggestedViewHeight == null) {
9660 this.calcSize();
9661 }
9662 return this.suggestedViewHeight;
9663 };
9664 Calendar.prototype.isHeightAuto = function () {
9665 return this.opt('contentHeight') === 'auto' || this.opt('height') === 'auto';
9666 };
9667 Calendar.prototype.updateViewSize = function (isResize) {
9668 if (isResize === void 0) { isResize = false; }
9669 var view = this.view;
9670 var scroll;
9671 if (!this.ignoreUpdateViewSize && view) {
9672 if (isResize) {
9673 this.calcSize();
9674 scroll = view.queryScroll();
9675 }
9676 this.ignoreUpdateViewSize++;
9677 view.updateSize(this.getSuggestedViewHeight(), this.isHeightAuto(), isResize);
9678 this.ignoreUpdateViewSize--;
9679 if (isResize) {
9680 view.applyScroll(scroll);
9681 }
9682 return true; // signal success
9683 }
9684 };
9685 Calendar.prototype.calcSize = function () {
9686 if (this.elementVisible()) {
9687 this._calcSize();
9688 }
9689 };
9690 Calendar.prototype._calcSize = function () {
9691 var contentHeightInput = this.opt('contentHeight');
9692 var heightInput = this.opt('height');
9693 if (typeof contentHeightInput === 'number') {
9694 this.suggestedViewHeight = contentHeightInput;
9695 }
9696 else if (typeof contentHeightInput === 'function') {
9697 this.suggestedViewHeight = contentHeightInput();
9698 }
9699 else if (typeof heightInput === 'number') {
9700 this.suggestedViewHeight = heightInput - this.queryToolbarsHeight();
9701 }
9702 else if (typeof heightInput === 'function') {
9703 this.suggestedViewHeight = heightInput() - this.queryToolbarsHeight();
9704 }
9705 else if (heightInput === 'parent') {
9706 this.suggestedViewHeight = this.el.parent().height() - this.queryToolbarsHeight();
9707 }
9708 else {
9709 this.suggestedViewHeight = Math.round(this.contentEl.width() /
9710 Math.max(this.opt('aspectRatio'), .5));
9711 }
9712 };
9713 Calendar.prototype.windowResize = function (ev) {
9714 if (
9715 // the purpose: so we don't process jqui "resize" events that have bubbled up
9716 // cast to any because .target, which is Element, can't be compared to window for some reason.
9717 ev.target === window &&
9718 this.view &&
9719 this.view.isDatesRendered) {
9720 if (this.updateViewSize(true)) {
9721 this.publiclyTrigger('windowResize', [this.view]);
9722 }
9723 }
9724 };
9725 /* Height "Freezing"
9726 -----------------------------------------------------------------------------*/
9727 Calendar.prototype.freezeContentHeight = function () {
9728 if (!(this.freezeContentHeightDepth++)) {
9729 this.forceFreezeContentHeight();
9730 }
9731 };
9732 Calendar.prototype.forceFreezeContentHeight = function () {
9733 this.contentEl.css({
9734 width: '100%',
9735 height: this.contentEl.height(),
9736 overflow: 'hidden'
9737 });
9738 };
9739 Calendar.prototype.thawContentHeight = function () {
9740 this.freezeContentHeightDepth--;
9741 // always bring back to natural height
9742 this.contentEl.css({
9743 width: '',
9744 height: '',
9745 overflow: ''
9746 });
9747 // but if there are future thaws, re-freeze
9748 if (this.freezeContentHeightDepth) {
9749 this.forceFreezeContentHeight();
9750 }
9751 };
9752 // Toolbar
9753 // -----------------------------------------------------------------------------------------------------------------
9754 Calendar.prototype.initToolbars = function () {
9755 this.header = new Toolbar_1.default(this, this.computeHeaderOptions());
9756 this.footer = new Toolbar_1.default(this, this.computeFooterOptions());
9757 this.toolbarsManager = new Iterator_1.default([this.header, this.footer]);
9758 };
9759 Calendar.prototype.computeHeaderOptions = function () {
9760 return {
9761 extraClasses: 'fc-header-toolbar',
9762 layout: this.opt('header')
9763 };
9764 };
9765 Calendar.prototype.computeFooterOptions = function () {
9766 return {
9767 extraClasses: 'fc-footer-toolbar',
9768 layout: this.opt('footer')
9769 };
9770 };
9771 // can be called repeatedly and Header will rerender
9772 Calendar.prototype.renderHeader = function () {
9773 var header = this.header;
9774 header.setToolbarOptions(this.computeHeaderOptions());
9775 header.render();
9776 if (header.el) {
9777 this.el.prepend(header.el);
9778 }
9779 };
9780 // can be called repeatedly and Footer will rerender
9781 Calendar.prototype.renderFooter = function () {
9782 var footer = this.footer;
9783 footer.setToolbarOptions(this.computeFooterOptions());
9784 footer.render();
9785 if (footer.el) {
9786 this.el.append(footer.el);
9787 }
9788 };
9789 Calendar.prototype.setToolbarsTitle = function (title) {
9790 this.toolbarsManager.proxyCall('updateTitle', title);
9791 };
9792 Calendar.prototype.updateToolbarButtons = function (dateProfile) {
9793 var now = this.getNow();
9794 var view = this.view;
9795 var todayInfo = view.dateProfileGenerator.build(now);
9796 var prevInfo = view.dateProfileGenerator.buildPrev(view.get('dateProfile'));
9797 var nextInfo = view.dateProfileGenerator.buildNext(view.get('dateProfile'));
9798 this.toolbarsManager.proxyCall((todayInfo.isValid && !dateProfile.currentUnzonedRange.containsDate(now)) ?
9799 'enableButton' :
9800 'disableButton', 'today');
9801 this.toolbarsManager.proxyCall(prevInfo.isValid ?
9802 'enableButton' :
9803 'disableButton', 'prev');
9804 this.toolbarsManager.proxyCall(nextInfo.isValid ?
9805 'enableButton' :
9806 'disableButton', 'next');
9807 };
9808 Calendar.prototype.queryToolbarsHeight = function () {
9809 return this.toolbarsManager.items.reduce(function (accumulator, toolbar) {
9810 var toolbarHeight = toolbar.el ? toolbar.el.outerHeight(true) : 0; // includes margin
9811 return accumulator + toolbarHeight;
9812 }, 0);
9813 };
9814 // Selection
9815 // -----------------------------------------------------------------------------------------------------------------
9816 // this public method receives start/end dates in any format, with any timezone
9817 Calendar.prototype.select = function (zonedStartInput, zonedEndInput) {
9818 this.view.select(this.buildSelectFootprint.apply(this, arguments));
9819 };
9820 Calendar.prototype.unselect = function () {
9821 if (this.view) {
9822 this.view.unselect();
9823 }
9824 };
9825 // Given arguments to the select method in the API, returns a span (unzoned start/end and other info)
9826 Calendar.prototype.buildSelectFootprint = function (zonedStartInput, zonedEndInput) {
9827 var start = this.moment(zonedStartInput).stripZone();
9828 var end;
9829 if (zonedEndInput) {
9830 end = this.moment(zonedEndInput).stripZone();
9831 }
9832 else if (start.hasTime()) {
9833 end = start.clone().add(this.defaultTimedEventDuration);
9834 }
9835 else {
9836 end = start.clone().add(this.defaultAllDayEventDuration);
9837 }
9838 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), !start.hasTime());
9839 };
9840 // Date Utils
9841 // -----------------------------------------------------------------------------------------------------------------
9842 Calendar.prototype.initMomentInternals = function () {
9843 var _this = this;
9844 this.defaultAllDayEventDuration = moment.duration(this.opt('defaultAllDayEventDuration'));
9845 this.defaultTimedEventDuration = moment.duration(this.opt('defaultTimedEventDuration'));
9846 // Called immediately, and when any of the options change.
9847 // Happens before any internal objects rebuild or rerender, because this is very core.
9848 this.optionsManager.watch('buildingMomentLocale', [
9849 '?locale', '?monthNames', '?monthNamesShort', '?dayNames', '?dayNamesShort',
9850 '?firstDay', '?weekNumberCalculation'
9851 ], function (opts) {
9852 var weekNumberCalculation = opts.weekNumberCalculation;
9853 var firstDay = opts.firstDay;
9854 var _week;
9855 // normalize
9856 if (weekNumberCalculation === 'iso') {
9857 weekNumberCalculation = 'ISO'; // normalize
9858 }
9859 var localeData = Object.create(// make a cheap copy
9860 locale_1.getMomentLocaleData(opts.locale) // will fall back to en
9861 );
9862 if (opts.monthNames) {
9863 localeData._months = opts.monthNames;
9864 }
9865 if (opts.monthNamesShort) {
9866 localeData._monthsShort = opts.monthNamesShort;
9867 }
9868 if (opts.dayNames) {
9869 localeData._weekdays = opts.dayNames;
9870 }
9871 if (opts.dayNamesShort) {
9872 localeData._weekdaysShort = opts.dayNamesShort;
9873 }
9874 if (firstDay == null && weekNumberCalculation === 'ISO') {
9875 firstDay = 1;
9876 }
9877 if (firstDay != null) {
9878 _week = Object.create(localeData._week); // _week: { dow: # }
9879 _week.dow = firstDay;
9880 localeData._week = _week;
9881 }
9882 if (weekNumberCalculation === 'ISO' ||
9883 weekNumberCalculation === 'local' ||
9884 typeof weekNumberCalculation === 'function') {
9885 localeData._fullCalendar_weekCalc = weekNumberCalculation; // moment-ext will know what to do with it
9886 }
9887 _this.localeData = localeData;
9888 // If the internal current date object already exists, move to new locale.
9889 // We do NOT need to do this technique for event dates, because this happens when converting to "segments".
9890 if (_this.currentDate) {
9891 _this.localizeMoment(_this.currentDate); // sets to localeData
9892 }
9893 });
9894 };
9895 // Builds a moment using the settings of the current calendar: timezone and locale.
9896 // Accepts anything the vanilla moment() constructor accepts.
9897 Calendar.prototype.moment = function () {
9898 var args = [];
9899 for (var _i = 0; _i < arguments.length; _i++) {
9900 args[_i] = arguments[_i];
9901 }
9902 var mom;
9903 if (this.opt('timezone') === 'local') {
9904 mom = moment_ext_1.default.apply(null, args);
9905 // Force the moment to be local, because momentExt doesn't guarantee it.
9906 if (mom.hasTime()) {
9907 mom.local();
9908 }
9909 }
9910 else if (this.opt('timezone') === 'UTC') {
9911 mom = moment_ext_1.default.utc.apply(null, args); // process as UTC
9912 }
9913 else {
9914 mom = moment_ext_1.default.parseZone.apply(null, args); // let the input decide the zone
9915 }
9916 this.localizeMoment(mom); // TODO
9917 return mom;
9918 };
9919 Calendar.prototype.msToMoment = function (ms, forceAllDay) {
9920 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC
9921 if (forceAllDay) {
9922 mom.stripTime();
9923 }
9924 else {
9925 mom = this.applyTimezone(mom); // may or may not apply locale
9926 }
9927 this.localizeMoment(mom);
9928 return mom;
9929 };
9930 Calendar.prototype.msToUtcMoment = function (ms, forceAllDay) {
9931 var mom = moment_ext_1.default.utc(ms); // TODO: optimize by using Date.UTC
9932 if (forceAllDay) {
9933 mom.stripTime();
9934 }
9935 this.localizeMoment(mom);
9936 return mom;
9937 };
9938 // Updates the given moment's locale settings to the current calendar locale settings.
9939 Calendar.prototype.localizeMoment = function (mom) {
9940 mom._locale = this.localeData;
9941 };
9942 // Returns a boolean about whether or not the calendar knows how to calculate
9943 // the timezone offset of arbitrary dates in the current timezone.
9944 Calendar.prototype.getIsAmbigTimezone = function () {
9945 return this.opt('timezone') !== 'local' && this.opt('timezone') !== 'UTC';
9946 };
9947 // Returns a copy of the given date in the current timezone. Has no effect on dates without times.
9948 Calendar.prototype.applyTimezone = function (date) {
9949 if (!date.hasTime()) {
9950 return date.clone();
9951 }
9952 var zonedDate = this.moment(date.toArray());
9953 var timeAdjust = date.time().asMilliseconds() - zonedDate.time().asMilliseconds();
9954 var adjustedZonedDate;
9955 // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396)
9956 if (timeAdjust) {
9957 adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds
9958 if (date.time().asMilliseconds() - adjustedZonedDate.time().asMilliseconds() === 0) {
9959 zonedDate = adjustedZonedDate;
9960 }
9961 }
9962 return zonedDate;
9963 };
9964 /*
9965 Assumes the footprint is non-open-ended.
9966 */
9967 Calendar.prototype.footprintToDateProfile = function (componentFootprint, ignoreEnd) {
9968 if (ignoreEnd === void 0) { ignoreEnd = false; }
9969 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs);
9970 var end;
9971 if (!ignoreEnd) {
9972 end = moment_ext_1.default.utc(componentFootprint.unzonedRange.endMs);
9973 }
9974 if (componentFootprint.isAllDay) {
9975 start.stripTime();
9976 if (end) {
9977 end.stripTime();
9978 }
9979 }
9980 else {
9981 start = this.applyTimezone(start);
9982 if (end) {
9983 end = this.applyTimezone(end);
9984 }
9985 }
9986 return new EventDateProfile_1.default(start, end, this);
9987 };
9988 // Returns a moment for the current date, as defined by the client's computer or from the `now` option.
9989 // Will return an moment with an ambiguous timezone.
9990 Calendar.prototype.getNow = function () {
9991 var now = this.opt('now');
9992 if (typeof now === 'function') {
9993 now = now();
9994 }
9995 return this.moment(now).stripZone();
9996 };
9997 // Produces a human-readable string for the given duration.
9998 // Side-effect: changes the locale of the given duration.
9999 Calendar.prototype.humanizeDuration = function (duration) {
10000 return duration.locale(this.opt('locale')).humanize();
10001 };
10002 // will return `null` if invalid range
10003 Calendar.prototype.parseUnzonedRange = function (rangeInput) {
10004 var start = null;
10005 var end = null;
10006 if (rangeInput.start) {
10007 start = this.moment(rangeInput.start).stripZone();
10008 }
10009 if (rangeInput.end) {
10010 end = this.moment(rangeInput.end).stripZone();
10011 }
10012 if (!start && !end) {
10013 return null;
10014 }
10015 if (start && end && end.isBefore(start)) {
10016 return null;
10017 }
10018 return new UnzonedRange_1.default(start, end);
10019 };
10020 // Event-Date Utilities
10021 // -----------------------------------------------------------------------------------------------------------------
10022 Calendar.prototype.initEventManager = function () {
10023 var _this = this;
10024 var eventManager = new EventManager_1.default(this);
10025 var rawSources = this.opt('eventSources') || [];
10026 var singleRawSource = this.opt('events');
10027 this.eventManager = eventManager;
10028 if (singleRawSource) {
10029 rawSources.unshift(singleRawSource);
10030 }
10031 eventManager.on('release', function (eventsPayload) {
10032 _this.trigger('eventsReset', eventsPayload);
10033 });
10034 eventManager.freeze();
10035 rawSources.forEach(function (rawSource) {
10036 var source = EventSourceParser_1.default.parse(rawSource, _this);
10037 if (source) {
10038 eventManager.addSource(source);
10039 }
10040 });
10041 eventManager.thaw();
10042 };
10043 Calendar.prototype.requestEvents = function (start, end) {
10044 return this.eventManager.requestEvents(start, end, this.opt('timezone'), !this.opt('lazyFetching'));
10045 };
10046 // Get an event's normalized end date. If not present, calculate it from the defaults.
10047 Calendar.prototype.getEventEnd = function (event) {
10048 if (event.end) {
10049 return event.end.clone();
10050 }
10051 else {
10052 return this.getDefaultEventEnd(event.allDay, event.start);
10053 }
10054 };
10055 // Given an event's allDay status and start date, return what its fallback end date should be.
10056 // TODO: rename to computeDefaultEventEnd
10057 Calendar.prototype.getDefaultEventEnd = function (allDay, zonedStart) {
10058 var end = zonedStart.clone();
10059 if (allDay) {
10060 end.stripTime().add(this.defaultAllDayEventDuration);
10061 }
10062 else {
10063 end.add(this.defaultTimedEventDuration);
10064 }
10065 if (this.getIsAmbigTimezone()) {
10066 end.stripZone(); // we don't know what the tzo should be
10067 }
10068 return end;
10069 };
10070 // Public Events API
10071 // -----------------------------------------------------------------------------------------------------------------
10072 Calendar.prototype.rerenderEvents = function () {
10073 this.view.flash('displayingEvents');
10074 };
10075 Calendar.prototype.refetchEvents = function () {
10076 this.eventManager.refetchAllSources();
10077 };
10078 Calendar.prototype.renderEvents = function (eventInputs, isSticky) {
10079 this.eventManager.freeze();
10080 for (var i = 0; i < eventInputs.length; i++) {
10081 this.renderEvent(eventInputs[i], isSticky);
10082 }
10083 this.eventManager.thaw();
10084 };
10085 Calendar.prototype.renderEvent = function (eventInput, isSticky) {
10086 if (isSticky === void 0) { isSticky = false; }
10087 var eventManager = this.eventManager;
10088 var eventDef = EventDefParser_1.default.parse(eventInput, eventInput.source || eventManager.stickySource);
10089 if (eventDef) {
10090 eventManager.addEventDef(eventDef, isSticky);
10091 }
10092 };
10093 // legacyQuery operates on legacy event instance objects
10094 Calendar.prototype.removeEvents = function (legacyQuery) {
10095 var eventManager = this.eventManager;
10096 var legacyInstances = [];
10097 var idMap = {};
10098 var eventDef;
10099 var i;
10100 if (legacyQuery == null) {
10101 eventManager.removeAllEventDefs(); // persist=true
10102 }
10103 else {
10104 eventManager.getEventInstances().forEach(function (eventInstance) {
10105 legacyInstances.push(eventInstance.toLegacy());
10106 });
10107 legacyInstances = filterLegacyEventInstances(legacyInstances, legacyQuery);
10108 // compute unique IDs
10109 for (i = 0; i < legacyInstances.length; i++) {
10110 eventDef = this.eventManager.getEventDefByUid(legacyInstances[i]._id);
10111 idMap[eventDef.id] = true;
10112 }
10113 eventManager.freeze();
10114 for (i in idMap) {
10115 eventManager.removeEventDefsById(i); // persist=true
10116 }
10117 eventManager.thaw();
10118 }
10119 };
10120 // legacyQuery operates on legacy event instance objects
10121 Calendar.prototype.clientEvents = function (legacyQuery) {
10122 var legacyEventInstances = [];
10123 this.eventManager.getEventInstances().forEach(function (eventInstance) {
10124 legacyEventInstances.push(eventInstance.toLegacy());
10125 });
10126 return filterLegacyEventInstances(legacyEventInstances, legacyQuery);
10127 };
10128 Calendar.prototype.updateEvents = function (eventPropsArray) {
10129 this.eventManager.freeze();
10130 for (var i = 0; i < eventPropsArray.length; i++) {
10131 this.updateEvent(eventPropsArray[i]);
10132 }
10133 this.eventManager.thaw();
10134 };
10135 Calendar.prototype.updateEvent = function (eventProps) {
10136 var eventDef = this.eventManager.getEventDefByUid(eventProps._id);
10137 var eventInstance;
10138 var eventDefMutation;
10139 if (eventDef instanceof SingleEventDef_1.default) {
10140 eventInstance = eventDef.buildInstance();
10141 eventDefMutation = EventDefMutation_1.default.createFromRawProps(eventInstance, eventProps, // raw props
10142 null // largeUnit -- who uses it?
10143 );
10144 this.eventManager.mutateEventsWithId(eventDef.id, eventDefMutation); // will release
10145 }
10146 };
10147 // Public Event Sources API
10148 // ------------------------------------------------------------------------------------
10149 Calendar.prototype.getEventSources = function () {
10150 return this.eventManager.otherSources.slice(); // clone
10151 };
10152 Calendar.prototype.getEventSourceById = function (id) {
10153 return this.eventManager.getSourceById(EventSource_1.default.normalizeId(id));
10154 };
10155 Calendar.prototype.addEventSource = function (sourceInput) {
10156 var source = EventSourceParser_1.default.parse(sourceInput, this);
10157 if (source) {
10158 this.eventManager.addSource(source);
10159 }
10160 };
10161 Calendar.prototype.removeEventSources = function (sourceMultiQuery) {
10162 var eventManager = this.eventManager;
10163 var sources;
10164 var i;
10165 if (sourceMultiQuery == null) {
10166 this.eventManager.removeAllSources();
10167 }
10168 else {
10169 sources = eventManager.multiQuerySources(sourceMultiQuery);
10170 eventManager.freeze();
10171 for (i = 0; i < sources.length; i++) {
10172 eventManager.removeSource(sources[i]);
10173 }
10174 eventManager.thaw();
10175 }
10176 };
10177 Calendar.prototype.removeEventSource = function (sourceQuery) {
10178 var eventManager = this.eventManager;
10179 var sources = eventManager.querySources(sourceQuery);
10180 var i;
10181 eventManager.freeze();
10182 for (i = 0; i < sources.length; i++) {
10183 eventManager.removeSource(sources[i]);
10184 }
10185 eventManager.thaw();
10186 };
10187 Calendar.prototype.refetchEventSources = function (sourceMultiQuery) {
10188 var eventManager = this.eventManager;
10189 var sources = eventManager.multiQuerySources(sourceMultiQuery);
10190 var i;
10191 eventManager.freeze();
10192 for (i = 0; i < sources.length; i++) {
10193 eventManager.refetchSource(sources[i]);
10194 }
10195 eventManager.thaw();
10196 };
10197 // not for internal use. use options module directly instead.
10198 Calendar.defaults = options_1.globalDefaults;
10199 Calendar.englishDefaults = options_1.englishDefaults;
10200 Calendar.rtlDefaults = options_1.rtlDefaults;
10201 return Calendar;
10202 }());
10203 exports.default = Calendar;
10204 EmitterMixin_1.default.mixInto(Calendar);
10205 ListenerMixin_1.default.mixInto(Calendar);
10206 function filterLegacyEventInstances(legacyEventInstances, legacyQuery) {
10207 if (legacyQuery == null) {
10208 return legacyEventInstances;
10209 }
10210 else if ($.isFunction(legacyQuery)) {
10211 return legacyEventInstances.filter(legacyQuery);
10212 }
10213 else {
10214 legacyQuery += ''; // normalize to string
10215 return legacyEventInstances.filter(function (legacyEventInstance) {
10216 // soft comparison because id not be normalized to string
10217 // tslint:disable-next-line
10218 return legacyEventInstance.id == legacyQuery ||
10219 legacyEventInstance._id === legacyQuery; // can specify internal id, but must exactly match
10220 });
10221 }
10222 }
10223
10224
10225 /***/ }),
10226 /* 221 */
10227 /***/ (function(module, exports, __webpack_require__) {
10228
10229 Object.defineProperty(exports, "__esModule", { value: true });
10230 var moment = __webpack_require__(0);
10231 var util_1 = __webpack_require__(4);
10232 var UnzonedRange_1 = __webpack_require__(5);
10233 var DateProfileGenerator = /** @class */ (function () {
10234 function DateProfileGenerator(_view) {
10235 this._view = _view;
10236 }
10237 DateProfileGenerator.prototype.opt = function (name) {
10238 return this._view.opt(name);
10239 };
10240 DateProfileGenerator.prototype.trimHiddenDays = function (unzonedRange) {
10241 return this._view.trimHiddenDays(unzonedRange);
10242 };
10243 DateProfileGenerator.prototype.msToUtcMoment = function (ms, forceAllDay) {
10244 return this._view.calendar.msToUtcMoment(ms, forceAllDay);
10245 };
10246 /* Date Range Computation
10247 ------------------------------------------------------------------------------------------------------------------*/
10248 // Builds a structure with info about what the dates/ranges will be for the "prev" view.
10249 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile) {
10250 var prevDate = currentDateProfile.date.clone()
10251 .startOf(currentDateProfile.currentRangeUnit)
10252 .subtract(currentDateProfile.dateIncrement);
10253 return this.build(prevDate, -1);
10254 };
10255 // Builds a structure with info about what the dates/ranges will be for the "next" view.
10256 DateProfileGenerator.prototype.buildNext = function (currentDateProfile) {
10257 var nextDate = currentDateProfile.date.clone()
10258 .startOf(currentDateProfile.currentRangeUnit)
10259 .add(currentDateProfile.dateIncrement);
10260 return this.build(nextDate, 1);
10261 };
10262 // Builds a structure holding dates/ranges for rendering around the given date.
10263 // Optional direction param indicates whether the date is being incremented/decremented
10264 // from its previous value. decremented = -1, incremented = 1 (default).
10265 DateProfileGenerator.prototype.build = function (date, direction, forceToValid) {
10266 if (forceToValid === void 0) { forceToValid = false; }
10267 var isDateAllDay = !date.hasTime();
10268 var validUnzonedRange;
10269 var minTime = null;
10270 var maxTime = null;
10271 var currentInfo;
10272 var isRangeAllDay;
10273 var renderUnzonedRange;
10274 var activeUnzonedRange;
10275 var isValid;
10276 validUnzonedRange = this.buildValidRange();
10277 validUnzonedRange = this.trimHiddenDays(validUnzonedRange);
10278 if (forceToValid) {
10279 date = this.msToUtcMoment(validUnzonedRange.constrainDate(date), // returns MS
10280 isDateAllDay);
10281 }
10282 currentInfo = this.buildCurrentRangeInfo(date, direction);
10283 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
10284 renderUnzonedRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.unzonedRange), currentInfo.unit, isRangeAllDay);
10285 renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange);
10286 activeUnzonedRange = renderUnzonedRange.clone();
10287 if (!this.opt('showNonCurrentDates')) {
10288 activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange);
10289 }
10290 minTime = moment.duration(this.opt('minTime'));
10291 maxTime = moment.duration(this.opt('maxTime'));
10292 activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime);
10293 activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null
10294 if (activeUnzonedRange) {
10295 date = this.msToUtcMoment(activeUnzonedRange.constrainDate(date), // returns MS
10296 isDateAllDay);
10297 }
10298 // it's invalid if the originally requested date is not contained,
10299 // or if the range is completely outside of the valid range.
10300 isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange);
10301 return {
10302 // constraint for where prev/next operations can go and where events can be dragged/resized to.
10303 // an object with optional start and end properties.
10304 validUnzonedRange: validUnzonedRange,
10305 // range the view is formally responsible for.
10306 // for example, a month view might have 1st-31st, excluding padded dates
10307 currentUnzonedRange: currentInfo.unzonedRange,
10308 // name of largest unit being displayed, like "month" or "week"
10309 currentRangeUnit: currentInfo.unit,
10310 isRangeAllDay: isRangeAllDay,
10311 // dates that display events and accept drag-n-drop
10312 // will be `null` if no dates accept events
10313 activeUnzonedRange: activeUnzonedRange,
10314 // date range with a rendered skeleton
10315 // includes not-active days that need some sort of DOM
10316 renderUnzonedRange: renderUnzonedRange,
10317 // Duration object that denotes the first visible time of any given day
10318 minTime: minTime,
10319 // Duration object that denotes the exclusive visible end time of any given day
10320 maxTime: maxTime,
10321 isValid: isValid,
10322 date: date,
10323 // how far the current date will move for a prev/next operation
10324 dateIncrement: this.buildDateIncrement(currentInfo.duration)
10325 // pass a fallback (might be null) ^
10326 };
10327 };
10328 // Builds an object with optional start/end properties.
10329 // Indicates the minimum/maximum dates to display.
10330 // not responsible for trimming hidden days.
10331 DateProfileGenerator.prototype.buildValidRange = function () {
10332 return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) ||
10333 new UnzonedRange_1.default(); // completely open-ended
10334 };
10335 // Builds a structure with info about the "current" range, the range that is
10336 // highlighted as being the current month for example.
10337 // See build() for a description of `direction`.
10338 // Guaranteed to have `range` and `unit` properties. `duration` is optional.
10339 // TODO: accept a MS-time instead of a moment `date`?
10340 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) {
10341 var viewSpec = this._view.viewSpec;
10342 var duration = null;
10343 var unit = null;
10344 var unzonedRange = null;
10345 var dayCount;
10346 if (viewSpec.duration) {
10347 duration = viewSpec.duration;
10348 unit = viewSpec.durationUnit;
10349 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
10350 }
10351 else if ((dayCount = this.opt('dayCount'))) {
10352 unit = 'day';
10353 unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount);
10354 }
10355 else if ((unzonedRange = this.buildCustomVisibleRange(date))) {
10356 unit = util_1.computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd());
10357 }
10358 else {
10359 duration = this.getFallbackDuration();
10360 unit = util_1.computeGreatestUnit(duration);
10361 unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
10362 }
10363 return { duration: duration, unit: unit, unzonedRange: unzonedRange };
10364 };
10365 DateProfileGenerator.prototype.getFallbackDuration = function () {
10366 return moment.duration({ days: 1 });
10367 };
10368 // Returns a new activeUnzonedRange to have time values (un-ambiguate)
10369 // minTime or maxTime causes the range to expand.
10370 DateProfileGenerator.prototype.adjustActiveRange = function (unzonedRange, minTime, maxTime) {
10371 var start = unzonedRange.getStart();
10372 var end = unzonedRange.getEnd();
10373 if (this._view.usesMinMaxTime) {
10374 if (minTime < 0) {
10375 start.time(0).add(minTime);
10376 }
10377 if (maxTime > 24 * 60 * 60 * 1000) {
10378 end.time(maxTime - (24 * 60 * 60 * 1000));
10379 }
10380 }
10381 return new UnzonedRange_1.default(start, end);
10382 };
10383 // Builds the "current" range when it is specified as an explicit duration.
10384 // `unit` is the already-computed computeGreatestUnit value of duration.
10385 // TODO: accept a MS-time instead of a moment `date`?
10386 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) {
10387 var alignment = this.opt('dateAlignment');
10388 var dateIncrementInput;
10389 var dateIncrementDuration;
10390 var start;
10391 var end;
10392 var res;
10393 // compute what the alignment should be
10394 if (!alignment) {
10395 dateIncrementInput = this.opt('dateIncrement');
10396 if (dateIncrementInput) {
10397 dateIncrementDuration = moment.duration(dateIncrementInput);
10398 // use the smaller of the two units
10399 if (dateIncrementDuration < duration) {
10400 alignment = util_1.computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput);
10401 }
10402 else {
10403 alignment = unit;
10404 }
10405 }
10406 else {
10407 alignment = unit;
10408 }
10409 }
10410 // if the view displays a single day or smaller
10411 if (duration.as('days') <= 1) {
10412 if (this._view.isHiddenDay(start)) {
10413 start = this._view.skipHiddenDays(start, direction);
10414 start.startOf('day');
10415 }
10416 }
10417 function computeRes() {
10418 start = date.clone().startOf(alignment);
10419 end = start.clone().add(duration);
10420 res = new UnzonedRange_1.default(start, end);
10421 }
10422 computeRes();
10423 // if range is completely enveloped by hidden days, go past the hidden days
10424 if (!this.trimHiddenDays(res)) {
10425 date = this._view.skipHiddenDays(date, direction);
10426 computeRes();
10427 }
10428 return res;
10429 };
10430 // Builds the "current" range when a dayCount is specified.
10431 // TODO: accept a MS-time instead of a moment `date`?
10432 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) {
10433 var customAlignment = this.opt('dateAlignment');
10434 var runningCount = 0;
10435 var start = date.clone();
10436 var end;
10437 if (customAlignment) {
10438 start.startOf(customAlignment);
10439 }
10440 start.startOf('day');
10441 start = this._view.skipHiddenDays(start, direction);
10442 end = start.clone();
10443 do {
10444 end.add(1, 'day');
10445 if (!this._view.isHiddenDay(end)) {
10446 runningCount++;
10447 }
10448 } while (runningCount < dayCount);
10449 return new UnzonedRange_1.default(start, end);
10450 };
10451 // Builds a normalized range object for the "visible" range,
10452 // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time.
10453 // TODO: accept a MS-time instead of a moment `date`?
10454 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) {
10455 var visibleUnzonedRange = this._view.getUnzonedRangeOption('visibleRange', this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations
10456 );
10457 if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) {
10458 return null;
10459 }
10460 return visibleUnzonedRange;
10461 };
10462 // Computes the range that will represent the element/cells for *rendering*,
10463 // but which may have voided days/times.
10464 // not responsible for trimming hidden days.
10465 DateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
10466 return currentUnzonedRange.clone();
10467 };
10468 // Compute the duration value that should be added/substracted to the current date
10469 // when a prev/next operation happens.
10470 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) {
10471 var dateIncrementInput = this.opt('dateIncrement');
10472 var customAlignment;
10473 if (dateIncrementInput) {
10474 return moment.duration(dateIncrementInput);
10475 }
10476 else if ((customAlignment = this.opt('dateAlignment'))) {
10477 return moment.duration(1, customAlignment);
10478 }
10479 else if (fallback) {
10480 return fallback;
10481 }
10482 else {
10483 return moment.duration({ days: 1 });
10484 }
10485 };
10486 return DateProfileGenerator;
10487 }());
10488 exports.default = DateProfileGenerator;
10489
10490
10491 /***/ }),
10492 /* 222 */
10493 /***/ (function(module, exports, __webpack_require__) {
10494
10495 Object.defineProperty(exports, "__esModule", { value: true });
10496 var tslib_1 = __webpack_require__(2);
10497 var $ = __webpack_require__(3);
10498 var moment = __webpack_require__(0);
10499 var exportHooks = __webpack_require__(16);
10500 var util_1 = __webpack_require__(4);
10501 var moment_ext_1 = __webpack_require__(10);
10502 var ListenerMixin_1 = __webpack_require__(7);
10503 var HitDragListener_1 = __webpack_require__(23);
10504 var SingleEventDef_1 = __webpack_require__(13);
10505 var EventInstanceGroup_1 = __webpack_require__(18);
10506 var EventSource_1 = __webpack_require__(6);
10507 var Interaction_1 = __webpack_require__(15);
10508 var ExternalDropping = /** @class */ (function (_super) {
10509 tslib_1.__extends(ExternalDropping, _super);
10510 function ExternalDropping() {
10511 var _this = _super !== null && _super.apply(this, arguments) || this;
10512 _this.isDragging = false; // jqui-dragging an external element? boolean
10513 return _this;
10514 }
10515 /*
10516 component impements:
10517 - eventRangesToEventFootprints
10518 - isEventInstanceGroupAllowed
10519 - isExternalInstanceGroupAllowed
10520 - renderDrag
10521 - unrenderDrag
10522 */
10523 ExternalDropping.prototype.end = function () {
10524 if (this.dragListener) {
10525 this.dragListener.endInteraction();
10526 }
10527 };
10528 ExternalDropping.prototype.bindToDocument = function () {
10529 this.listenTo($(document), {
10530 dragstart: this.handleDragStart,
10531 sortstart: this.handleDragStart // jqui
10532 });
10533 };
10534 ExternalDropping.prototype.unbindFromDocument = function () {
10535 this.stopListeningTo($(document));
10536 };
10537 // Called when a jQuery UI drag is initiated anywhere in the DOM
10538 ExternalDropping.prototype.handleDragStart = function (ev, ui) {
10539 var el;
10540 var accept;
10541 if (this.opt('droppable')) {
10542 el = $((ui ? ui.item : null) || ev.target);
10543 // Test that the dragged element passes the dropAccept selector or filter function.
10544 // FYI, the default is "*" (matches all)
10545 accept = this.opt('dropAccept');
10546 if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {
10547 if (!this.isDragging) {
10548 this.listenToExternalDrag(el, ev, ui);
10549 }
10550 }
10551 }
10552 };
10553 // Called when a jQuery UI drag starts and it needs to be monitored for dropping
10554 ExternalDropping.prototype.listenToExternalDrag = function (el, ev, ui) {
10555 var _this = this;
10556 var component = this.component;
10557 var view = this.view;
10558 var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create
10559 var singleEventDef; // a null value signals an unsuccessful drag
10560 // listener that tracks mouse movement over date-associated pixel regions
10561 var dragListener = this.dragListener = new HitDragListener_1.default(component, {
10562 interactionStart: function () {
10563 _this.isDragging = true;
10564 },
10565 hitOver: function (hit) {
10566 var isAllowed = true;
10567 var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid
10568 var mutatedEventInstanceGroup;
10569 if (hitFootprint) {
10570 singleEventDef = _this.computeExternalDrop(hitFootprint, meta);
10571 if (singleEventDef) {
10572 mutatedEventInstanceGroup = new EventInstanceGroup_1.default(singleEventDef.buildInstances());
10573 isAllowed = meta.eventProps ? // isEvent?
10574 component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) :
10575 component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup);
10576 }
10577 else {
10578 isAllowed = false;
10579 }
10580 }
10581 else {
10582 isAllowed = false;
10583 }
10584 if (!isAllowed) {
10585 singleEventDef = null;
10586 util_1.disableCursor();
10587 }
10588 if (singleEventDef) {
10589 component.renderDrag(// called without a seg parameter
10590 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar)));
10591 }
10592 },
10593 hitOut: function () {
10594 singleEventDef = null; // signal unsuccessful
10595 },
10596 hitDone: function () {
10597 util_1.enableCursor();
10598 component.unrenderDrag();
10599 },
10600 interactionEnd: function (ev) {
10601 if (singleEventDef) {
10602 view.reportExternalDrop(singleEventDef, Boolean(meta.eventProps), // isEvent
10603 Boolean(meta.stick), // isSticky
10604 el, ev, ui);
10605 }
10606 _this.isDragging = false;
10607 _this.dragListener = null;
10608 }
10609 });
10610 dragListener.startDrag(ev); // start listening immediately
10611 };
10612 // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),
10613 // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null.
10614 // Returning a null value signals an invalid drop hit.
10615 // DOES NOT consider overlap/constraint.
10616 // Assumes both footprints are non-open-ended.
10617 ExternalDropping.prototype.computeExternalDrop = function (componentFootprint, meta) {
10618 var calendar = this.view.calendar;
10619 var start = moment_ext_1.default.utc(componentFootprint.unzonedRange.startMs).stripZone();
10620 var end;
10621 var eventDef;
10622 if (componentFootprint.isAllDay) {
10623 // if dropped on an all-day span, and element's metadata specified a time, set it
10624 if (meta.startTime) {
10625 start.time(meta.startTime);
10626 }
10627 else {
10628 start.stripTime();
10629 }
10630 }
10631 if (meta.duration) {
10632 end = start.clone().add(meta.duration);
10633 }
10634 start = calendar.applyTimezone(start);
10635 if (end) {
10636 end = calendar.applyTimezone(end);
10637 }
10638 eventDef = SingleEventDef_1.default.parse($.extend({}, meta.eventProps, {
10639 start: start,
10640 end: end
10641 }), new EventSource_1.default(calendar));
10642 return eventDef;
10643 };
10644 return ExternalDropping;
10645 }(Interaction_1.default));
10646 exports.default = ExternalDropping;
10647 ListenerMixin_1.default.mixInto(ExternalDropping);
10648 /* External-Dragging-Element Data
10649 ----------------------------------------------------------------------------------------------------------------------*/
10650 // Require all HTML5 data-* attributes used by FullCalendar to have this prefix.
10651 // A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.
10652 exportHooks.dataAttrPrefix = '';
10653 // Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure
10654 // to be used for Event Object creation.
10655 // A defined `.eventProps`, even when empty, indicates that an event should be created.
10656 function getDraggedElMeta(el) {
10657 var prefix = exportHooks.dataAttrPrefix;
10658 var eventProps; // properties for creating the event, not related to date/time
10659 var startTime; // a Duration
10660 var duration;
10661 var stick;
10662 if (prefix) {
10663 prefix += '-';
10664 }
10665 eventProps = el.data(prefix + 'event') || null;
10666 if (eventProps) {
10667 if (typeof eventProps === 'object') {
10668 eventProps = $.extend({}, eventProps); // make a copy
10669 }
10670 else {
10671 eventProps = {};
10672 }
10673 // pluck special-cased date/time properties
10674 startTime = eventProps.start;
10675 if (startTime == null) {
10676 startTime = eventProps.time;
10677 } // accept 'time' as well
10678 duration = eventProps.duration;
10679 stick = eventProps.stick;
10680 delete eventProps.start;
10681 delete eventProps.time;
10682 delete eventProps.duration;
10683 delete eventProps.stick;
10684 }
10685 // fallback to standalone attribute values for each of the date/time properties
10686 if (startTime == null) {
10687 startTime = el.data(prefix + 'start');
10688 }
10689 if (startTime == null) {
10690 startTime = el.data(prefix + 'time');
10691 } // accept 'time' as well
10692 if (duration == null) {
10693 duration = el.data(prefix + 'duration');
10694 }
10695 if (stick == null) {
10696 stick = el.data(prefix + 'stick');
10697 }
10698 // massage into correct data types
10699 startTime = startTime != null ? moment.duration(startTime) : null;
10700 duration = duration != null ? moment.duration(duration) : null;
10701 stick = Boolean(stick);
10702 return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };
10703 }
10704
10705
10706 /***/ }),
10707 /* 223 */
10708 /***/ (function(module, exports, __webpack_require__) {
10709
10710 Object.defineProperty(exports, "__esModule", { value: true });
10711 var tslib_1 = __webpack_require__(2);
10712 var $ = __webpack_require__(3);
10713 var util_1 = __webpack_require__(4);
10714 var EventDefMutation_1 = __webpack_require__(37);
10715 var EventDefDateMutation_1 = __webpack_require__(50);
10716 var HitDragListener_1 = __webpack_require__(23);
10717 var Interaction_1 = __webpack_require__(15);
10718 var EventResizing = /** @class */ (function (_super) {
10719 tslib_1.__extends(EventResizing, _super);
10720 /*
10721 component impements:
10722 - bindSegHandlerToEl
10723 - publiclyTrigger
10724 - diffDates
10725 - eventRangesToEventFootprints
10726 - isEventInstanceGroupAllowed
10727 - getSafeHitFootprint
10728 */
10729 function EventResizing(component, eventPointing) {
10730 var _this = _super.call(this, component) || this;
10731 _this.isResizing = false;
10732 _this.eventPointing = eventPointing;
10733 return _this;
10734 }
10735 EventResizing.prototype.end = function () {
10736 if (this.dragListener) {
10737 this.dragListener.endInteraction();
10738 }
10739 };
10740 EventResizing.prototype.bindToEl = function (el) {
10741 var component = this.component;
10742 component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this));
10743 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
10744 };
10745 EventResizing.prototype.handleMouseDown = function (seg, ev) {
10746 if (this.component.canStartResize(seg, ev)) {
10747 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
10748 .startInteraction(ev, { distance: 5 });
10749 }
10750 };
10751 EventResizing.prototype.handleTouchStart = function (seg, ev) {
10752 if (this.component.canStartResize(seg, ev)) {
10753 this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
10754 .startInteraction(ev);
10755 }
10756 };
10757 // Creates a listener that tracks the user as they resize an event segment.
10758 // Generic enough to work with any type of Grid.
10759 EventResizing.prototype.buildDragListener = function (seg, isStart) {
10760 var _this = this;
10761 var component = this.component;
10762 var view = this.view;
10763 var calendar = view.calendar;
10764 var eventManager = calendar.eventManager;
10765 var el = seg.el;
10766 var eventDef = seg.footprint.eventDef;
10767 var eventInstance = seg.footprint.eventInstance;
10768 var isDragging;
10769 var resizeMutation; // zoned event date properties. falsy if invalid resize
10770 // Tracks mouse movement over the *grid's* coordinate map
10771 var dragListener = this.dragListener = new HitDragListener_1.default(component, {
10772 scroll: this.opt('dragScroll'),
10773 subjectEl: el,
10774 interactionStart: function () {
10775 isDragging = false;
10776 },
10777 dragStart: function (ev) {
10778 isDragging = true;
10779 // ensure a mouseout on the manipulated event has been reported
10780 _this.eventPointing.handleMouseout(seg, ev);
10781 _this.segResizeStart(seg, ev);
10782 },
10783 hitOver: function (hit, isOrig, origHit) {
10784 var isAllowed = true;
10785 var origHitFootprint = component.getSafeHitFootprint(origHit);
10786 var hitFootprint = component.getSafeHitFootprint(hit);
10787 var mutatedEventInstanceGroup;
10788 if (origHitFootprint && hitFootprint) {
10789 resizeMutation = isStart ?
10790 _this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) :
10791 _this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint);
10792 if (resizeMutation) {
10793 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, resizeMutation);
10794 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
10795 }
10796 else {
10797 isAllowed = false;
10798 }
10799 }
10800 else {
10801 isAllowed = false;
10802 }
10803 if (!isAllowed) {
10804 resizeMutation = null;
10805 util_1.disableCursor();
10806 }
10807 else if (resizeMutation.isEmpty()) {
10808 // no change. (FYI, event dates might have zones)
10809 resizeMutation = null;
10810 }
10811 if (resizeMutation) {
10812 view.hideEventsWithId(seg.footprint.eventDef.id);
10813 view.renderEventResize(component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg);
10814 }
10815 },
10816 hitOut: function () {
10817 resizeMutation = null;
10818 },
10819 hitDone: function () {
10820 view.unrenderEventResize(seg);
10821 view.showEventsWithId(seg.footprint.eventDef.id);
10822 util_1.enableCursor();
10823 },
10824 interactionEnd: function (ev) {
10825 if (isDragging) {
10826 _this.segResizeStop(seg, ev);
10827 }
10828 if (resizeMutation) {
10829 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
10830 view.reportEventResize(eventInstance, resizeMutation, el, ev);
10831 }
10832 _this.dragListener = null;
10833 }
10834 });
10835 return dragListener;
10836 };
10837 // Called before event segment resizing starts
10838 EventResizing.prototype.segResizeStart = function (seg, ev) {
10839 this.isResizing = true;
10840 this.component.publiclyTrigger('eventResizeStart', {
10841 context: seg.el[0],
10842 args: [
10843 seg.footprint.getEventLegacy(),
10844 ev,
10845 {},
10846 this.view
10847 ]
10848 });
10849 };
10850 // Called after event segment resizing stops
10851 EventResizing.prototype.segResizeStop = function (seg, ev) {
10852 this.isResizing = false;
10853 this.component.publiclyTrigger('eventResizeStop', {
10854 context: seg.el[0],
10855 args: [
10856 seg.footprint.getEventLegacy(),
10857 ev,
10858 {},
10859 this.view
10860 ]
10861 });
10862 };
10863 // Returns new date-information for an event segment being resized from its start
10864 EventResizing.prototype.computeEventStartResizeMutation = function (startFootprint, endFootprint, origEventFootprint) {
10865 var origRange = origEventFootprint.componentFootprint.unzonedRange;
10866 var startDelta = this.component.diffDates(endFootprint.unzonedRange.getStart(), startFootprint.unzonedRange.getStart());
10867 var dateMutation;
10868 var eventDefMutation;
10869 if (origRange.getStart().add(startDelta) < origRange.getEnd()) {
10870 dateMutation = new EventDefDateMutation_1.default();
10871 dateMutation.setStartDelta(startDelta);
10872 eventDefMutation = new EventDefMutation_1.default();
10873 eventDefMutation.setDateMutation(dateMutation);
10874 return eventDefMutation;
10875 }
10876 return false;
10877 };
10878 // Returns new date-information for an event segment being resized from its end
10879 EventResizing.prototype.computeEventEndResizeMutation = function (startFootprint, endFootprint, origEventFootprint) {
10880 var origRange = origEventFootprint.componentFootprint.unzonedRange;
10881 var endDelta = this.component.diffDates(endFootprint.unzonedRange.getEnd(), startFootprint.unzonedRange.getEnd());
10882 var dateMutation;
10883 var eventDefMutation;
10884 if (origRange.getEnd().add(endDelta) > origRange.getStart()) {
10885 dateMutation = new EventDefDateMutation_1.default();
10886 dateMutation.setEndDelta(endDelta);
10887 eventDefMutation = new EventDefMutation_1.default();
10888 eventDefMutation.setDateMutation(dateMutation);
10889 return eventDefMutation;
10890 }
10891 return false;
10892 };
10893 return EventResizing;
10894 }(Interaction_1.default));
10895 exports.default = EventResizing;
10896
10897
10898 /***/ }),
10899 /* 224 */
10900 /***/ (function(module, exports, __webpack_require__) {
10901
10902 Object.defineProperty(exports, "__esModule", { value: true });
10903 var tslib_1 = __webpack_require__(2);
10904 var util_1 = __webpack_require__(4);
10905 var EventDefMutation_1 = __webpack_require__(37);
10906 var EventDefDateMutation_1 = __webpack_require__(50);
10907 var DragListener_1 = __webpack_require__(54);
10908 var HitDragListener_1 = __webpack_require__(23);
10909 var MouseFollower_1 = __webpack_require__(244);
10910 var Interaction_1 = __webpack_require__(15);
10911 var EventDragging = /** @class */ (function (_super) {
10912 tslib_1.__extends(EventDragging, _super);
10913 /*
10914 component implements:
10915 - bindSegHandlerToEl
10916 - publiclyTrigger
10917 - diffDates
10918 - eventRangesToEventFootprints
10919 - isEventInstanceGroupAllowed
10920 */
10921 function EventDragging(component, eventPointing) {
10922 var _this = _super.call(this, component) || this;
10923 _this.isDragging = false;
10924 _this.eventPointing = eventPointing;
10925 return _this;
10926 }
10927 EventDragging.prototype.end = function () {
10928 if (this.dragListener) {
10929 this.dragListener.endInteraction();
10930 }
10931 };
10932 EventDragging.prototype.getSelectionDelay = function () {
10933 var delay = this.opt('eventLongPressDelay');
10934 if (delay == null) {
10935 delay = this.opt('longPressDelay'); // fallback
10936 }
10937 return delay;
10938 };
10939 EventDragging.prototype.bindToEl = function (el) {
10940 var component = this.component;
10941 component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this));
10942 component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
10943 };
10944 EventDragging.prototype.handleMousedown = function (seg, ev) {
10945 if (!this.component.shouldIgnoreMouse() &&
10946 this.component.canStartDrag(seg, ev)) {
10947 this.buildDragListener(seg).startInteraction(ev, { distance: 5 });
10948 }
10949 };
10950 EventDragging.prototype.handleTouchStart = function (seg, ev) {
10951 var component = this.component;
10952 var settings = {
10953 delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected?
10954 0 : this.getSelectionDelay()
10955 };
10956 if (component.canStartDrag(seg, ev)) {
10957 this.buildDragListener(seg).startInteraction(ev, settings);
10958 }
10959 else if (component.canStartSelection(seg, ev)) {
10960 this.buildSelectListener(seg).startInteraction(ev, settings);
10961 }
10962 };
10963 // seg isn't draggable, but let's use a generic DragListener
10964 // simply for the delay, so it can be selected.
10965 // Has side effect of setting/unsetting `dragListener`
10966 EventDragging.prototype.buildSelectListener = function (seg) {
10967 var _this = this;
10968 var view = this.view;
10969 var eventDef = seg.footprint.eventDef;
10970 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
10971 if (this.dragListener) {
10972 return this.dragListener;
10973 }
10974 var dragListener = this.dragListener = new DragListener_1.default({
10975 dragStart: function (ev) {
10976 if (dragListener.isTouch &&
10977 !view.isEventDefSelected(eventDef) &&
10978 eventInstance) {
10979 // if not previously selected, will fire after a delay. then, select the event
10980 view.selectEventInstance(eventInstance);
10981 }
10982 },
10983 interactionEnd: function (ev) {
10984 _this.dragListener = null;
10985 }
10986 });
10987 return dragListener;
10988 };
10989 // Builds a listener that will track user-dragging on an event segment.
10990 // Generic enough to work with any type of Grid.
10991 // Has side effect of setting/unsetting `dragListener`
10992 EventDragging.prototype.buildDragListener = function (seg) {
10993 var _this = this;
10994 var component = this.component;
10995 var view = this.view;
10996 var calendar = view.calendar;
10997 var eventManager = calendar.eventManager;
10998 var el = seg.el;
10999 var eventDef = seg.footprint.eventDef;
11000 var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
11001 var isDragging;
11002 var mouseFollower; // A clone of the original element that will move with the mouse
11003 var eventDefMutation;
11004 if (this.dragListener) {
11005 return this.dragListener;
11006 }
11007 // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
11008 // of the view.
11009 var dragListener = this.dragListener = new HitDragListener_1.default(view, {
11010 scroll: this.opt('dragScroll'),
11011 subjectEl: el,
11012 subjectCenter: true,
11013 interactionStart: function (ev) {
11014 seg.component = component; // for renderDrag
11015 isDragging = false;
11016 mouseFollower = new MouseFollower_1.default(seg.el, {
11017 additionalClass: 'fc-dragging',
11018 parentEl: view.el,
11019 opacity: dragListener.isTouch ? null : _this.opt('dragOpacity'),
11020 revertDuration: _this.opt('dragRevertDuration'),
11021 zIndex: 2 // one above the .fc-view
11022 });
11023 mouseFollower.hide(); // don't show until we know this is a real drag
11024 mouseFollower.start(ev);
11025 },
11026 dragStart: function (ev) {
11027 if (dragListener.isTouch &&
11028 !view.isEventDefSelected(eventDef) &&
11029 eventInstance) {
11030 // if not previously selected, will fire after a delay. then, select the event
11031 view.selectEventInstance(eventInstance);
11032 }
11033 isDragging = true;
11034 // ensure a mouseout on the manipulated event has been reported
11035 _this.eventPointing.handleMouseout(seg, ev);
11036 _this.segDragStart(seg, ev);
11037 view.hideEventsWithId(seg.footprint.eventDef.id);
11038 },
11039 hitOver: function (hit, isOrig, origHit) {
11040 var isAllowed = true;
11041 var origFootprint;
11042 var footprint;
11043 var mutatedEventInstanceGroup;
11044 // starting hit could be forced (DayGrid.limit)
11045 if (seg.hit) {
11046 origHit = seg.hit;
11047 }
11048 // hit might not belong to this grid, so query origin grid
11049 origFootprint = origHit.component.getSafeHitFootprint(origHit);
11050 footprint = hit.component.getSafeHitFootprint(hit);
11051 if (origFootprint && footprint) {
11052 eventDefMutation = _this.computeEventDropMutation(origFootprint, footprint, eventDef);
11053 if (eventDefMutation) {
11054 mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(eventDef.id, eventDefMutation);
11055 isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
11056 }
11057 else {
11058 isAllowed = false;
11059 }
11060 }
11061 else {
11062 isAllowed = false;
11063 }
11064 if (!isAllowed) {
11065 eventDefMutation = null;
11066 util_1.disableCursor();
11067 }
11068 // if a valid drop location, have the subclass render a visual indication
11069 if (eventDefMutation &&
11070 view.renderDrag(// truthy if rendered something
11071 component.eventRangesToEventFootprints(mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)), seg, dragListener.isTouch)) {
11072 mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own
11073 }
11074 else {
11075 mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)
11076 }
11077 if (isOrig) {
11078 // needs to have moved hits to be a valid drop
11079 eventDefMutation = null;
11080 }
11081 },
11082 hitOut: function () {
11083 view.unrenderDrag(seg); // unrender whatever was done in renderDrag
11084 mouseFollower.show(); // show in case we are moving out of all hits
11085 eventDefMutation = null;
11086 },
11087 hitDone: function () {
11088 util_1.enableCursor();
11089 },
11090 interactionEnd: function (ev) {
11091 delete seg.component; // prevent side effects
11092 // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
11093 mouseFollower.stop(!eventDefMutation, function () {
11094 if (isDragging) {
11095 view.unrenderDrag(seg);
11096 _this.segDragStop(seg, ev);
11097 }
11098 view.showEventsWithId(seg.footprint.eventDef.id);
11099 if (eventDefMutation) {
11100 // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
11101 view.reportEventDrop(eventInstance, eventDefMutation, el, ev);
11102 }
11103 });
11104 _this.dragListener = null;
11105 }
11106 });
11107 return dragListener;
11108 };
11109 // Called before event segment dragging starts
11110 EventDragging.prototype.segDragStart = function (seg, ev) {
11111 this.isDragging = true;
11112 this.component.publiclyTrigger('eventDragStart', {
11113 context: seg.el[0],
11114 args: [
11115 seg.footprint.getEventLegacy(),
11116 ev,
11117 {},
11118 this.view
11119 ]
11120 });
11121 };
11122 // Called after event segment dragging stops
11123 EventDragging.prototype.segDragStop = function (seg, ev) {
11124 this.isDragging = false;
11125 this.component.publiclyTrigger('eventDragStop', {
11126 context: seg.el[0],
11127 args: [
11128 seg.footprint.getEventLegacy(),
11129 ev,
11130 {},
11131 this.view
11132 ]
11133 });
11134 };
11135 // DOES NOT consider overlap/constraint
11136 EventDragging.prototype.computeEventDropMutation = function (startFootprint, endFootprint, eventDef) {
11137 var eventDefMutation = new EventDefMutation_1.default();
11138 eventDefMutation.setDateMutation(this.computeEventDateMutation(startFootprint, endFootprint));
11139 return eventDefMutation;
11140 };
11141 EventDragging.prototype.computeEventDateMutation = function (startFootprint, endFootprint) {
11142 var date0 = startFootprint.unzonedRange.getStart();
11143 var date1 = endFootprint.unzonedRange.getStart();
11144 var clearEnd = false;
11145 var forceTimed = false;
11146 var forceAllDay = false;
11147 var dateDelta;
11148 var dateMutation;
11149 if (startFootprint.isAllDay !== endFootprint.isAllDay) {
11150 clearEnd = true;
11151 if (endFootprint.isAllDay) {
11152 forceAllDay = true;
11153 date0.stripTime();
11154 }
11155 else {
11156 forceTimed = true;
11157 }
11158 }
11159 dateDelta = this.component.diffDates(date1, date0);
11160 dateMutation = new EventDefDateMutation_1.default();
11161 dateMutation.clearEnd = clearEnd;
11162 dateMutation.forceTimed = forceTimed;
11163 dateMutation.forceAllDay = forceAllDay;
11164 dateMutation.setDateDelta(dateDelta);
11165 return dateMutation;
11166 };
11167 return EventDragging;
11168 }(Interaction_1.default));
11169 exports.default = EventDragging;
11170
11171
11172 /***/ }),
11173 /* 225 */
11174 /***/ (function(module, exports, __webpack_require__) {
11175
11176 Object.defineProperty(exports, "__esModule", { value: true });
11177 var tslib_1 = __webpack_require__(2);
11178 var util_1 = __webpack_require__(4);
11179 var HitDragListener_1 = __webpack_require__(23);
11180 var ComponentFootprint_1 = __webpack_require__(12);
11181 var UnzonedRange_1 = __webpack_require__(5);
11182 var Interaction_1 = __webpack_require__(15);
11183 var DateSelecting = /** @class */ (function (_super) {
11184 tslib_1.__extends(DateSelecting, _super);
11185 /*
11186 component must implement:
11187 - bindDateHandlerToEl
11188 - getSafeHitFootprint
11189 - renderHighlight
11190 - unrenderHighlight
11191 */
11192 function DateSelecting(component) {
11193 var _this = _super.call(this, component) || this;
11194 _this.dragListener = _this.buildDragListener();
11195 return _this;
11196 }
11197 DateSelecting.prototype.end = function () {
11198 this.dragListener.endInteraction();
11199 };
11200 DateSelecting.prototype.getDelay = function () {
11201 var delay = this.opt('selectLongPressDelay');
11202 if (delay == null) {
11203 delay = this.opt('longPressDelay'); // fallback
11204 }
11205 return delay;
11206 };
11207 DateSelecting.prototype.bindToEl = function (el) {
11208 var _this = this;
11209 var component = this.component;
11210 var dragListener = this.dragListener;
11211 component.bindDateHandlerToEl(el, 'mousedown', function (ev) {
11212 if (_this.opt('selectable') && !component.shouldIgnoreMouse()) {
11213 dragListener.startInteraction(ev, {
11214 distance: _this.opt('selectMinDistance')
11215 });
11216 }
11217 });
11218 component.bindDateHandlerToEl(el, 'touchstart', function (ev) {
11219 if (_this.opt('selectable') && !component.shouldIgnoreTouch()) {
11220 dragListener.startInteraction(ev, {
11221 delay: _this.getDelay()
11222 });
11223 }
11224 });
11225 util_1.preventSelection(el);
11226 };
11227 // Creates a listener that tracks the user's drag across day elements, for day selecting.
11228 DateSelecting.prototype.buildDragListener = function () {
11229 var _this = this;
11230 var component = this.component;
11231 var selectionFootprint; // null if invalid selection
11232 var dragListener = new HitDragListener_1.default(component, {
11233 scroll: this.opt('dragScroll'),
11234 interactionStart: function () {
11235 selectionFootprint = null;
11236 },
11237 dragStart: function (ev) {
11238 _this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one
11239 },
11240 hitOver: function (hit, isOrig, origHit) {
11241 var origHitFootprint;
11242 var hitFootprint;
11243 if (origHit) {
11244 origHitFootprint = component.getSafeHitFootprint(origHit);
11245 hitFootprint = component.getSafeHitFootprint(hit);
11246 if (origHitFootprint && hitFootprint) {
11247 selectionFootprint = _this.computeSelection(origHitFootprint, hitFootprint);
11248 }
11249 else {
11250 selectionFootprint = null;
11251 }
11252 if (selectionFootprint) {
11253 component.renderSelectionFootprint(selectionFootprint);
11254 }
11255 else if (selectionFootprint === false) {
11256 util_1.disableCursor();
11257 }
11258 }
11259 },
11260 hitOut: function () {
11261 selectionFootprint = null;
11262 component.unrenderSelection();
11263 },
11264 hitDone: function () {
11265 util_1.enableCursor();
11266 },
11267 interactionEnd: function (ev, isCancelled) {
11268 if (!isCancelled && selectionFootprint) {
11269 // the selection will already have been rendered. just report it
11270 _this.view.reportSelection(selectionFootprint, ev);
11271 }
11272 }
11273 });
11274 return dragListener;
11275 };
11276 // Given the first and last date-spans of a selection, returns another date-span object.
11277 // Subclasses can override and provide additional data in the span object. Will be passed to renderSelectionFootprint().
11278 // Will return false if the selection is invalid and this should be indicated to the user.
11279 // Will return null/undefined if a selection invalid but no error should be reported.
11280 DateSelecting.prototype.computeSelection = function (footprint0, footprint1) {
11281 var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1);
11282 if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) {
11283 return false;
11284 }
11285 return wholeFootprint;
11286 };
11287 // Given two spans, must return the combination of the two.
11288 // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.
11289 // Assumes both footprints are non-open-ended.
11290 DateSelecting.prototype.computeSelectionFootprint = function (footprint0, footprint1) {
11291 var ms = [
11292 footprint0.unzonedRange.startMs,
11293 footprint0.unzonedRange.endMs,
11294 footprint1.unzonedRange.startMs,
11295 footprint1.unzonedRange.endMs
11296 ];
11297 ms.sort(util_1.compareNumbers);
11298 return new ComponentFootprint_1.default(new UnzonedRange_1.default(ms[0], ms[3]), footprint0.isAllDay);
11299 };
11300 DateSelecting.prototype.isSelectionFootprintAllowed = function (componentFootprint) {
11301 return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) &&
11302 this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint);
11303 };
11304 return DateSelecting;
11305 }(Interaction_1.default));
11306 exports.default = DateSelecting;
11307
11308
11309 /***/ }),
11310 /* 226 */
11311 /***/ (function(module, exports, __webpack_require__) {
11312
11313 Object.defineProperty(exports, "__esModule", { value: true });
11314 var tslib_1 = __webpack_require__(2);
11315 var moment = __webpack_require__(0);
11316 var $ = __webpack_require__(3);
11317 var util_1 = __webpack_require__(4);
11318 var Scroller_1 = __webpack_require__(39);
11319 var View_1 = __webpack_require__(41);
11320 var TimeGrid_1 = __webpack_require__(227);
11321 var DayGrid_1 = __webpack_require__(61);
11322 var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
11323 var agendaTimeGridMethods;
11324 var agendaDayGridMethods;
11325 /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
11326 ----------------------------------------------------------------------------------------------------------------------*/
11327 // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
11328 // Responsible for managing width/height.
11329 var AgendaView = /** @class */ (function (_super) {
11330 tslib_1.__extends(AgendaView, _super);
11331 function AgendaView(calendar, viewSpec) {
11332 var _this = _super.call(this, calendar, viewSpec) || this;
11333 _this.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
11334 _this.timeGrid = _this.instantiateTimeGrid();
11335 _this.addChild(_this.timeGrid);
11336 if (_this.opt('allDaySlot')) {
11337 _this.dayGrid = _this.instantiateDayGrid(); // the all-day subcomponent of this view
11338 _this.addChild(_this.dayGrid);
11339 }
11340 _this.scroller = new Scroller_1.default({
11341 overflowX: 'hidden',
11342 overflowY: 'auto'
11343 });
11344 return _this;
11345 }
11346 // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
11347 AgendaView.prototype.instantiateTimeGrid = function () {
11348 var timeGrid = new this.timeGridClass(this);
11349 util_1.copyOwnProps(agendaTimeGridMethods, timeGrid);
11350 return timeGrid;
11351 };
11352 // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
11353 AgendaView.prototype.instantiateDayGrid = function () {
11354 var dayGrid = new this.dayGridClass(this);
11355 util_1.copyOwnProps(agendaDayGridMethods, dayGrid);
11356 return dayGrid;
11357 };
11358 /* Rendering
11359 ------------------------------------------------------------------------------------------------------------------*/
11360 AgendaView.prototype.renderSkeleton = function () {
11361 var timeGridWrapEl;
11362 var timeGridEl;
11363 this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml());
11364 this.scroller.render();
11365 timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container');
11366 timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl);
11367 this.el.find('.fc-body > tr > td').append(timeGridWrapEl);
11368 this.timeGrid.headContainerEl = this.el.find('.fc-head-container');
11369 this.timeGrid.setElement(timeGridEl);
11370 if (this.dayGrid) {
11371 this.dayGrid.setElement(this.el.find('.fc-day-grid'));
11372 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
11373 this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();
11374 }
11375 };
11376 AgendaView.prototype.unrenderSkeleton = function () {
11377 this.timeGrid.removeElement();
11378 if (this.dayGrid) {
11379 this.dayGrid.removeElement();
11380 }
11381 this.scroller.destroy();
11382 };
11383 // Builds the HTML skeleton for the view.
11384 // The day-grid and time-grid components will render inside containers defined by this HTML.
11385 AgendaView.prototype.renderSkeletonHtml = function () {
11386 var theme = this.calendar.theme;
11387 return '' +
11388 '<table class="' + theme.getClass('tableGrid') + '">' +
11389 (this.opt('columnHeader') ?
11390 '<thead class="fc-head">' +
11391 '<tr>' +
11392 '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
11393 '</tr>' +
11394 '</thead>' :
11395 '') +
11396 '<tbody class="fc-body">' +
11397 '<tr>' +
11398 '<td class="' + theme.getClass('widgetContent') + '">' +
11399 (this.dayGrid ?
11400 '<div class="fc-day-grid"/>' +
11401 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '"/>' :
11402 '') +
11403 '</td>' +
11404 '</tr>' +
11405 '</tbody>' +
11406 '</table>';
11407 };
11408 // Generates an HTML attribute string for setting the width of the axis, if it is known
11409 AgendaView.prototype.axisStyleAttr = function () {
11410 if (this.axisWidth != null) {
11411 return 'style="width:' + this.axisWidth + 'px"';
11412 }
11413 return '';
11414 };
11415 /* Now Indicator
11416 ------------------------------------------------------------------------------------------------------------------*/
11417 AgendaView.prototype.getNowIndicatorUnit = function () {
11418 return this.timeGrid.getNowIndicatorUnit();
11419 };
11420 /* Dimensions
11421 ------------------------------------------------------------------------------------------------------------------*/
11422 // Adjusts the vertical dimensions of the view to the specified values
11423 AgendaView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
11424 var eventLimit;
11425 var scrollerHeight;
11426 var scrollbarWidths;
11427 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
11428 // make all axis cells line up, and record the width so newly created axis cells will have it
11429 this.axisWidth = util_1.matchCellWidths(this.el.find('.fc-axis'));
11430 // hack to give the view some height prior to timeGrid's columns being rendered
11431 // TODO: separate setting height from scroller VS timeGrid.
11432 if (!this.timeGrid.colEls) {
11433 if (!isAuto) {
11434 scrollerHeight = this.computeScrollerHeight(totalHeight);
11435 this.scroller.setHeight(scrollerHeight);
11436 }
11437 return;
11438 }
11439 // set of fake row elements that must compensate when scroller has scrollbars
11440 var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)');
11441 // reset all dimensions back to the original state
11442 this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary
11443 this.scroller.clear(); // sets height to 'auto' and clears overflow
11444 util_1.uncompensateScroll(noScrollRowEls);
11445 // limit number of events in the all-day area
11446 if (this.dayGrid) {
11447 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
11448 eventLimit = this.opt('eventLimit');
11449 if (eventLimit && typeof eventLimit !== 'number') {
11450 eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
11451 }
11452 if (eventLimit) {
11453 this.dayGrid.limitRows(eventLimit);
11454 }
11455 }
11456 if (!isAuto) {
11457 scrollerHeight = this.computeScrollerHeight(totalHeight);
11458 this.scroller.setHeight(scrollerHeight);
11459 scrollbarWidths = this.scroller.getScrollbarWidths();
11460 if (scrollbarWidths.left || scrollbarWidths.right) {
11461 // make the all-day and header rows lines up
11462 util_1.compensateScroll(noScrollRowEls, scrollbarWidths);
11463 // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
11464 // and reapply the desired height to the scroller.
11465 scrollerHeight = this.computeScrollerHeight(totalHeight);
11466 this.scroller.setHeight(scrollerHeight);
11467 }
11468 // guarantees the same scrollbar widths
11469 this.scroller.lockOverflow(scrollbarWidths);
11470 // if there's any space below the slats, show the horizontal rule.
11471 // this won't cause any new overflow, because lockOverflow already called.
11472 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
11473 this.timeGrid.bottomRuleEl.show();
11474 }
11475 }
11476 };
11477 // given a desired total height of the view, returns what the height of the scroller should be
11478 AgendaView.prototype.computeScrollerHeight = function (totalHeight) {
11479 return totalHeight -
11480 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
11481 };
11482 /* Scroll
11483 ------------------------------------------------------------------------------------------------------------------*/
11484 // Computes the initial pre-configured scroll state prior to allowing the user to change it
11485 AgendaView.prototype.computeInitialDateScroll = function () {
11486 var scrollTime = moment.duration(this.opt('scrollTime'));
11487 var top = this.timeGrid.computeTimeTop(scrollTime);
11488 // zoom can give weird floating-point values. rather scroll a little bit further
11489 top = Math.ceil(top);
11490 if (top) {
11491 top++; // to overcome top border that slots beyond the first have. looks better
11492 }
11493 return { top: top };
11494 };
11495 AgendaView.prototype.queryDateScroll = function () {
11496 return { top: this.scroller.getScrollTop() };
11497 };
11498 AgendaView.prototype.applyDateScroll = function (scroll) {
11499 if (scroll.top !== undefined) {
11500 this.scroller.setScrollTop(scroll.top);
11501 }
11502 };
11503 /* Hit Areas
11504 ------------------------------------------------------------------------------------------------------------------*/
11505 // forward all hit-related method calls to the grids (dayGrid might not be defined)
11506 AgendaView.prototype.getHitFootprint = function (hit) {
11507 // TODO: hit.component is set as a hack to identify where the hit came from
11508 return hit.component.getHitFootprint(hit);
11509 };
11510 AgendaView.prototype.getHitEl = function (hit) {
11511 // TODO: hit.component is set as a hack to identify where the hit came from
11512 return hit.component.getHitEl(hit);
11513 };
11514 /* Event Rendering
11515 ------------------------------------------------------------------------------------------------------------------*/
11516 AgendaView.prototype.executeEventRender = function (eventsPayload) {
11517 var dayEventsPayload = {};
11518 var timedEventsPayload = {};
11519 var id;
11520 var eventInstanceGroup;
11521 // separate the events into all-day and timed
11522 for (id in eventsPayload) {
11523 eventInstanceGroup = eventsPayload[id];
11524 if (eventInstanceGroup.getEventDef().isAllDay()) {
11525 dayEventsPayload[id] = eventInstanceGroup;
11526 }
11527 else {
11528 timedEventsPayload[id] = eventInstanceGroup;
11529 }
11530 }
11531 this.timeGrid.executeEventRender(timedEventsPayload);
11532 if (this.dayGrid) {
11533 this.dayGrid.executeEventRender(dayEventsPayload);
11534 }
11535 };
11536 /* Dragging/Resizing Routing
11537 ------------------------------------------------------------------------------------------------------------------*/
11538 // A returned value of `true` signals that a mock "helper" event has been rendered.
11539 AgendaView.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
11540 var groups = groupEventFootprintsByAllDay(eventFootprints);
11541 var renderedHelper = false;
11542 renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch);
11543 if (this.dayGrid) {
11544 renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper;
11545 }
11546 return renderedHelper;
11547 };
11548 AgendaView.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
11549 var groups = groupEventFootprintsByAllDay(eventFootprints);
11550 this.timeGrid.renderEventResize(groups.timed, seg, isTouch);
11551 if (this.dayGrid) {
11552 this.dayGrid.renderEventResize(groups.allDay, seg, isTouch);
11553 }
11554 };
11555 /* Selection
11556 ------------------------------------------------------------------------------------------------------------------*/
11557 // Renders a visual indication of a selection
11558 AgendaView.prototype.renderSelectionFootprint = function (componentFootprint) {
11559 if (!componentFootprint.isAllDay) {
11560 this.timeGrid.renderSelectionFootprint(componentFootprint);
11561 }
11562 else if (this.dayGrid) {
11563 this.dayGrid.renderSelectionFootprint(componentFootprint);
11564 }
11565 };
11566 return AgendaView;
11567 }(View_1.default));
11568 exports.default = AgendaView;
11569 AgendaView.prototype.timeGridClass = TimeGrid_1.default;
11570 AgendaView.prototype.dayGridClass = DayGrid_1.default;
11571 // Will customize the rendering behavior of the AgendaView's timeGrid
11572 agendaTimeGridMethods = {
11573 // Generates the HTML that will go before the day-of week header cells
11574 renderHeadIntroHtml: function () {
11575 var view = this.view;
11576 var calendar = view.calendar;
11577 var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true);
11578 var weekText;
11579 if (this.opt('weekNumbers')) {
11580 weekText = weekStart.format(this.opt('smallWeekFormat'));
11581 return '' +
11582 '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' +
11583 view.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
11584 { date: weekStart, type: 'week', forceOff: this.colCnt > 1 }, util_1.htmlEscape(weekText) // inner HTML
11585 ) +
11586 '</th>';
11587 }
11588 else {
11589 return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>';
11590 }
11591 },
11592 // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
11593 renderBgIntroHtml: function () {
11594 var view = this.view;
11595 return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>';
11596 },
11597 // Generates the HTML that goes before all other types of cells.
11598 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
11599 renderIntroHtml: function () {
11600 var view = this.view;
11601 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
11602 }
11603 };
11604 // Will customize the rendering behavior of the AgendaView's dayGrid
11605 agendaDayGridMethods = {
11606 // Generates the HTML that goes before the all-day cells
11607 renderBgIntroHtml: function () {
11608 var view = this.view;
11609 return '' +
11610 '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
11611 '<span>' + // needed for matchCellWidths
11612 view.getAllDayHtml() +
11613 '</span>' +
11614 '</td>';
11615 },
11616 // Generates the HTML that goes before all other types of cells.
11617 // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
11618 renderIntroHtml: function () {
11619 var view = this.view;
11620 return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
11621 }
11622 };
11623 function groupEventFootprintsByAllDay(eventFootprints) {
11624 var allDay = [];
11625 var timed = [];
11626 var i;
11627 for (i = 0; i < eventFootprints.length; i++) {
11628 if (eventFootprints[i].componentFootprint.isAllDay) {
11629 allDay.push(eventFootprints[i]);
11630 }
11631 else {
11632 timed.push(eventFootprints[i]);
11633 }
11634 }
11635 return { allDay: allDay, timed: timed };
11636 }
11637
11638
11639 /***/ }),
11640 /* 227 */
11641 /***/ (function(module, exports, __webpack_require__) {
11642
11643 Object.defineProperty(exports, "__esModule", { value: true });
11644 var tslib_1 = __webpack_require__(2);
11645 var $ = __webpack_require__(3);
11646 var moment = __webpack_require__(0);
11647 var util_1 = __webpack_require__(4);
11648 var InteractiveDateComponent_1 = __webpack_require__(40);
11649 var BusinessHourRenderer_1 = __webpack_require__(56);
11650 var StandardInteractionsMixin_1 = __webpack_require__(60);
11651 var DayTableMixin_1 = __webpack_require__(55);
11652 var CoordCache_1 = __webpack_require__(53);
11653 var UnzonedRange_1 = __webpack_require__(5);
11654 var ComponentFootprint_1 = __webpack_require__(12);
11655 var TimeGridEventRenderer_1 = __webpack_require__(246);
11656 var TimeGridHelperRenderer_1 = __webpack_require__(247);
11657 var TimeGridFillRenderer_1 = __webpack_require__(248);
11658 /* A component that renders one or more columns of vertical time slots
11659 ----------------------------------------------------------------------------------------------------------------------*/
11660 // We mixin DayTable, even though there is only a single row of days
11661 // potential nice values for the slot-duration and interval-duration
11662 // from largest to smallest
11663 var AGENDA_STOCK_SUB_DURATIONS = [
11664 { hours: 1 },
11665 { minutes: 30 },
11666 { minutes: 15 },
11667 { seconds: 30 },
11668 { seconds: 15 }
11669 ];
11670 var TimeGrid = /** @class */ (function (_super) {
11671 tslib_1.__extends(TimeGrid, _super);
11672 function TimeGrid(view) {
11673 var _this = _super.call(this, view) || this;
11674 _this.processOptions();
11675 return _this;
11676 }
11677 // Slices up the given span (unzoned start/end with other misc data) into an array of segments
11678 TimeGrid.prototype.componentFootprintToSegs = function (componentFootprint) {
11679 var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange);
11680 var i;
11681 for (i = 0; i < segs.length; i++) {
11682 if (this.isRTL) {
11683 segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex;
11684 }
11685 else {
11686 segs[i].col = segs[i].dayIndex;
11687 }
11688 }
11689 return segs;
11690 };
11691 /* Date Handling
11692 ------------------------------------------------------------------------------------------------------------------*/
11693 TimeGrid.prototype.sliceRangeByTimes = function (unzonedRange) {
11694 var segs = [];
11695 var segRange;
11696 var dayIndex;
11697 for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) {
11698 segRange = unzonedRange.intersect(this.dayRanges[dayIndex]);
11699 if (segRange) {
11700 segs.push({
11701 startMs: segRange.startMs,
11702 endMs: segRange.endMs,
11703 isStart: segRange.isStart,
11704 isEnd: segRange.isEnd,
11705 dayIndex: dayIndex
11706 });
11707 }
11708 }
11709 return segs;
11710 };
11711 /* Options
11712 ------------------------------------------------------------------------------------------------------------------*/
11713 // Parses various options into properties of this object
11714 TimeGrid.prototype.processOptions = function () {
11715 var slotDuration = this.opt('slotDuration');
11716 var snapDuration = this.opt('snapDuration');
11717 var input;
11718 slotDuration = moment.duration(slotDuration);
11719 snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
11720 this.slotDuration = slotDuration;
11721 this.snapDuration = snapDuration;
11722 this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple?
11723 // might be an array value (for TimelineView).
11724 // if so, getting the most granular entry (the last one probably).
11725 input = this.opt('slotLabelFormat');
11726 if ($.isArray(input)) {
11727 input = input[input.length - 1];
11728 }
11729 this.labelFormat = input ||
11730 this.opt('smallTimeFormat'); // the computed default
11731 input = this.opt('slotLabelInterval');
11732 this.labelInterval = input ?
11733 moment.duration(input) :
11734 this.computeLabelInterval(slotDuration);
11735 };
11736 // Computes an automatic value for slotLabelInterval
11737 TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
11738 var i;
11739 var labelInterval;
11740 var slotsPerLabel;
11741 // find the smallest stock label interval that results in more than one slots-per-label
11742 for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
11743 labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
11744 slotsPerLabel = util_1.divideDurationByDuration(labelInterval, slotDuration);
11745 if (util_1.isInt(slotsPerLabel) && slotsPerLabel > 1) {
11746 return labelInterval;
11747 }
11748 }
11749 return moment.duration(slotDuration); // fall back. clone
11750 };
11751 /* Date Rendering
11752 ------------------------------------------------------------------------------------------------------------------*/
11753 TimeGrid.prototype.renderDates = function (dateProfile) {
11754 this.dateProfile = dateProfile;
11755 this.updateDayTable();
11756 this.renderSlats();
11757 this.renderColumns();
11758 };
11759 TimeGrid.prototype.unrenderDates = function () {
11760 // this.unrenderSlats(); // don't need this because repeated .html() calls clear
11761 this.unrenderColumns();
11762 };
11763 TimeGrid.prototype.renderSkeleton = function () {
11764 var theme = this.view.calendar.theme;
11765 this.el.html('<div class="fc-bg"></div>' +
11766 '<div class="fc-slats"></div>' +
11767 '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none" />');
11768 this.bottomRuleEl = this.el.find('hr');
11769 };
11770 TimeGrid.prototype.renderSlats = function () {
11771 var theme = this.view.calendar.theme;
11772 this.slatContainerEl = this.el.find('> .fc-slats')
11773 .html(// avoids needing ::unrenderSlats()
11774 '<table class="' + theme.getClass('tableGrid') + '">' +
11775 this.renderSlatRowHtml() +
11776 '</table>');
11777 this.slatEls = this.slatContainerEl.find('tr');
11778 this.slatCoordCache = new CoordCache_1.default({
11779 els: this.slatEls,
11780 isVertical: true
11781 });
11782 };
11783 // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
11784 TimeGrid.prototype.renderSlatRowHtml = function () {
11785 var view = this.view;
11786 var calendar = view.calendar;
11787 var theme = calendar.theme;
11788 var isRTL = this.isRTL;
11789 var dateProfile = this.dateProfile;
11790 var html = '';
11791 var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations
11792 var slotIterator = moment.duration(0);
11793 var slotDate; // will be on the view's first day, but we only care about its time
11794 var isLabeled;
11795 var axisHtml;
11796 // Calculate the time for each slot
11797 while (slotTime < dateProfile.maxTime) {
11798 slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime);
11799 isLabeled = util_1.isInt(util_1.divideDurationByDuration(slotIterator, this.labelInterval));
11800 axisHtml =
11801 '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
11802 (isLabeled ?
11803 '<span>' + // for matchCellWidths
11804 util_1.htmlEscape(slotDate.format(this.labelFormat)) +
11805 '</span>' :
11806 '') +
11807 '</td>';
11808 html +=
11809 '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' +
11810 (isLabeled ? '' : ' class="fc-minor"') +
11811 '>' +
11812 (!isRTL ? axisHtml : '') +
11813 '<td class="' + theme.getClass('widgetContent') + '"/>' +
11814 (isRTL ? axisHtml : '') +
11815 '</tr>';
11816 slotTime.add(this.slotDuration);
11817 slotIterator.add(this.slotDuration);
11818 }
11819 return html;
11820 };
11821 TimeGrid.prototype.renderColumns = function () {
11822 var dateProfile = this.dateProfile;
11823 var theme = this.view.calendar.theme;
11824 this.dayRanges = this.dayDates.map(function (dayDate) {
11825 return new UnzonedRange_1.default(dayDate.clone().add(dateProfile.minTime), dayDate.clone().add(dateProfile.maxTime));
11826 });
11827 if (this.headContainerEl) {
11828 this.headContainerEl.html(this.renderHeadHtml());
11829 }
11830 this.el.find('> .fc-bg').html('<table class="' + theme.getClass('tableGrid') + '">' +
11831 this.renderBgTrHtml(0) + // row=0
11832 '</table>');
11833 this.colEls = this.el.find('.fc-day, .fc-disabled-day');
11834 this.colCoordCache = new CoordCache_1.default({
11835 els: this.colEls,
11836 isHorizontal: true
11837 });
11838 this.renderContentSkeleton();
11839 };
11840 TimeGrid.prototype.unrenderColumns = function () {
11841 this.unrenderContentSkeleton();
11842 };
11843 /* Content Skeleton
11844 ------------------------------------------------------------------------------------------------------------------*/
11845 // Renders the DOM that the view's content will live in
11846 TimeGrid.prototype.renderContentSkeleton = function () {
11847 var cellHtml = '';
11848 var i;
11849 var skeletonEl;
11850 for (i = 0; i < this.colCnt; i++) {
11851 cellHtml +=
11852 '<td>' +
11853 '<div class="fc-content-col">' +
11854 '<div class="fc-event-container fc-helper-container"></div>' +
11855 '<div class="fc-event-container"></div>' +
11856 '<div class="fc-highlight-container"></div>' +
11857 '<div class="fc-bgevent-container"></div>' +
11858 '<div class="fc-business-container"></div>' +
11859 '</div>' +
11860 '</td>';
11861 }
11862 skeletonEl = this.contentSkeletonEl = $('<div class="fc-content-skeleton">' +
11863 '<table>' +
11864 '<tr>' + cellHtml + '</tr>' +
11865 '</table>' +
11866 '</div>');
11867 this.colContainerEls = skeletonEl.find('.fc-content-col');
11868 this.helperContainerEls = skeletonEl.find('.fc-helper-container');
11869 this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)');
11870 this.bgContainerEls = skeletonEl.find('.fc-bgevent-container');
11871 this.highlightContainerEls = skeletonEl.find('.fc-highlight-container');
11872 this.businessContainerEls = skeletonEl.find('.fc-business-container');
11873 this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level
11874 this.el.append(skeletonEl);
11875 };
11876 TimeGrid.prototype.unrenderContentSkeleton = function () {
11877 if (this.contentSkeletonEl) {
11878 this.contentSkeletonEl.remove();
11879 this.contentSkeletonEl = null;
11880 this.colContainerEls = null;
11881 this.helperContainerEls = null;
11882 this.fgContainerEls = null;
11883 this.bgContainerEls = null;
11884 this.highlightContainerEls = null;
11885 this.businessContainerEls = null;
11886 }
11887 };
11888 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
11889 TimeGrid.prototype.groupSegsByCol = function (segs) {
11890 var segsByCol = [];
11891 var i;
11892 for (i = 0; i < this.colCnt; i++) {
11893 segsByCol.push([]);
11894 }
11895 for (i = 0; i < segs.length; i++) {
11896 segsByCol[segs[i].col].push(segs[i]);
11897 }
11898 return segsByCol;
11899 };
11900 // Given segments grouped by column, insert the segments' elements into a parallel array of container
11901 // elements, each living within a column.
11902 TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
11903 var col;
11904 var segs;
11905 var i;
11906 for (col = 0; col < this.colCnt; col++) {
11907 segs = segsByCol[col];
11908 for (i = 0; i < segs.length; i++) {
11909 containerEls.eq(col).append(segs[i].el);
11910 }
11911 }
11912 };
11913 /* Now Indicator
11914 ------------------------------------------------------------------------------------------------------------------*/
11915 TimeGrid.prototype.getNowIndicatorUnit = function () {
11916 return 'minute'; // will refresh on the minute
11917 };
11918 TimeGrid.prototype.renderNowIndicator = function (date) {
11919 // HACK: if date columns not ready for some reason (scheduler)
11920 if (!this.colContainerEls) {
11921 return;
11922 }
11923 // seg system might be overkill, but it handles scenario where line needs to be rendered
11924 // more than once because of columns with the same date (resources columns for example)
11925 var segs = this.componentFootprintToSegs(new ComponentFootprint_1.default(new UnzonedRange_1.default(date, date.valueOf() + 1), // protect against null range
11926 false // all-day
11927 ));
11928 var top = this.computeDateTop(date, date);
11929 var nodes = [];
11930 var i;
11931 // render lines within the columns
11932 for (i = 0; i < segs.length; i++) {
11933 nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>')
11934 .css('top', top)
11935 .appendTo(this.colContainerEls.eq(segs[i].col))[0]);
11936 }
11937 // render an arrow over the axis
11938 if (segs.length > 0) {
11939 nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>')
11940 .css('top', top)
11941 .appendTo(this.el.find('.fc-content-skeleton'))[0]);
11942 }
11943 this.nowIndicatorEls = $(nodes);
11944 };
11945 TimeGrid.prototype.unrenderNowIndicator = function () {
11946 if (this.nowIndicatorEls) {
11947 this.nowIndicatorEls.remove();
11948 this.nowIndicatorEls = null;
11949 }
11950 };
11951 /* Coordinates
11952 ------------------------------------------------------------------------------------------------------------------*/
11953 TimeGrid.prototype.updateSize = function (totalHeight, isAuto, isResize) {
11954 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
11955 this.slatCoordCache.build();
11956 if (isResize) {
11957 this.updateSegVerticals([].concat(this.eventRenderer.getSegs(), this.businessSegs || []));
11958 }
11959 };
11960 TimeGrid.prototype.getTotalSlatHeight = function () {
11961 return this.slatContainerEl.outerHeight();
11962 };
11963 // Computes the top coordinate, relative to the bounds of the grid, of the given date.
11964 // `ms` can be a millisecond UTC time OR a UTC moment.
11965 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
11966 TimeGrid.prototype.computeDateTop = function (ms, startOfDayDate) {
11967 return this.computeTimeTop(moment.duration(ms - startOfDayDate.clone().stripTime()));
11968 };
11969 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
11970 TimeGrid.prototype.computeTimeTop = function (time) {
11971 var len = this.slatEls.length;
11972 var dateProfile = this.dateProfile;
11973 var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered
11974 var slatIndex;
11975 var slatRemainder;
11976 // compute a floating-point number for how many slats should be progressed through.
11977 // from 0 to number of slats (inclusive)
11978 // constrained because minTime/maxTime might be customized.
11979 slatCoverage = Math.max(0, slatCoverage);
11980 slatCoverage = Math.min(len, slatCoverage);
11981 // an integer index of the furthest whole slat
11982 // from 0 to number slats (*exclusive*, so len-1)
11983 slatIndex = Math.floor(slatCoverage);
11984 slatIndex = Math.min(slatIndex, len - 1);
11985 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
11986 // could be 1.0 if slatCoverage is covering *all* the slots
11987 slatRemainder = slatCoverage - slatIndex;
11988 return this.slatCoordCache.getTopPosition(slatIndex) +
11989 this.slatCoordCache.getHeight(slatIndex) * slatRemainder;
11990 };
11991 // Refreshes the CSS top/bottom coordinates for each segment element.
11992 // Works when called after initial render, after a window resize/zoom for example.
11993 TimeGrid.prototype.updateSegVerticals = function (segs) {
11994 this.computeSegVerticals(segs);
11995 this.assignSegVerticals(segs);
11996 };
11997 // For each segment in an array, computes and assigns its top and bottom properties
11998 TimeGrid.prototype.computeSegVerticals = function (segs) {
11999 var eventMinHeight = this.opt('agendaEventMinHeight');
12000 var i;
12001 var seg;
12002 var dayDate;
12003 for (i = 0; i < segs.length; i++) {
12004 seg = segs[i];
12005 dayDate = this.dayDates[seg.dayIndex];
12006 seg.top = this.computeDateTop(seg.startMs, dayDate);
12007 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.endMs, dayDate));
12008 }
12009 };
12010 // Given segments that already have their top/bottom properties computed, applies those values to
12011 // the segments' elements.
12012 TimeGrid.prototype.assignSegVerticals = function (segs) {
12013 var i;
12014 var seg;
12015 for (i = 0; i < segs.length; i++) {
12016 seg = segs[i];
12017 seg.el.css(this.generateSegVerticalCss(seg));
12018 }
12019 };
12020 // Generates an object with CSS properties for the top/bottom coordinates of a segment element
12021 TimeGrid.prototype.generateSegVerticalCss = function (seg) {
12022 return {
12023 top: seg.top,
12024 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
12025 };
12026 };
12027 /* Hit System
12028 ------------------------------------------------------------------------------------------------------------------*/
12029 TimeGrid.prototype.prepareHits = function () {
12030 this.colCoordCache.build();
12031 this.slatCoordCache.build();
12032 };
12033 TimeGrid.prototype.releaseHits = function () {
12034 this.colCoordCache.clear();
12035 // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop
12036 };
12037 TimeGrid.prototype.queryHit = function (leftOffset, topOffset) {
12038 var snapsPerSlot = this.snapsPerSlot;
12039 var colCoordCache = this.colCoordCache;
12040 var slatCoordCache = this.slatCoordCache;
12041 if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) {
12042 var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
12043 var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
12044 if (colIndex != null && slatIndex != null) {
12045 var slatTop = slatCoordCache.getTopOffset(slatIndex);
12046 var slatHeight = slatCoordCache.getHeight(slatIndex);
12047 var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
12048 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
12049 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
12050 var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
12051 var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
12052 return {
12053 col: colIndex,
12054 snap: snapIndex,
12055 component: this,
12056 left: colCoordCache.getLeftOffset(colIndex),
12057 right: colCoordCache.getRightOffset(colIndex),
12058 top: snapTop,
12059 bottom: snapBottom
12060 };
12061 }
12062 }
12063 };
12064 TimeGrid.prototype.getHitFootprint = function (hit) {
12065 var start = this.getCellDate(0, hit.col); // row=0
12066 var time = this.computeSnapTime(hit.snap); // pass in the snap-index
12067 var end;
12068 start.time(time);
12069 end = start.clone().add(this.snapDuration);
12070 return new ComponentFootprint_1.default(new UnzonedRange_1.default(start, end), false // all-day?
12071 );
12072 };
12073 // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
12074 TimeGrid.prototype.computeSnapTime = function (snapIndex) {
12075 return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex);
12076 };
12077 TimeGrid.prototype.getHitEl = function (hit) {
12078 return this.colEls.eq(hit.col);
12079 };
12080 /* Event Drag Visualization
12081 ------------------------------------------------------------------------------------------------------------------*/
12082 // Renders a visual indication of an event being dragged over the specified date(s).
12083 // A returned value of `true` signals that a mock "helper" event has been rendered.
12084 TimeGrid.prototype.renderDrag = function (eventFootprints, seg, isTouch) {
12085 var i;
12086 if (seg) {
12087 if (eventFootprints.length) {
12088 this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
12089 // signal that a helper has been rendered
12090 return true;
12091 }
12092 }
12093 else {
12094 for (i = 0; i < eventFootprints.length; i++) {
12095 this.renderHighlight(eventFootprints[i].componentFootprint);
12096 }
12097 }
12098 };
12099 // Unrenders any visual indication of an event being dragged
12100 TimeGrid.prototype.unrenderDrag = function () {
12101 this.unrenderHighlight();
12102 this.helperRenderer.unrender();
12103 };
12104 /* Event Resize Visualization
12105 ------------------------------------------------------------------------------------------------------------------*/
12106 // Renders a visual indication of an event being resized
12107 TimeGrid.prototype.renderEventResize = function (eventFootprints, seg, isTouch) {
12108 this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
12109 };
12110 // Unrenders any visual indication of an event being resized
12111 TimeGrid.prototype.unrenderEventResize = function () {
12112 this.helperRenderer.unrender();
12113 };
12114 /* Selection
12115 ------------------------------------------------------------------------------------------------------------------*/
12116 // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
12117 TimeGrid.prototype.renderSelectionFootprint = function (componentFootprint) {
12118 if (this.opt('selectHelper')) {
12119 this.helperRenderer.renderComponentFootprint(componentFootprint);
12120 }
12121 else {
12122 this.renderHighlight(componentFootprint);
12123 }
12124 };
12125 // Unrenders any visual indication of a selection
12126 TimeGrid.prototype.unrenderSelection = function () {
12127 this.helperRenderer.unrender();
12128 this.unrenderHighlight();
12129 };
12130 return TimeGrid;
12131 }(InteractiveDateComponent_1.default));
12132 exports.default = TimeGrid;
12133 TimeGrid.prototype.eventRendererClass = TimeGridEventRenderer_1.default;
12134 TimeGrid.prototype.businessHourRendererClass = BusinessHourRenderer_1.default;
12135 TimeGrid.prototype.helperRendererClass = TimeGridHelperRenderer_1.default;
12136 TimeGrid.prototype.fillRendererClass = TimeGridFillRenderer_1.default;
12137 StandardInteractionsMixin_1.default.mixInto(TimeGrid);
12138 DayTableMixin_1.default.mixInto(TimeGrid);
12139
12140
12141 /***/ }),
12142 /* 228 */
12143 /***/ (function(module, exports, __webpack_require__) {
12144
12145 Object.defineProperty(exports, "__esModule", { value: true });
12146 var tslib_1 = __webpack_require__(2);
12147 var UnzonedRange_1 = __webpack_require__(5);
12148 var DateProfileGenerator_1 = __webpack_require__(221);
12149 var BasicViewDateProfileGenerator = /** @class */ (function (_super) {
12150 tslib_1.__extends(BasicViewDateProfileGenerator, _super);
12151 function BasicViewDateProfileGenerator() {
12152 return _super !== null && _super.apply(this, arguments) || this;
12153 }
12154 // Computes the date range that will be rendered.
12155 BasicViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
12156 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange
12157 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
12158 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
12159 // year and month views should be aligned with weeks. this is already done for week
12160 if (/^(year|month)$/.test(currentRangeUnit)) {
12161 start.startOf('week');
12162 // make end-of-week if not already
12163 if (end.weekday()) {
12164 end.add(1, 'week').startOf('week'); // exclusively move backwards
12165 }
12166 }
12167 return new UnzonedRange_1.default(start, end);
12168 };
12169 return BasicViewDateProfileGenerator;
12170 }(DateProfileGenerator_1.default));
12171 exports.default = BasicViewDateProfileGenerator;
12172
12173
12174 /***/ }),
12175 /* 229 */
12176 /***/ (function(module, exports, __webpack_require__) {
12177
12178 Object.defineProperty(exports, "__esModule", { value: true });
12179 var tslib_1 = __webpack_require__(2);
12180 var moment = __webpack_require__(0);
12181 var util_1 = __webpack_require__(4);
12182 var BasicView_1 = __webpack_require__(62);
12183 var MonthViewDateProfileGenerator_1 = __webpack_require__(253);
12184 /* A month view with day cells running in rows (one-per-week) and columns
12185 ----------------------------------------------------------------------------------------------------------------------*/
12186 var MonthView = /** @class */ (function (_super) {
12187 tslib_1.__extends(MonthView, _super);
12188 function MonthView() {
12189 return _super !== null && _super.apply(this, arguments) || this;
12190 }
12191 // Overrides the default BasicView behavior to have special multi-week auto-height logic
12192 MonthView.prototype.setGridHeight = function (height, isAuto) {
12193 // if auto, make the height of each row the height that it would be if there were 6 weeks
12194 if (isAuto) {
12195 height *= this.dayGrid.rowCnt / 6;
12196 }
12197 util_1.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
12198 };
12199 MonthView.prototype.isDateInOtherMonth = function (date, dateProfile) {
12200 return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize
12201 };
12202 return MonthView;
12203 }(BasicView_1.default));
12204 exports.default = MonthView;
12205 MonthView.prototype.dateProfileGeneratorClass = MonthViewDateProfileGenerator_1.default;
12206
12207
12208 /***/ }),
12209 /* 230 */
12210 /***/ (function(module, exports, __webpack_require__) {
12211
12212 Object.defineProperty(exports, "__esModule", { value: true });
12213 var tslib_1 = __webpack_require__(2);
12214 var $ = __webpack_require__(3);
12215 var util_1 = __webpack_require__(4);
12216 var UnzonedRange_1 = __webpack_require__(5);
12217 var View_1 = __webpack_require__(41);
12218 var Scroller_1 = __webpack_require__(39);
12219 var ListEventRenderer_1 = __webpack_require__(254);
12220 var ListEventPointing_1 = __webpack_require__(255);
12221 /*
12222 Responsible for the scroller, and forwarding event-related actions into the "grid".
12223 */
12224 var ListView = /** @class */ (function (_super) {
12225 tslib_1.__extends(ListView, _super);
12226 function ListView(calendar, viewSpec) {
12227 var _this = _super.call(this, calendar, viewSpec) || this;
12228 _this.segSelector = '.fc-list-item'; // which elements accept event actions
12229 _this.scroller = new Scroller_1.default({
12230 overflowX: 'hidden',
12231 overflowY: 'auto'
12232 });
12233 return _this;
12234 }
12235 ListView.prototype.renderSkeleton = function () {
12236 this.el.addClass('fc-list-view ' +
12237 this.calendar.theme.getClass('listView'));
12238 this.scroller.render();
12239 this.scroller.el.appendTo(this.el);
12240 this.contentEl = this.scroller.scrollEl; // shortcut
12241 };
12242 ListView.prototype.unrenderSkeleton = function () {
12243 this.scroller.destroy(); // will remove the Grid too
12244 };
12245 ListView.prototype.updateSize = function (totalHeight, isAuto, isResize) {
12246 _super.prototype.updateSize.call(this, totalHeight, isAuto, isResize);
12247 this.scroller.clear(); // sets height to 'auto' and clears overflow
12248 if (!isAuto) {
12249 this.scroller.setHeight(this.computeScrollerHeight(totalHeight));
12250 }
12251 };
12252 ListView.prototype.computeScrollerHeight = function (totalHeight) {
12253 return totalHeight -
12254 util_1.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
12255 };
12256 ListView.prototype.renderDates = function (dateProfile) {
12257 var calendar = this.calendar;
12258 var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true);
12259 var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true);
12260 var dayDates = [];
12261 var dayRanges = [];
12262 while (dayStart < viewEnd) {
12263 dayDates.push(dayStart.clone());
12264 dayRanges.push(new UnzonedRange_1.default(dayStart, dayStart.clone().add(1, 'day')));
12265 dayStart.add(1, 'day');
12266 }
12267 this.dayDates = dayDates;
12268 this.dayRanges = dayRanges;
12269 // all real rendering happens in EventRenderer
12270 };
12271 // slices by day
12272 ListView.prototype.componentFootprintToSegs = function (footprint) {
12273 var dayRanges = this.dayRanges;
12274 var dayIndex;
12275 var segRange;
12276 var seg;
12277 var segs = [];
12278 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
12279 segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]);
12280 if (segRange) {
12281 seg = {
12282 startMs: segRange.startMs,
12283 endMs: segRange.endMs,
12284 isStart: segRange.isStart,
12285 isEnd: segRange.isEnd,
12286 dayIndex: dayIndex
12287 };
12288 segs.push(seg);
12289 // detect when footprint won't go fully into the next day,
12290 // and mutate the latest seg to the be the end.
12291 if (!seg.isEnd && !footprint.isAllDay &&
12292 dayIndex + 1 < dayRanges.length &&
12293 footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold) {
12294 seg.endMs = footprint.unzonedRange.endMs;
12295 seg.isEnd = true;
12296 break;
12297 }
12298 }
12299 }
12300 return segs;
12301 };
12302 ListView.prototype.renderEmptyMessage = function () {
12303 this.contentEl.html('<div class="fc-list-empty-wrap2">' + // TODO: try less wraps
12304 '<div class="fc-list-empty-wrap1">' +
12305 '<div class="fc-list-empty">' +
12306 util_1.htmlEscape(this.opt('noEventsMessage')) +
12307 '</div>' +
12308 '</div>' +
12309 '</div>');
12310 };
12311 // render the event segments in the view
12312 ListView.prototype.renderSegList = function (allSegs) {
12313 var segsByDay = this.groupSegsByDay(allSegs); // sparse array
12314 var dayIndex;
12315 var daySegs;
12316 var i;
12317 var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody/></table>');
12318 var tbodyEl = tableEl.find('tbody');
12319 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
12320 daySegs = segsByDay[dayIndex];
12321 if (daySegs) {
12322 // append a day header
12323 tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex]));
12324 this.eventRenderer.sortEventSegs(daySegs);
12325 for (i = 0; i < daySegs.length; i++) {
12326 tbodyEl.append(daySegs[i].el); // append event row
12327 }
12328 }
12329 }
12330 this.contentEl.empty().append(tableEl);
12331 };
12332 // Returns a sparse array of arrays, segs grouped by their dayIndex
12333 ListView.prototype.groupSegsByDay = function (segs) {
12334 var segsByDay = []; // sparse array
12335 var i;
12336 var seg;
12337 for (i = 0; i < segs.length; i++) {
12338 seg = segs[i];
12339 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
12340 .push(seg);
12341 }
12342 return segsByDay;
12343 };
12344 // generates the HTML for the day headers that live amongst the event rows
12345 ListView.prototype.dayHeaderHtml = function (dayDate) {
12346 var mainFormat = this.opt('listDayFormat');
12347 var altFormat = this.opt('listDayAltFormat');
12348 return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' +
12349 '<td class="' + (this.calendar.theme.getClass('tableListHeading') ||
12350 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' +
12351 (mainFormat ?
12352 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-main' }, util_1.htmlEscape(dayDate.format(mainFormat)) // inner HTML
12353 ) :
12354 '') +
12355 (altFormat ?
12356 this.buildGotoAnchorHtml(dayDate, { 'class': 'fc-list-heading-alt' }, util_1.htmlEscape(dayDate.format(altFormat)) // inner HTML
12357 ) :
12358 '') +
12359 '</td>' +
12360 '</tr>';
12361 };
12362 return ListView;
12363 }(View_1.default));
12364 exports.default = ListView;
12365 ListView.prototype.eventRendererClass = ListEventRenderer_1.default;
12366 ListView.prototype.eventPointingClass = ListEventPointing_1.default;
12367
12368
12369 /***/ }),
12370 /* 231 */,
12371 /* 232 */,
12372 /* 233 */,
12373 /* 234 */,
12374 /* 235 */,
12375 /* 236 */
12376 /***/ (function(module, exports, __webpack_require__) {
12377
12378 var $ = __webpack_require__(3);
12379 var exportHooks = __webpack_require__(16);
12380 var util_1 = __webpack_require__(4);
12381 var Calendar_1 = __webpack_require__(220);
12382 // for intentional side-effects
12383 __webpack_require__(10);
12384 __webpack_require__(47);
12385 __webpack_require__(256);
12386 __webpack_require__(257);
12387 __webpack_require__(260);
12388 __webpack_require__(261);
12389 __webpack_require__(262);
12390 __webpack_require__(263);
12391 $.fullCalendar = exportHooks;
12392 $.fn.fullCalendar = function (options) {
12393 var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
12394 var res = this; // what this function will return (this jQuery object by default)
12395 this.each(function (i, _element) {
12396 var element = $(_element);
12397 var calendar = element.data('fullCalendar'); // get the existing calendar object (if any)
12398 var singleRes; // the returned value of this single method call
12399 // a method call
12400 if (typeof options === 'string') {
12401 if (options === 'getCalendar') {
12402 if (!i) {
12403 res = calendar;
12404 }
12405 }
12406 else if (options === 'destroy') {
12407 if (calendar) {
12408 calendar.destroy();
12409 element.removeData('fullCalendar');
12410 }
12411 }
12412 else if (!calendar) {
12413 util_1.warn('Attempting to call a FullCalendar method on an element with no calendar.');
12414 }
12415 else if ($.isFunction(calendar[options])) {
12416 singleRes = calendar[options].apply(calendar, args);
12417 if (!i) {
12418 res = singleRes; // record the first method call result
12419 }
12420 if (options === 'destroy') {
12421 element.removeData('fullCalendar');
12422 }
12423 }
12424 else {
12425 util_1.warn("'" + options + "' is an unknown FullCalendar method.");
12426 }
12427 }
12428 else if (!calendar) {
12429 calendar = new Calendar_1.default(element, options);
12430 element.data('fullCalendar', calendar);
12431 calendar.render();
12432 }
12433 });
12434 return res;
12435 };
12436 module.exports = exportHooks;
12437
12438
12439 /***/ }),
12440 /* 237 */
12441 /***/ (function(module, exports, __webpack_require__) {
12442
12443 Object.defineProperty(exports, "__esModule", { value: true });
12444 var tslib_1 = __webpack_require__(2);
12445 var Model_1 = __webpack_require__(48);
12446 var Component = /** @class */ (function (_super) {
12447 tslib_1.__extends(Component, _super);
12448 function Component() {
12449 return _super !== null && _super.apply(this, arguments) || this;
12450 }
12451 Component.prototype.setElement = function (el) {
12452 this.el = el;
12453 this.bindGlobalHandlers();
12454 this.renderSkeleton();
12455 this.set('isInDom', true);
12456 };
12457 Component.prototype.removeElement = function () {
12458 this.unset('isInDom');
12459 this.unrenderSkeleton();
12460 this.unbindGlobalHandlers();
12461 this.el.remove();
12462 // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
12463 // We don't null-out the View's other jQuery element references upon destroy,
12464 // so we shouldn't kill this.el either.
12465 };
12466 Component.prototype.bindGlobalHandlers = function () {
12467 // subclasses can override
12468 };
12469 Component.prototype.unbindGlobalHandlers = function () {
12470 // subclasses can override
12471 };
12472 /*
12473 NOTE: Can't have a `render` method. Read the deprecation notice in View::executeDateRender
12474 */
12475 // Renders the basic structure of the view before any content is rendered
12476 Component.prototype.renderSkeleton = function () {
12477 // subclasses should implement
12478 };
12479 // Unrenders the basic structure of the view
12480 Component.prototype.unrenderSkeleton = function () {
12481 // subclasses should implement
12482 };
12483 return Component;
12484 }(Model_1.default));
12485 exports.default = Component;
12486
12487
12488 /***/ }),
12489 /* 238 */
12490 /***/ (function(module, exports) {
12491
12492 Object.defineProperty(exports, "__esModule", { value: true });
12493 var Iterator = /** @class */ (function () {
12494 function Iterator(items) {
12495 this.items = items || [];
12496 }
12497 /* Calls a method on every item passing the arguments through */
12498 Iterator.prototype.proxyCall = function (methodName) {
12499 var args = [];
12500 for (var _i = 1; _i < arguments.length; _i++) {
12501 args[_i - 1] = arguments[_i];
12502 }
12503 var results = [];
12504 this.items.forEach(function (item) {
12505 results.push(item[methodName].apply(item, args));
12506 });
12507 return results;
12508 };
12509 return Iterator;
12510 }());
12511 exports.default = Iterator;
12512
12513
12514 /***/ }),
12515 /* 239 */
12516 /***/ (function(module, exports, __webpack_require__) {
12517
12518 Object.defineProperty(exports, "__esModule", { value: true });
12519 var $ = __webpack_require__(3);
12520 var util_1 = __webpack_require__(4);
12521 /* Toolbar with buttons and title
12522 ----------------------------------------------------------------------------------------------------------------------*/
12523 var Toolbar = /** @class */ (function () {
12524 function Toolbar(calendar, toolbarOptions) {
12525 this.el = null; // mirrors local `el`
12526 this.viewsWithButtons = [];
12527 this.calendar = calendar;
12528 this.toolbarOptions = toolbarOptions;
12529 }
12530 // method to update toolbar-specific options, not calendar-wide options
12531 Toolbar.prototype.setToolbarOptions = function (newToolbarOptions) {
12532 this.toolbarOptions = newToolbarOptions;
12533 };
12534 // can be called repeatedly and will rerender
12535 Toolbar.prototype.render = function () {
12536 var sections = this.toolbarOptions.layout;
12537 var el = this.el;
12538 if (sections) {
12539 if (!el) {
12540 el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'/>");
12541 }
12542 else {
12543 el.empty();
12544 }
12545 el.append(this.renderSection('left'))
12546 .append(this.renderSection('right'))
12547 .append(this.renderSection('center'))
12548 .append('<div class="fc-clear"/>');
12549 }
12550 else {
12551 this.removeElement();
12552 }
12553 };
12554 Toolbar.prototype.removeElement = function () {
12555 if (this.el) {
12556 this.el.remove();
12557 this.el = null;
12558 }
12559 };
12560 Toolbar.prototype.renderSection = function (position) {
12561 var _this = this;
12562 var calendar = this.calendar;
12563 var theme = calendar.theme;
12564 var optionsManager = calendar.optionsManager;
12565 var viewSpecManager = calendar.viewSpecManager;
12566 var sectionEl = $('<div class="fc-' + position + '"/>');
12567 var buttonStr = this.toolbarOptions.layout[position];
12568 var calendarCustomButtons = optionsManager.get('customButtons') || {};
12569 var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
12570 var calendarButtonText = optionsManager.get('buttonText') || {};
12571 if (buttonStr) {
12572 $.each(buttonStr.split(' '), function (i, buttonGroupStr) {
12573 var groupChildren = $();
12574 var isOnlyButtons = true;
12575 var groupEl;
12576 $.each(buttonGroupStr.split(','), function (j, buttonName) {
12577 var customButtonProps;
12578 var viewSpec;
12579 var buttonClick;
12580 var buttonIcon; // only one of these will be set
12581 var buttonText; // "
12582 var buttonInnerHtml;
12583 var buttonClasses;
12584 var buttonEl;
12585 var buttonAriaAttr;
12586 if (buttonName === 'title') {
12587 groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height
12588 isOnlyButtons = false;
12589 }
12590 else {
12591 if ((customButtonProps = calendarCustomButtons[buttonName])) {
12592 buttonClick = function (ev) {
12593 if (customButtonProps.click) {
12594 customButtonProps.click.call(buttonEl[0], ev);
12595 }
12596 };
12597 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
12598 (buttonIcon = theme.getIconClass(buttonName)) ||
12599 (buttonText = customButtonProps.text);
12600 }
12601 else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) {
12602 _this.viewsWithButtons.push(buttonName);
12603 buttonClick = function () {
12604 calendar.changeView(buttonName);
12605 };
12606 (buttonText = viewSpec.buttonTextOverride) ||
12607 (buttonIcon = theme.getIconClass(buttonName)) ||
12608 (buttonText = viewSpec.buttonTextDefault);
12609 }
12610 else if (calendar[buttonName]) {
12611 buttonClick = function () {
12612 calendar[buttonName]();
12613 };
12614 (buttonText = calendarButtonTextOverrides[buttonName]) ||
12615 (buttonIcon = theme.getIconClass(buttonName)) ||
12616 (buttonText = calendarButtonText[buttonName]);
12617 // ^ everything else is considered default
12618 }
12619 if (buttonClick) {
12620 buttonClasses = [
12621 'fc-' + buttonName + '-button',
12622 theme.getClass('button'),
12623 theme.getClass('stateDefault')
12624 ];
12625 if (buttonText) {
12626 buttonInnerHtml = util_1.htmlEscape(buttonText);
12627 buttonAriaAttr = '';
12628 }
12629 else if (buttonIcon) {
12630 buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
12631 buttonAriaAttr = ' aria-label="' + buttonName + '"';
12632 }
12633 buttonEl = $(// type="button" so that it doesn't submit a form
12634 '<button type="button" class="' + buttonClasses.join(' ') + '"' +
12635 buttonAriaAttr +
12636 '>' + buttonInnerHtml + '</button>')
12637 .click(function (ev) {
12638 // don't process clicks for disabled buttons
12639 if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) {
12640 buttonClick(ev);
12641 // after the click action, if the button becomes the "active" tab, or disabled,
12642 // it should never have a hover class, so remove it now.
12643 if (buttonEl.hasClass(theme.getClass('stateActive')) ||
12644 buttonEl.hasClass(theme.getClass('stateDisabled'))) {
12645 buttonEl.removeClass(theme.getClass('stateHover'));
12646 }
12647 }
12648 })
12649 .mousedown(function () {
12650 // the *down* effect (mouse pressed in).
12651 // only on buttons that are not the "active" tab, or disabled
12652 buttonEl
12653 .not('.' + theme.getClass('stateActive'))
12654 .not('.' + theme.getClass('stateDisabled'))
12655 .addClass(theme.getClass('stateDown'));
12656 })
12657 .mouseup(function () {
12658 // undo the *down* effect
12659 buttonEl.removeClass(theme.getClass('stateDown'));
12660 })
12661 .hover(function () {
12662 // the *hover* effect.
12663 // only on buttons that are not the "active" tab, or disabled
12664 buttonEl
12665 .not('.' + theme.getClass('stateActive'))
12666 .not('.' + theme.getClass('stateDisabled'))
12667 .addClass(theme.getClass('stateHover'));
12668 }, function () {
12669 // undo the *hover* effect
12670 buttonEl
12671 .removeClass(theme.getClass('stateHover'))
12672 .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup
12673 });
12674 groupChildren = groupChildren.add(buttonEl);
12675 }
12676 }
12677 });
12678 if (isOnlyButtons) {
12679 groupChildren
12680 .first().addClass(theme.getClass('cornerLeft')).end()
12681 .last().addClass(theme.getClass('cornerRight')).end();
12682 }
12683 if (groupChildren.length > 1) {
12684 groupEl = $('<div/>');
12685 if (isOnlyButtons) {
12686 groupEl.addClass(theme.getClass('buttonGroup'));
12687 }
12688 groupEl.append(groupChildren);
12689 sectionEl.append(groupEl);
12690 }
12691 else {
12692 sectionEl.append(groupChildren); // 1 or 0 children
12693 }
12694 });
12695 }
12696 return sectionEl;
12697 };
12698 Toolbar.prototype.updateTitle = function (text) {
12699 if (this.el) {
12700 this.el.find('h2').text(text);
12701 }
12702 };
12703 Toolbar.prototype.activateButton = function (buttonName) {
12704 if (this.el) {
12705 this.el.find('.fc-' + buttonName + '-button')
12706 .addClass(this.calendar.theme.getClass('stateActive'));
12707 }
12708 };
12709 Toolbar.prototype.deactivateButton = function (buttonName) {
12710 if (this.el) {
12711 this.el.find('.fc-' + buttonName + '-button')
12712 .removeClass(this.calendar.theme.getClass('stateActive'));
12713 }
12714 };
12715 Toolbar.prototype.disableButton = function (buttonName) {
12716 if (this.el) {
12717 this.el.find('.fc-' + buttonName + '-button')
12718 .prop('disabled', true)
12719 .addClass(this.calendar.theme.getClass('stateDisabled'));
12720 }
12721 };
12722 Toolbar.prototype.enableButton = function (buttonName) {
12723 if (this.el) {
12724 this.el.find('.fc-' + buttonName + '-button')
12725 .prop('disabled', false)
12726 .removeClass(this.calendar.theme.getClass('stateDisabled'));
12727 }
12728 };
12729 Toolbar.prototype.getViewsWithButtons = function () {
12730 return this.viewsWithButtons;
12731 };
12732 return Toolbar;
12733 }());
12734 exports.default = Toolbar;
12735
12736
12737 /***/ }),
12738 /* 240 */
12739 /***/ (function(module, exports, __webpack_require__) {
12740
12741 Object.defineProperty(exports, "__esModule", { value: true });
12742 var tslib_1 = __webpack_require__(2);
12743 var $ = __webpack_require__(3);
12744 var util_1 = __webpack_require__(4);
12745 var options_1 = __webpack_require__(32);
12746 var locale_1 = __webpack_require__(31);
12747 var Model_1 = __webpack_require__(48);
12748 var OptionsManager = /** @class */ (function (_super) {
12749 tslib_1.__extends(OptionsManager, _super);
12750 function OptionsManager(_calendar, overrides) {
12751 var _this = _super.call(this) || this;
12752 _this._calendar = _calendar;
12753 _this.overrides = $.extend({}, overrides); // make a copy
12754 _this.dynamicOverrides = {};
12755 _this.compute();
12756 return _this;
12757 }
12758 OptionsManager.prototype.add = function (newOptionHash) {
12759 var optionCnt = 0;
12760 var optionName;
12761 this.recordOverrides(newOptionHash); // will trigger this model's watchers
12762 for (optionName in newOptionHash) {
12763 optionCnt++;
12764 }
12765 // special-case handling of single option change.
12766 // if only one option change, `optionName` will be its name.
12767 if (optionCnt === 1) {
12768 if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') {
12769 this._calendar.updateViewSize(true); // isResize=true
12770 return;
12771 }
12772 else if (optionName === 'defaultDate') {
12773 return; // can't change date this way. use gotoDate instead
12774 }
12775 else if (optionName === 'businessHours') {
12776 return; // this model already reacts to this
12777 }
12778 else if (/^(event|select)(Overlap|Constraint|Allow)$/.test(optionName)) {
12779 return; // doesn't affect rendering. only interactions.
12780 }
12781 else if (optionName === 'timezone') {
12782 this._calendar.view.flash('initialEvents');
12783 return;
12784 }
12785 }
12786 // catch-all. rerender the header and footer and rebuild/rerender the current view
12787 this._calendar.renderHeader();
12788 this._calendar.renderFooter();
12789 // even non-current views will be affected by this option change. do before rerender
12790 // TODO: detangle
12791 this._calendar.viewsByType = {};
12792 this._calendar.reinitView();
12793 };
12794 // Computes the flattened options hash for the calendar and assigns to `this.options`.
12795 // Assumes this.overrides and this.dynamicOverrides have already been initialized.
12796 OptionsManager.prototype.compute = function () {
12797 var locale;
12798 var localeDefaults;
12799 var isRTL;
12800 var dirDefaults;
12801 var rawOptions;
12802 locale = util_1.firstDefined(// explicit locale option given?
12803 this.dynamicOverrides.locale, this.overrides.locale);
12804 localeDefaults = locale_1.localeOptionHash[locale];
12805 if (!localeDefaults) {
12806 locale = options_1.globalDefaults.locale;
12807 localeDefaults = locale_1.localeOptionHash[locale] || {};
12808 }
12809 isRTL = util_1.firstDefined(// based on options computed so far, is direction RTL?
12810 this.dynamicOverrides.isRTL, this.overrides.isRTL, localeDefaults.isRTL, options_1.globalDefaults.isRTL);
12811 dirDefaults = isRTL ? options_1.rtlDefaults : {};
12812 this.dirDefaults = dirDefaults;
12813 this.localeDefaults = localeDefaults;
12814 rawOptions = options_1.mergeOptions([
12815 options_1.globalDefaults,
12816 dirDefaults,
12817 localeDefaults,
12818 this.overrides,
12819 this.dynamicOverrides
12820 ]);
12821 locale_1.populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options
12822 this.reset(rawOptions);
12823 };
12824 // stores the new options internally, but does not rerender anything.
12825 OptionsManager.prototype.recordOverrides = function (newOptionHash) {
12826 var optionName;
12827 for (optionName in newOptionHash) {
12828 this.dynamicOverrides[optionName] = newOptionHash[optionName];
12829 }
12830 this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it
12831 this.compute(); // this.options needs to be recomputed after the dynamic override
12832 };
12833 return OptionsManager;
12834 }(Model_1.default));
12835 exports.default = OptionsManager;
12836
12837
12838 /***/ }),
12839 /* 241 */
12840 /***/ (function(module, exports, __webpack_require__) {
12841
12842 Object.defineProperty(exports, "__esModule", { value: true });
12843 var moment = __webpack_require__(0);
12844 var $ = __webpack_require__(3);
12845 var ViewRegistry_1 = __webpack_require__(22);
12846 var util_1 = __webpack_require__(4);
12847 var options_1 = __webpack_require__(32);
12848 var locale_1 = __webpack_require__(31);
12849 var ViewSpecManager = /** @class */ (function () {
12850 function ViewSpecManager(optionsManager, _calendar) {
12851 this.optionsManager = optionsManager;
12852 this._calendar = _calendar;
12853 this.clearCache();
12854 }
12855 ViewSpecManager.prototype.clearCache = function () {
12856 this.viewSpecCache = {};
12857 };
12858 // Gets information about how to create a view. Will use a cache.
12859 ViewSpecManager.prototype.getViewSpec = function (viewType) {
12860 var cache = this.viewSpecCache;
12861 return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType));
12862 };
12863 // Given a duration singular unit, like "week" or "day", finds a matching view spec.
12864 // Preference is given to views that have corresponding buttons.
12865 ViewSpecManager.prototype.getUnitViewSpec = function (unit) {
12866 var viewTypes;
12867 var i;
12868 var spec;
12869 if ($.inArray(unit, util_1.unitsDesc) !== -1) {
12870 // put views that have buttons first. there will be duplicates, but oh well
12871 viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well?
12872 $.each(ViewRegistry_1.viewHash, function (viewType) {
12873 viewTypes.push(viewType);
12874 });
12875 for (i = 0; i < viewTypes.length; i++) {
12876 spec = this.getViewSpec(viewTypes[i]);
12877 if (spec) {
12878 if (spec.singleUnit === unit) {
12879 return spec;
12880 }
12881 }
12882 }
12883 }
12884 };
12885 // Builds an object with information on how to create a given view
12886 ViewSpecManager.prototype.buildViewSpec = function (requestedViewType) {
12887 var viewOverrides = this.optionsManager.overrides.views || {};
12888 var specChain = []; // for the view. lowest to highest priority
12889 var defaultsChain = []; // for the view. lowest to highest priority
12890 var overridesChain = []; // for the view. lowest to highest priority
12891 var viewType = requestedViewType;
12892 var spec; // for the view
12893 var overrides; // for the view
12894 var durationInput;
12895 var duration;
12896 var unit;
12897 // iterate from the specific view definition to a more general one until we hit an actual View class
12898 while (viewType) {
12899 spec = ViewRegistry_1.viewHash[viewType];
12900 overrides = viewOverrides[viewType];
12901 viewType = null; // clear. might repopulate for another iteration
12902 if (typeof spec === 'function') {
12903 spec = { 'class': spec };
12904 }
12905 if (spec) {
12906 specChain.unshift(spec);
12907 defaultsChain.unshift(spec.defaults || {});
12908 durationInput = durationInput || spec.duration;
12909 viewType = viewType || spec.type;
12910 }
12911 if (overrides) {
12912 overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level
12913 durationInput = durationInput || overrides.duration;
12914 viewType = viewType || overrides.type;
12915 }
12916 }
12917 spec = util_1.mergeProps(specChain);
12918 spec.type = requestedViewType;
12919 if (!spec['class']) {
12920 return false;
12921 }
12922 // fall back to top-level `duration` option
12923 durationInput = durationInput ||
12924 this.optionsManager.dynamicOverrides.duration ||
12925 this.optionsManager.overrides.duration;
12926 if (durationInput) {
12927 duration = moment.duration(durationInput);
12928 if (duration.valueOf()) {
12929 unit = util_1.computeDurationGreatestUnit(duration, durationInput);
12930 spec.duration = duration;
12931 spec.durationUnit = unit;
12932 // view is a single-unit duration, like "week" or "day"
12933 // incorporate options for this. lowest priority
12934 if (duration.as(unit) === 1) {
12935 spec.singleUnit = unit;
12936 overridesChain.unshift(viewOverrides[unit] || {});
12937 }
12938 }
12939 }
12940 spec.defaults = options_1.mergeOptions(defaultsChain);
12941 spec.overrides = options_1.mergeOptions(overridesChain);
12942 this.buildViewSpecOptions(spec);
12943 this.buildViewSpecButtonText(spec, requestedViewType);
12944 return spec;
12945 };
12946 // Builds and assigns a view spec's options object from its already-assigned defaults and overrides
12947 ViewSpecManager.prototype.buildViewSpecOptions = function (spec) {
12948 var optionsManager = this.optionsManager;
12949 spec.options = options_1.mergeOptions([
12950 options_1.globalDefaults,
12951 spec.defaults,
12952 optionsManager.dirDefaults,
12953 optionsManager.localeDefaults,
12954 optionsManager.overrides,
12955 spec.overrides,
12956 optionsManager.dynamicOverrides // dynamically set via setter. highest precedence
12957 ]);
12958 locale_1.populateInstanceComputableOptions(spec.options);
12959 };
12960 // Computes and assigns a view spec's buttonText-related options
12961 ViewSpecManager.prototype.buildViewSpecButtonText = function (spec, requestedViewType) {
12962 var optionsManager = this.optionsManager;
12963 // given an options object with a possible `buttonText` hash, lookup the buttonText for the
12964 // requested view, falling back to a generic unit entry like "week" or "day"
12965 function queryButtonText(options) {
12966 var buttonText = options.buttonText || {};
12967 return buttonText[requestedViewType] ||
12968 // view can decide to look up a certain key
12969 (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) ||
12970 // a key like "month"
12971 (spec.singleUnit ? buttonText[spec.singleUnit] : null);
12972 }
12973 // highest to lowest priority
12974 spec.buttonTextOverride =
12975 queryButtonText(optionsManager.dynamicOverrides) ||
12976 queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
12977 spec.overrides.buttonText; // `buttonText` for view-specific options is a string
12978 // highest to lowest priority. mirrors buildViewSpecOptions
12979 spec.buttonTextDefault =
12980 queryButtonText(optionsManager.localeDefaults) ||
12981 queryButtonText(optionsManager.dirDefaults) ||
12982 spec.defaults.buttonText || // a single string. from ViewSubclass.defaults
12983 queryButtonText(options_1.globalDefaults) ||
12984 (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days"
12985 requestedViewType; // fall back to given view name
12986 };
12987 return ViewSpecManager;
12988 }());
12989 exports.default = ViewSpecManager;
12990
12991
12992 /***/ }),
12993 /* 242 */
12994 /***/ (function(module, exports, __webpack_require__) {
12995
12996 Object.defineProperty(exports, "__esModule", { value: true });
12997 var $ = __webpack_require__(3);
12998 var util_1 = __webpack_require__(4);
12999 var EventPeriod_1 = __webpack_require__(243);
13000 var ArrayEventSource_1 = __webpack_require__(52);
13001 var EventSource_1 = __webpack_require__(6);
13002 var EventSourceParser_1 = __webpack_require__(38);
13003 var SingleEventDef_1 = __webpack_require__(13);
13004 var EventInstanceGroup_1 = __webpack_require__(18);
13005 var EmitterMixin_1 = __webpack_require__(11);
13006 var ListenerMixin_1 = __webpack_require__(7);
13007 var EventManager = /** @class */ (function () {
13008 function EventManager(calendar) {
13009 this.calendar = calendar;
13010 this.stickySource = new ArrayEventSource_1.default(calendar);
13011 this.otherSources = [];
13012 }
13013 EventManager.prototype.requestEvents = function (start, end, timezone, force) {
13014 if (force ||
13015 !this.currentPeriod ||
13016 !this.currentPeriod.isWithinRange(start, end) ||
13017 timezone !== this.currentPeriod.timezone) {
13018 this.setPeriod(// will change this.currentPeriod
13019 new EventPeriod_1.default(start, end, timezone));
13020 }
13021 return this.currentPeriod.whenReleased();
13022 };
13023 // Source Adding/Removing
13024 // -----------------------------------------------------------------------------------------------------------------
13025 EventManager.prototype.addSource = function (eventSource) {
13026 this.otherSources.push(eventSource);
13027 if (this.currentPeriod) {
13028 this.currentPeriod.requestSource(eventSource); // might release
13029 }
13030 };
13031 EventManager.prototype.removeSource = function (doomedSource) {
13032 util_1.removeExact(this.otherSources, doomedSource);
13033 if (this.currentPeriod) {
13034 this.currentPeriod.purgeSource(doomedSource); // might release
13035 }
13036 };
13037 EventManager.prototype.removeAllSources = function () {
13038 this.otherSources = [];
13039 if (this.currentPeriod) {
13040 this.currentPeriod.purgeAllSources(); // might release
13041 }
13042 };
13043 // Source Refetching
13044 // -----------------------------------------------------------------------------------------------------------------
13045 EventManager.prototype.refetchSource = function (eventSource) {
13046 var currentPeriod = this.currentPeriod;
13047 if (currentPeriod) {
13048 currentPeriod.freeze();
13049 currentPeriod.purgeSource(eventSource);
13050 currentPeriod.requestSource(eventSource);
13051 currentPeriod.thaw();
13052 }
13053 };
13054 EventManager.prototype.refetchAllSources = function () {
13055 var currentPeriod = this.currentPeriod;
13056 if (currentPeriod) {
13057 currentPeriod.freeze();
13058 currentPeriod.purgeAllSources();
13059 currentPeriod.requestSources(this.getSources());
13060 currentPeriod.thaw();
13061 }
13062 };
13063 // Source Querying
13064 // -----------------------------------------------------------------------------------------------------------------
13065 EventManager.prototype.getSources = function () {
13066 return [this.stickySource].concat(this.otherSources);
13067 };
13068 // like querySources, but accepts multple match criteria (like multiple IDs)
13069 EventManager.prototype.multiQuerySources = function (matchInputs) {
13070 // coerce into an array
13071 if (!matchInputs) {
13072 matchInputs = [];
13073 }
13074 else if (!$.isArray(matchInputs)) {
13075 matchInputs = [matchInputs];
13076 }
13077 var matchingSources = [];
13078 var i;
13079 // resolve raw inputs to real event source objects
13080 for (i = 0; i < matchInputs.length; i++) {
13081 matchingSources.push.apply(// append
13082 matchingSources, this.querySources(matchInputs[i]));
13083 }
13084 return matchingSources;
13085 };
13086 // matchInput can either by a real event source object, an ID, or the function/URL for the source.
13087 // returns an array of matching source objects.
13088 EventManager.prototype.querySources = function (matchInput) {
13089 var sources = this.otherSources;
13090 var i;
13091 var source;
13092 // given a proper event source object
13093 for (i = 0; i < sources.length; i++) {
13094 source = sources[i];
13095 if (source === matchInput) {
13096 return [source];
13097 }
13098 }
13099 // an ID match
13100 source = this.getSourceById(EventSource_1.default.normalizeId(matchInput));
13101 if (source) {
13102 return [source];
13103 }
13104 // parse as an event source
13105 matchInput = EventSourceParser_1.default.parse(matchInput, this.calendar);
13106 if (matchInput) {
13107 return $.grep(sources, function (source) {
13108 return isSourcesEquivalent(matchInput, source);
13109 });
13110 }
13111 };
13112 /*
13113 ID assumed to already be normalized
13114 */
13115 EventManager.prototype.getSourceById = function (id) {
13116 return $.grep(this.otherSources, function (source) {
13117 return source.id && source.id === id;
13118 })[0];
13119 };
13120 // Event-Period
13121 // -----------------------------------------------------------------------------------------------------------------
13122 EventManager.prototype.setPeriod = function (eventPeriod) {
13123 if (this.currentPeriod) {
13124 this.unbindPeriod(this.currentPeriod);
13125 this.currentPeriod = null;
13126 }
13127 this.currentPeriod = eventPeriod;
13128 this.bindPeriod(eventPeriod);
13129 eventPeriod.requestSources(this.getSources());
13130 };
13131 EventManager.prototype.bindPeriod = function (eventPeriod) {
13132 this.listenTo(eventPeriod, 'release', function (eventsPayload) {
13133 this.trigger('release', eventsPayload);
13134 });
13135 };
13136 EventManager.prototype.unbindPeriod = function (eventPeriod) {
13137 this.stopListeningTo(eventPeriod);
13138 };
13139 // Event Getting/Adding/Removing
13140 // -----------------------------------------------------------------------------------------------------------------
13141 EventManager.prototype.getEventDefByUid = function (uid) {
13142 if (this.currentPeriod) {
13143 return this.currentPeriod.getEventDefByUid(uid);
13144 }
13145 };
13146 EventManager.prototype.addEventDef = function (eventDef, isSticky) {
13147 if (isSticky) {
13148 this.stickySource.addEventDef(eventDef);
13149 }
13150 if (this.currentPeriod) {
13151 this.currentPeriod.addEventDef(eventDef); // might release
13152 }
13153 };
13154 EventManager.prototype.removeEventDefsById = function (eventId) {
13155 this.getSources().forEach(function (eventSource) {
13156 eventSource.removeEventDefsById(eventId);
13157 });
13158 if (this.currentPeriod) {
13159 this.currentPeriod.removeEventDefsById(eventId); // might release
13160 }
13161 };
13162 EventManager.prototype.removeAllEventDefs = function () {
13163 this.getSources().forEach(function (eventSource) {
13164 eventSource.removeAllEventDefs();
13165 });
13166 if (this.currentPeriod) {
13167 this.currentPeriod.removeAllEventDefs();
13168 }
13169 };
13170 // Event Mutating
13171 // -----------------------------------------------------------------------------------------------------------------
13172 /*
13173 Returns an undo function.
13174 */
13175 EventManager.prototype.mutateEventsWithId = function (eventDefId, eventDefMutation) {
13176 var currentPeriod = this.currentPeriod;
13177 var eventDefs;
13178 var undoFuncs = [];
13179 if (currentPeriod) {
13180 currentPeriod.freeze();
13181 eventDefs = currentPeriod.getEventDefsById(eventDefId);
13182 eventDefs.forEach(function (eventDef) {
13183 // add/remove esp because id might change
13184 currentPeriod.removeEventDef(eventDef);
13185 undoFuncs.push(eventDefMutation.mutateSingle(eventDef));
13186 currentPeriod.addEventDef(eventDef);
13187 });
13188 currentPeriod.thaw();
13189 return function () {
13190 currentPeriod.freeze();
13191 for (var i = 0; i < eventDefs.length; i++) {
13192 currentPeriod.removeEventDef(eventDefs[i]);
13193 undoFuncs[i]();
13194 currentPeriod.addEventDef(eventDefs[i]);
13195 }
13196 currentPeriod.thaw();
13197 };
13198 }
13199 return function () { };
13200 };
13201 /*
13202 copies and then mutates
13203 */
13204 EventManager.prototype.buildMutatedEventInstanceGroup = function (eventDefId, eventDefMutation) {
13205 var eventDefs = this.getEventDefsById(eventDefId);
13206 var i;
13207 var defCopy;
13208 var allInstances = [];
13209 for (i = 0; i < eventDefs.length; i++) {
13210 defCopy = eventDefs[i].clone();
13211 if (defCopy instanceof SingleEventDef_1.default) {
13212 eventDefMutation.mutateSingle(defCopy);
13213 allInstances.push.apply(allInstances, // append
13214 defCopy.buildInstances());
13215 }
13216 }
13217 return new EventInstanceGroup_1.default(allInstances);
13218 };
13219 // Freezing
13220 // -----------------------------------------------------------------------------------------------------------------
13221 EventManager.prototype.freeze = function () {
13222 if (this.currentPeriod) {
13223 this.currentPeriod.freeze();
13224 }
13225 };
13226 EventManager.prototype.thaw = function () {
13227 if (this.currentPeriod) {
13228 this.currentPeriod.thaw();
13229 }
13230 };
13231 // methods that simply forward to EventPeriod
13232 EventManager.prototype.getEventDefsById = function (eventDefId) {
13233 return this.currentPeriod.getEventDefsById(eventDefId);
13234 };
13235 EventManager.prototype.getEventInstances = function () {
13236 return this.currentPeriod.getEventInstances();
13237 };
13238 EventManager.prototype.getEventInstancesWithId = function (eventDefId) {
13239 return this.currentPeriod.getEventInstancesWithId(eventDefId);
13240 };
13241 EventManager.prototype.getEventInstancesWithoutId = function (eventDefId) {
13242 return this.currentPeriod.getEventInstancesWithoutId(eventDefId);
13243 };
13244 return EventManager;
13245 }());
13246 exports.default = EventManager;
13247 EmitterMixin_1.default.mixInto(EventManager);
13248 ListenerMixin_1.default.mixInto(EventManager);
13249 function isSourcesEquivalent(source0, source1) {
13250 return source0.getPrimitive() === source1.getPrimitive();
13251 }
13252
13253
13254 /***/ }),
13255 /* 243 */
13256 /***/ (function(module, exports, __webpack_require__) {
13257
13258 Object.defineProperty(exports, "__esModule", { value: true });
13259 var $ = __webpack_require__(3);
13260 var util_1 = __webpack_require__(4);
13261 var Promise_1 = __webpack_require__(20);
13262 var EmitterMixin_1 = __webpack_require__(11);
13263 var UnzonedRange_1 = __webpack_require__(5);
13264 var EventInstanceGroup_1 = __webpack_require__(18);
13265 var EventPeriod = /** @class */ (function () {
13266 function EventPeriod(start, end, timezone) {
13267 this.pendingCnt = 0;
13268 this.freezeDepth = 0;
13269 this.stuntedReleaseCnt = 0;
13270 this.releaseCnt = 0;
13271 this.start = start;
13272 this.end = end;
13273 this.timezone = timezone;
13274 this.unzonedRange = new UnzonedRange_1.default(start.clone().stripZone(), end.clone().stripZone());
13275 this.requestsByUid = {};
13276 this.eventDefsByUid = {};
13277 this.eventDefsById = {};
13278 this.eventInstanceGroupsById = {};
13279 }
13280 EventPeriod.prototype.isWithinRange = function (start, end) {
13281 // TODO: use a range util function?
13282 return !start.isBefore(this.start) && !end.isAfter(this.end);
13283 };
13284 // Requesting and Purging
13285 // -----------------------------------------------------------------------------------------------------------------
13286 EventPeriod.prototype.requestSources = function (sources) {
13287 this.freeze();
13288 for (var i = 0; i < sources.length; i++) {
13289 this.requestSource(sources[i]);
13290 }
13291 this.thaw();
13292 };
13293 EventPeriod.prototype.requestSource = function (source) {
13294 var _this = this;
13295 var request = { source: source, status: 'pending', eventDefs: null };
13296 this.requestsByUid[source.uid] = request;
13297 this.pendingCnt += 1;
13298 source.fetch(this.start, this.end, this.timezone).then(function (eventDefs) {
13299 if (request.status !== 'cancelled') {
13300 request.status = 'completed';
13301 request.eventDefs = eventDefs;
13302 _this.addEventDefs(eventDefs);
13303 _this.pendingCnt--;
13304 _this.tryRelease();
13305 }
13306 }, function () {
13307 if (request.status !== 'cancelled') {
13308 request.status = 'failed';
13309 _this.pendingCnt--;
13310 _this.tryRelease();
13311 }
13312 });
13313 };
13314 EventPeriod.prototype.purgeSource = function (source) {
13315 var request = this.requestsByUid[source.uid];
13316 if (request) {
13317 delete this.requestsByUid[source.uid];
13318 if (request.status === 'pending') {
13319 request.status = 'cancelled';
13320 this.pendingCnt--;
13321 this.tryRelease();
13322 }
13323 else if (request.status === 'completed') {
13324 request.eventDefs.forEach(this.removeEventDef.bind(this));
13325 }
13326 }
13327 };
13328 EventPeriod.prototype.purgeAllSources = function () {
13329 var requestsByUid = this.requestsByUid;
13330 var uid;
13331 var request;
13332 var completedCnt = 0;
13333 for (uid in requestsByUid) {
13334 request = requestsByUid[uid];
13335 if (request.status === 'pending') {
13336 request.status = 'cancelled';
13337 }
13338 else if (request.status === 'completed') {
13339 completedCnt++;
13340 }
13341 }
13342 this.requestsByUid = {};
13343 this.pendingCnt = 0;
13344 if (completedCnt) {
13345 this.removeAllEventDefs(); // might release
13346 }
13347 };
13348 // Event Definitions
13349 // -----------------------------------------------------------------------------------------------------------------
13350 EventPeriod.prototype.getEventDefByUid = function (eventDefUid) {
13351 return this.eventDefsByUid[eventDefUid];
13352 };
13353 EventPeriod.prototype.getEventDefsById = function (eventDefId) {
13354 var a = this.eventDefsById[eventDefId];
13355 if (a) {
13356 return a.slice(); // clone
13357 }
13358 return [];
13359 };
13360 EventPeriod.prototype.addEventDefs = function (eventDefs) {
13361 for (var i = 0; i < eventDefs.length; i++) {
13362 this.addEventDef(eventDefs[i]);
13363 }
13364 };
13365 EventPeriod.prototype.addEventDef = function (eventDef) {
13366 var eventDefsById = this.eventDefsById;
13367 var eventDefId = eventDef.id;
13368 var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []);
13369 var eventInstances = eventDef.buildInstances(this.unzonedRange);
13370 var i;
13371 eventDefs.push(eventDef);
13372 this.eventDefsByUid[eventDef.uid] = eventDef;
13373 for (i = 0; i < eventInstances.length; i++) {
13374 this.addEventInstance(eventInstances[i], eventDefId);
13375 }
13376 };
13377 EventPeriod.prototype.removeEventDefsById = function (eventDefId) {
13378 var _this = this;
13379 this.getEventDefsById(eventDefId).forEach(function (eventDef) {
13380 _this.removeEventDef(eventDef);
13381 });
13382 };
13383 EventPeriod.prototype.removeAllEventDefs = function () {
13384 var isEmpty = $.isEmptyObject(this.eventDefsByUid);
13385 this.eventDefsByUid = {};
13386 this.eventDefsById = {};
13387 this.eventInstanceGroupsById = {};
13388 if (!isEmpty) {
13389 this.tryRelease();
13390 }
13391 };
13392 EventPeriod.prototype.removeEventDef = function (eventDef) {
13393 var eventDefsById = this.eventDefsById;
13394 var eventDefs = eventDefsById[eventDef.id];
13395 delete this.eventDefsByUid[eventDef.uid];
13396 if (eventDefs) {
13397 util_1.removeExact(eventDefs, eventDef);
13398 if (!eventDefs.length) {
13399 delete eventDefsById[eventDef.id];
13400 }
13401 this.removeEventInstancesForDef(eventDef);
13402 }
13403 };
13404 // Event Instances
13405 // -----------------------------------------------------------------------------------------------------------------
13406 EventPeriod.prototype.getEventInstances = function () {
13407 var eventInstanceGroupsById = this.eventInstanceGroupsById;
13408 var eventInstances = [];
13409 var id;
13410 for (id in eventInstanceGroupsById) {
13411 eventInstances.push.apply(eventInstances, // append
13412 eventInstanceGroupsById[id].eventInstances);
13413 }
13414 return eventInstances;
13415 };
13416 EventPeriod.prototype.getEventInstancesWithId = function (eventDefId) {
13417 var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId];
13418 if (eventInstanceGroup) {
13419 return eventInstanceGroup.eventInstances.slice(); // clone
13420 }
13421 return [];
13422 };
13423 EventPeriod.prototype.getEventInstancesWithoutId = function (eventDefId) {
13424 var eventInstanceGroupsById = this.eventInstanceGroupsById;
13425 var matchingInstances = [];
13426 var id;
13427 for (id in eventInstanceGroupsById) {
13428 if (id !== eventDefId) {
13429 matchingInstances.push.apply(matchingInstances, // append
13430 eventInstanceGroupsById[id].eventInstances);
13431 }
13432 }
13433 return matchingInstances;
13434 };
13435 EventPeriod.prototype.addEventInstance = function (eventInstance, eventDefId) {
13436 var eventInstanceGroupsById = this.eventInstanceGroupsById;
13437 var eventInstanceGroup = eventInstanceGroupsById[eventDefId] ||
13438 (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup_1.default());
13439 eventInstanceGroup.eventInstances.push(eventInstance);
13440 this.tryRelease();
13441 };
13442 EventPeriod.prototype.removeEventInstancesForDef = function (eventDef) {
13443 var eventInstanceGroupsById = this.eventInstanceGroupsById;
13444 var eventInstanceGroup = eventInstanceGroupsById[eventDef.id];
13445 var removeCnt;
13446 if (eventInstanceGroup) {
13447 removeCnt = util_1.removeMatching(eventInstanceGroup.eventInstances, function (currentEventInstance) {
13448 return currentEventInstance.def === eventDef;
13449 });
13450 if (!eventInstanceGroup.eventInstances.length) {
13451 delete eventInstanceGroupsById[eventDef.id];
13452 }
13453 if (removeCnt) {
13454 this.tryRelease();
13455 }
13456 }
13457 };
13458 // Releasing and Freezing
13459 // -----------------------------------------------------------------------------------------------------------------
13460 EventPeriod.prototype.tryRelease = function () {
13461 if (!this.pendingCnt) {
13462 if (!this.freezeDepth) {
13463 this.release();
13464 }
13465 else {
13466 this.stuntedReleaseCnt++;
13467 }
13468 }
13469 };
13470 EventPeriod.prototype.release = function () {
13471 this.releaseCnt++;
13472 this.trigger('release', this.eventInstanceGroupsById);
13473 };
13474 EventPeriod.prototype.whenReleased = function () {
13475 var _this = this;
13476 if (this.releaseCnt) {
13477 return Promise_1.default.resolve(this.eventInstanceGroupsById);
13478 }
13479 else {
13480 return Promise_1.default.construct(function (onResolve) {
13481 _this.one('release', onResolve);
13482 });
13483 }
13484 };
13485 EventPeriod.prototype.freeze = function () {
13486 if (!(this.freezeDepth++)) {
13487 this.stuntedReleaseCnt = 0;
13488 }
13489 };
13490 EventPeriod.prototype.thaw = function () {
13491 if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) {
13492 this.release();
13493 }
13494 };
13495 return EventPeriod;
13496 }());
13497 exports.default = EventPeriod;
13498 EmitterMixin_1.default.mixInto(EventPeriod);
13499
13500
13501 /***/ }),
13502 /* 244 */
13503 /***/ (function(module, exports, __webpack_require__) {
13504
13505 Object.defineProperty(exports, "__esModule", { value: true });
13506 var $ = __webpack_require__(3);
13507 var util_1 = __webpack_require__(4);
13508 var ListenerMixin_1 = __webpack_require__(7);
13509 /* Creates a clone of an element and lets it track the mouse as it moves
13510 ----------------------------------------------------------------------------------------------------------------------*/
13511 var MouseFollower = /** @class */ (function () {
13512 function MouseFollower(sourceEl, options) {
13513 this.isFollowing = false;
13514 this.isHidden = false;
13515 this.isAnimating = false; // doing the revert animation?
13516 this.options = options = options || {};
13517 this.sourceEl = sourceEl;
13518 this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent
13519 }
13520 // Causes the element to start following the mouse
13521 MouseFollower.prototype.start = function (ev) {
13522 if (!this.isFollowing) {
13523 this.isFollowing = true;
13524 this.y0 = util_1.getEvY(ev);
13525 this.x0 = util_1.getEvX(ev);
13526 this.topDelta = 0;
13527 this.leftDelta = 0;
13528 if (!this.isHidden) {
13529 this.updatePosition();
13530 }
13531 if (util_1.getEvIsTouch(ev)) {
13532 this.listenTo($(document), 'touchmove', this.handleMove);
13533 }
13534 else {
13535 this.listenTo($(document), 'mousemove', this.handleMove);
13536 }
13537 }
13538 };
13539 // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
13540 // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.
13541 MouseFollower.prototype.stop = function (shouldRevert, callback) {
13542 var _this = this;
13543 var revertDuration = this.options.revertDuration;
13544 var complete = function () {
13545 _this.isAnimating = false;
13546 _this.removeElement();
13547 _this.top0 = _this.left0 = null; // reset state for future updatePosition calls
13548 if (callback) {
13549 callback();
13550 }
13551 };
13552 if (this.isFollowing && !this.isAnimating) {
13553 this.isFollowing = false;
13554 this.stopListeningTo($(document));
13555 if (shouldRevert && revertDuration && !this.isHidden) {
13556 this.isAnimating = true;
13557 this.el.animate({
13558 top: this.top0,
13559 left: this.left0
13560 }, {
13561 duration: revertDuration,
13562 complete: complete
13563 });
13564 }
13565 else {
13566 complete();
13567 }
13568 }
13569 };
13570 // Gets the tracking element. Create it if necessary
13571 MouseFollower.prototype.getEl = function () {
13572 var el = this.el;
13573 if (!el) {
13574 el = this.el = this.sourceEl.clone()
13575 .addClass(this.options.additionalClass || '')
13576 .css({
13577 position: 'absolute',
13578 visibility: '',
13579 display: this.isHidden ? 'none' : '',
13580 margin: 0,
13581 right: 'auto',
13582 bottom: 'auto',
13583 width: this.sourceEl.width(),
13584 height: this.sourceEl.height(),
13585 opacity: this.options.opacity || '',
13586 zIndex: this.options.zIndex
13587 });
13588 // we don't want long taps or any mouse interaction causing selection/menus.
13589 // would use preventSelection(), but that prevents selectstart, causing problems.
13590 el.addClass('fc-unselectable');
13591 el.appendTo(this.parentEl);
13592 }
13593 return el;
13594 };
13595 // Removes the tracking element if it has already been created
13596 MouseFollower.prototype.removeElement = function () {
13597 if (this.el) {
13598 this.el.remove();
13599 this.el = null;
13600 }
13601 };
13602 // Update the CSS position of the tracking element
13603 MouseFollower.prototype.updatePosition = function () {
13604 var sourceOffset;
13605 var origin;
13606 this.getEl(); // ensure this.el
13607 // make sure origin info was computed
13608 if (this.top0 == null) {
13609 sourceOffset = this.sourceEl.offset();
13610 origin = this.el.offsetParent().offset();
13611 this.top0 = sourceOffset.top - origin.top;
13612 this.left0 = sourceOffset.left - origin.left;
13613 }
13614 this.el.css({
13615 top: this.top0 + this.topDelta,
13616 left: this.left0 + this.leftDelta
13617 });
13618 };
13619 // Gets called when the user moves the mouse
13620 MouseFollower.prototype.handleMove = function (ev) {
13621 this.topDelta = util_1.getEvY(ev) - this.y0;
13622 this.leftDelta = util_1.getEvX(ev) - this.x0;
13623 if (!this.isHidden) {
13624 this.updatePosition();
13625 }
13626 };
13627 // Temporarily makes the tracking element invisible. Can be called before following starts
13628 MouseFollower.prototype.hide = function () {
13629 if (!this.isHidden) {
13630 this.isHidden = true;
13631 if (this.el) {
13632 this.el.hide();
13633 }
13634 }
13635 };
13636 // Show the tracking element after it has been temporarily hidden
13637 MouseFollower.prototype.show = function () {
13638 if (this.isHidden) {
13639 this.isHidden = false;
13640 this.updatePosition();
13641 this.getEl().show();
13642 }
13643 };
13644 return MouseFollower;
13645 }());
13646 exports.default = MouseFollower;
13647 ListenerMixin_1.default.mixInto(MouseFollower);
13648
13649
13650 /***/ }),
13651 /* 245 */
13652 /***/ (function(module, exports, __webpack_require__) {
13653
13654 Object.defineProperty(exports, "__esModule", { value: true });
13655 var tslib_1 = __webpack_require__(2);
13656 var HitDragListener_1 = __webpack_require__(23);
13657 var Interaction_1 = __webpack_require__(15);
13658 var DateClicking = /** @class */ (function (_super) {
13659 tslib_1.__extends(DateClicking, _super);
13660 /*
13661 component must implement:
13662 - bindDateHandlerToEl
13663 - getSafeHitFootprint
13664 - getHitEl
13665 */
13666 function DateClicking(component) {
13667 var _this = _super.call(this, component) || this;
13668 _this.dragListener = _this.buildDragListener();
13669 return _this;
13670 }
13671 DateClicking.prototype.end = function () {
13672 this.dragListener.endInteraction();
13673 };
13674 DateClicking.prototype.bindToEl = function (el) {
13675 var component = this.component;
13676 var dragListener = this.dragListener;
13677 component.bindDateHandlerToEl(el, 'mousedown', function (ev) {
13678 if (!component.shouldIgnoreMouse()) {
13679 dragListener.startInteraction(ev);
13680 }
13681 });
13682 component.bindDateHandlerToEl(el, 'touchstart', function (ev) {
13683 if (!component.shouldIgnoreTouch()) {
13684 dragListener.startInteraction(ev);
13685 }
13686 });
13687 };
13688 // Creates a listener that tracks the user's drag across day elements, for day clicking.
13689 DateClicking.prototype.buildDragListener = function () {
13690 var _this = this;
13691 var component = this.component;
13692 var dayClickHit; // null if invalid dayClick
13693 var dragListener = new HitDragListener_1.default(component, {
13694 scroll: this.opt('dragScroll'),
13695 interactionStart: function () {
13696 dayClickHit = dragListener.origHit;
13697 },
13698 hitOver: function (hit, isOrig, origHit) {
13699 // if user dragged to another cell at any point, it can no longer be a dayClick
13700 if (!isOrig) {
13701 dayClickHit = null;
13702 }
13703 },
13704 hitOut: function () {
13705 dayClickHit = null;
13706 },
13707 interactionEnd: function (ev, isCancelled) {
13708 var componentFootprint;
13709 if (!isCancelled && dayClickHit) {
13710 componentFootprint = component.getSafeHitFootprint(dayClickHit);
13711 if (componentFootprint) {
13712 _this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev);
13713 }
13714 }
13715 }
13716 });
13717 // because dragListener won't be called with any time delay, "dragging" will begin immediately,
13718 // which will kill any touchmoving/scrolling. Prevent this.
13719 dragListener.shouldCancelTouchScroll = false;
13720 dragListener.scrollAlwaysKills = true;
13721 return dragListener;
13722 };
13723 return DateClicking;
13724 }(Interaction_1.default));
13725 exports.default = DateClicking;
13726
13727
13728 /***/ }),
13729 /* 246 */
13730 /***/ (function(module, exports, __webpack_require__) {
13731
13732 Object.defineProperty(exports, "__esModule", { value: true });
13733 var tslib_1 = __webpack_require__(2);
13734 var util_1 = __webpack_require__(4);
13735 var EventRenderer_1 = __webpack_require__(42);
13736 /*
13737 Only handles foreground segs.
13738 Does not own rendering. Use for low-level util methods by TimeGrid.
13739 */
13740 var TimeGridEventRenderer = /** @class */ (function (_super) {
13741 tslib_1.__extends(TimeGridEventRenderer, _super);
13742 function TimeGridEventRenderer(timeGrid, fillRenderer) {
13743 var _this = _super.call(this, timeGrid, fillRenderer) || this;
13744 _this.timeGrid = timeGrid;
13745 return _this;
13746 }
13747 TimeGridEventRenderer.prototype.renderFgSegs = function (segs) {
13748 this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls);
13749 };
13750 // Given an array of foreground segments, render a DOM element for each, computes position,
13751 // and attaches to the column inner-container elements.
13752 TimeGridEventRenderer.prototype.renderFgSegsIntoContainers = function (segs, containerEls) {
13753 var segsByCol;
13754 var col;
13755 segsByCol = this.timeGrid.groupSegsByCol(segs);
13756 for (col = 0; col < this.timeGrid.colCnt; col++) {
13757 this.updateFgSegCoords(segsByCol[col]);
13758 }
13759 this.timeGrid.attachSegsByCol(segsByCol, containerEls);
13760 };
13761 TimeGridEventRenderer.prototype.unrenderFgSegs = function () {
13762 if (this.fgSegs) {
13763 this.fgSegs.forEach(function (seg) {
13764 seg.el.remove();
13765 });
13766 }
13767 };
13768 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
13769 TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
13770 return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM)
13771 };
13772 // Computes a default `displayEventEnd` value if one is not expliclty defined
13773 TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
13774 return true;
13775 };
13776 // Renders the HTML for a single event segment's default rendering
13777 TimeGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
13778 var view = this.view;
13779 var calendar = view.calendar;
13780 var componentFootprint = seg.footprint.componentFootprint;
13781 var isAllDay = componentFootprint.isAllDay;
13782 var eventDef = seg.footprint.eventDef;
13783 var isDraggable = view.isEventDefDraggable(eventDef);
13784 var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef);
13785 var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
13786 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
13787 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef));
13788 var timeText;
13789 var fullTimeText; // more verbose time text. for the print stylesheet
13790 var startTimeText; // just the start time text
13791 classes.unshift('fc-time-grid-event', 'fc-v-event');
13792 // if the event appears to span more than one day...
13793 if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
13794 // Don't display time text on segments that run entirely through a day.
13795 // That would appear as midnight-midnight and would look dumb.
13796 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
13797 if (seg.isStart || seg.isEnd) {
13798 var zonedStart = calendar.msToMoment(seg.startMs);
13799 var zonedEnd = calendar.msToMoment(seg.endMs);
13800 timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay);
13801 fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT');
13802 startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false
13803 }
13804 }
13805 else {
13806 // Display the normal time text for the *event's* times
13807 timeText = this.getTimeText(seg.footprint);
13808 fullTimeText = this.getTimeText(seg.footprint, 'LT');
13809 startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false
13810 }
13811 return '<a class="' + classes.join(' ') + '"' +
13812 (eventDef.url ?
13813 ' href="' + util_1.htmlEscape(eventDef.url) + '"' :
13814 '') +
13815 (skinCss ?
13816 ' style="' + skinCss + '"' :
13817 '') +
13818 '>' +
13819 '<div class="fc-content">' +
13820 (timeText ?
13821 '<div class="fc-time"' +
13822 ' data-start="' + util_1.htmlEscape(startTimeText) + '"' +
13823 ' data-full="' + util_1.htmlEscape(fullTimeText) + '"' +
13824 '>' +
13825 '<span>' + util_1.htmlEscape(timeText) + '</span>' +
13826 '</div>' :
13827 '') +
13828 (eventDef.title ?
13829 '<div class="fc-title">' +
13830 util_1.htmlEscape(eventDef.title) +
13831 '</div>' :
13832 '') +
13833 '</div>' +
13834 '<div class="fc-bg"/>' +
13835 /* TODO: write CSS for this
13836 (isResizableFromStart ?
13837 '<div class="fc-resizer fc-start-resizer" />' :
13838 ''
13839 ) +
13840 */
13841 (isResizableFromEnd ?
13842 '<div class="fc-resizer fc-end-resizer" />' :
13843 '') +
13844 '</a>';
13845 };
13846 // Given segments that are assumed to all live in the *same column*,
13847 // compute their verical/horizontal coordinates and assign to their elements.
13848 TimeGridEventRenderer.prototype.updateFgSegCoords = function (segs) {
13849 this.timeGrid.computeSegVerticals(segs); // horizontals relies on this
13850 this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array
13851 this.timeGrid.assignSegVerticals(segs);
13852 this.assignFgSegHorizontals(segs);
13853 };
13854 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
13855 // NOTE: Also reorders the given array by date!
13856 TimeGridEventRenderer.prototype.computeFgSegHorizontals = function (segs) {
13857 var levels;
13858 var level0;
13859 var i;
13860 this.sortEventSegs(segs); // order by certain criteria
13861 levels = buildSlotSegLevels(segs);
13862 computeForwardSlotSegs(levels);
13863 if ((level0 = levels[0])) {
13864 for (i = 0; i < level0.length; i++) {
13865 computeSlotSegPressures(level0[i]);
13866 }
13867 for (i = 0; i < level0.length; i++) {
13868 this.computeFgSegForwardBack(level0[i], 0, 0);
13869 }
13870 }
13871 };
13872 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
13873 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
13874 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
13875 //
13876 // The segment might be part of a "series", which means consecutive segments with the same pressure
13877 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
13878 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
13879 // coordinate of the first segment in the series.
13880 TimeGridEventRenderer.prototype.computeFgSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
13881 var forwardSegs = seg.forwardSegs;
13882 var i;
13883 if (seg.forwardCoord === undefined) {
13884 if (!forwardSegs.length) {
13885 // if there are no forward segments, this segment should butt up against the edge
13886 seg.forwardCoord = 1;
13887 }
13888 else {
13889 // sort highest pressure first
13890 this.sortForwardSegs(forwardSegs);
13891 // this segment's forwardCoord will be calculated from the backwardCoord of the
13892 // highest-pressure forward segment.
13893 this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
13894 seg.forwardCoord = forwardSegs[0].backwardCoord;
13895 }
13896 // calculate the backwardCoord from the forwardCoord. consider the series
13897 seg.backwardCoord = seg.forwardCoord -
13898 (seg.forwardCoord - seriesBackwardCoord) / // available width for series
13899 (seriesBackwardPressure + 1); // # of segments in the series
13900 // use this segment's coordinates to computed the coordinates of the less-pressurized
13901 // forward segments
13902 for (i = 0; i < forwardSegs.length; i++) {
13903 this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
13904 }
13905 }
13906 };
13907 TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
13908 forwardSegs.sort(util_1.proxy(this, 'compareForwardSegs'));
13909 };
13910 // A cmp function for determining which forward segment to rely on more when computing coordinates.
13911 TimeGridEventRenderer.prototype.compareForwardSegs = function (seg1, seg2) {
13912 // put higher-pressure first
13913 return seg2.forwardPressure - seg1.forwardPressure ||
13914 // put segments that are closer to initial edge first (and favor ones with no coords yet)
13915 (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
13916 // do normal sorting...
13917 this.compareEventSegs(seg1, seg2);
13918 };
13919 // Given foreground event segments that have already had their position coordinates computed,
13920 // assigns position-related CSS values to their elements.
13921 TimeGridEventRenderer.prototype.assignFgSegHorizontals = function (segs) {
13922 var i;
13923 var seg;
13924 for (i = 0; i < segs.length; i++) {
13925 seg = segs[i];
13926 seg.el.css(this.generateFgSegHorizontalCss(seg));
13927 // if the height is short, add a className for alternate styling
13928 if (seg.bottom - seg.top < 30) {
13929 seg.el.addClass('fc-short');
13930 }
13931 }
13932 };
13933 // Generates an object with CSS properties/values that should be applied to an event segment element.
13934 // Contains important positioning-related properties that should be applied to any event element, customized or not.
13935 TimeGridEventRenderer.prototype.generateFgSegHorizontalCss = function (seg) {
13936 var shouldOverlap = this.opt('slotEventOverlap');
13937 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
13938 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
13939 var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
13940 var isRTL = this.timeGrid.isRTL;
13941 var left; // amount of space from left edge, a fraction of the total width
13942 var right; // amount of space from right edge, a fraction of the total width
13943 if (shouldOverlap) {
13944 // double the width, but don't go beyond the maximum forward coordinate (1.0)
13945 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
13946 }
13947 if (isRTL) {
13948 left = 1 - forwardCoord;
13949 right = backwardCoord;
13950 }
13951 else {
13952 left = backwardCoord;
13953 right = 1 - forwardCoord;
13954 }
13955 props.zIndex = seg.level + 1; // convert from 0-base to 1-based
13956 props.left = left * 100 + '%';
13957 props.right = right * 100 + '%';
13958 if (shouldOverlap && seg.forwardPressure) {
13959 // add padding to the edge so that forward stacked events don't cover the resizer's icon
13960 props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
13961 }
13962 return props;
13963 };
13964 return TimeGridEventRenderer;
13965 }(EventRenderer_1.default));
13966 exports.default = TimeGridEventRenderer;
13967 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
13968 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
13969 function buildSlotSegLevels(segs) {
13970 var levels = [];
13971 var i;
13972 var seg;
13973 var j;
13974 for (i = 0; i < segs.length; i++) {
13975 seg = segs[i];
13976 // go through all the levels and stop on the first level where there are no collisions
13977 for (j = 0; j < levels.length; j++) {
13978 if (!computeSlotSegCollisions(seg, levels[j]).length) {
13979 break;
13980 }
13981 }
13982 seg.level = j;
13983 (levels[j] || (levels[j] = [])).push(seg);
13984 }
13985 return levels;
13986 }
13987 // For every segment, figure out the other segments that are in subsequent
13988 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
13989 function computeForwardSlotSegs(levels) {
13990 var i;
13991 var level;
13992 var j;
13993 var seg;
13994 var k;
13995 for (i = 0; i < levels.length; i++) {
13996 level = levels[i];
13997 for (j = 0; j < level.length; j++) {
13998 seg = level[j];
13999 seg.forwardSegs = [];
14000 for (k = i + 1; k < levels.length; k++) {
14001 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
14002 }
14003 }
14004 }
14005 }
14006 // Figure out which path forward (via seg.forwardSegs) results in the longest path until
14007 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
14008 function computeSlotSegPressures(seg) {
14009 var forwardSegs = seg.forwardSegs;
14010 var forwardPressure = 0;
14011 var i;
14012 var forwardSeg;
14013 if (seg.forwardPressure === undefined) {
14014 for (i = 0; i < forwardSegs.length; i++) {
14015 forwardSeg = forwardSegs[i];
14016 // figure out the child's maximum forward path
14017 computeSlotSegPressures(forwardSeg);
14018 // either use the existing maximum, or use the child's forward pressure
14019 // plus one (for the forwardSeg itself)
14020 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
14021 }
14022 seg.forwardPressure = forwardPressure;
14023 }
14024 }
14025 // Find all the segments in `otherSegs` that vertically collide with `seg`.
14026 // Append into an optionally-supplied `results` array and return.
14027 function computeSlotSegCollisions(seg, otherSegs, results) {
14028 if (results === void 0) { results = []; }
14029 for (var i = 0; i < otherSegs.length; i++) {
14030 if (isSlotSegCollision(seg, otherSegs[i])) {
14031 results.push(otherSegs[i]);
14032 }
14033 }
14034 return results;
14035 }
14036 // Do these segments occupy the same vertical space?
14037 function isSlotSegCollision(seg1, seg2) {
14038 return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
14039 }
14040
14041
14042 /***/ }),
14043 /* 247 */
14044 /***/ (function(module, exports, __webpack_require__) {
14045
14046 Object.defineProperty(exports, "__esModule", { value: true });
14047 var tslib_1 = __webpack_require__(2);
14048 var $ = __webpack_require__(3);
14049 var HelperRenderer_1 = __webpack_require__(58);
14050 var TimeGridHelperRenderer = /** @class */ (function (_super) {
14051 tslib_1.__extends(TimeGridHelperRenderer, _super);
14052 function TimeGridHelperRenderer() {
14053 return _super !== null && _super.apply(this, arguments) || this;
14054 }
14055 TimeGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
14056 var helperNodes = [];
14057 var i;
14058 var seg;
14059 var sourceEl;
14060 // TODO: not good to call eventRenderer this way
14061 this.eventRenderer.renderFgSegsIntoContainers(segs, this.component.helperContainerEls);
14062 // Try to make the segment that is in the same row as sourceSeg look the same
14063 for (i = 0; i < segs.length; i++) {
14064 seg = segs[i];
14065 if (sourceSeg && sourceSeg.col === seg.col) {
14066 sourceEl = sourceSeg.el;
14067 seg.el.css({
14068 left: sourceEl.css('left'),
14069 right: sourceEl.css('right'),
14070 'margin-left': sourceEl.css('margin-left'),
14071 'margin-right': sourceEl.css('margin-right')
14072 });
14073 }
14074 helperNodes.push(seg.el[0]);
14075 }
14076 return $(helperNodes); // must return the elements rendered
14077 };
14078 return TimeGridHelperRenderer;
14079 }(HelperRenderer_1.default));
14080 exports.default = TimeGridHelperRenderer;
14081
14082
14083 /***/ }),
14084 /* 248 */
14085 /***/ (function(module, exports, __webpack_require__) {
14086
14087 Object.defineProperty(exports, "__esModule", { value: true });
14088 var tslib_1 = __webpack_require__(2);
14089 var FillRenderer_1 = __webpack_require__(57);
14090 var TimeGridFillRenderer = /** @class */ (function (_super) {
14091 tslib_1.__extends(TimeGridFillRenderer, _super);
14092 function TimeGridFillRenderer() {
14093 return _super !== null && _super.apply(this, arguments) || this;
14094 }
14095 TimeGridFillRenderer.prototype.attachSegEls = function (type, segs) {
14096 var timeGrid = this.component;
14097 var containerEls;
14098 // TODO: more efficient lookup
14099 if (type === 'bgEvent') {
14100 containerEls = timeGrid.bgContainerEls;
14101 }
14102 else if (type === 'businessHours') {
14103 containerEls = timeGrid.businessContainerEls;
14104 }
14105 else if (type === 'highlight') {
14106 containerEls = timeGrid.highlightContainerEls;
14107 }
14108 timeGrid.updateSegVerticals(segs);
14109 timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
14110 return segs.map(function (seg) {
14111 return seg.el[0];
14112 });
14113 };
14114 return TimeGridFillRenderer;
14115 }(FillRenderer_1.default));
14116 exports.default = TimeGridFillRenderer;
14117
14118
14119 /***/ }),
14120 /* 249 */
14121 /***/ (function(module, exports, __webpack_require__) {
14122
14123 /* A rectangular panel that is absolutely positioned over other content
14124 ------------------------------------------------------------------------------------------------------------------------
14125 Options:
14126 - className (string)
14127 - content (HTML string or jQuery element set)
14128 - parentEl
14129 - top
14130 - left
14131 - right (the x coord of where the right edge should be. not a "CSS" right)
14132 - autoHide (boolean)
14133 - show (callback)
14134 - hide (callback)
14135 */
14136 Object.defineProperty(exports, "__esModule", { value: true });
14137 var $ = __webpack_require__(3);
14138 var util_1 = __webpack_require__(4);
14139 var ListenerMixin_1 = __webpack_require__(7);
14140 var Popover = /** @class */ (function () {
14141 function Popover(options) {
14142 this.isHidden = true;
14143 this.margin = 10; // the space required between the popover and the edges of the scroll container
14144 this.options = options || {};
14145 }
14146 // Shows the popover on the specified position. Renders it if not already
14147 Popover.prototype.show = function () {
14148 if (this.isHidden) {
14149 if (!this.el) {
14150 this.render();
14151 }
14152 this.el.show();
14153 this.position();
14154 this.isHidden = false;
14155 this.trigger('show');
14156 }
14157 };
14158 // Hides the popover, through CSS, but does not remove it from the DOM
14159 Popover.prototype.hide = function () {
14160 if (!this.isHidden) {
14161 this.el.hide();
14162 this.isHidden = true;
14163 this.trigger('hide');
14164 }
14165 };
14166 // Creates `this.el` and renders content inside of it
14167 Popover.prototype.render = function () {
14168 var _this = this;
14169 var options = this.options;
14170 this.el = $('<div class="fc-popover"/>')
14171 .addClass(options.className || '')
14172 .css({
14173 // position initially to the top left to avoid creating scrollbars
14174 top: 0,
14175 left: 0
14176 })
14177 .append(options.content)
14178 .appendTo(options.parentEl);
14179 // when a click happens on anything inside with a 'fc-close' className, hide the popover
14180 this.el.on('click', '.fc-close', function () {
14181 _this.hide();
14182 });
14183 if (options.autoHide) {
14184 this.listenTo($(document), 'mousedown', this.documentMousedown);
14185 }
14186 };
14187 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
14188 Popover.prototype.documentMousedown = function (ev) {
14189 // only hide the popover if the click happened outside the popover
14190 if (this.el && !$(ev.target).closest(this.el).length) {
14191 this.hide();
14192 }
14193 };
14194 // Hides and unregisters any handlers
14195 Popover.prototype.removeElement = function () {
14196 this.hide();
14197 if (this.el) {
14198 this.el.remove();
14199 this.el = null;
14200 }
14201 this.stopListeningTo($(document), 'mousedown');
14202 };
14203 // Positions the popover optimally, using the top/left/right options
14204 Popover.prototype.position = function () {
14205 var options = this.options;
14206 var origin = this.el.offsetParent().offset();
14207 var width = this.el.outerWidth();
14208 var height = this.el.outerHeight();
14209 var windowEl = $(window);
14210 var viewportEl = util_1.getScrollParent(this.el);
14211 var viewportTop;
14212 var viewportLeft;
14213 var viewportOffset;
14214 var top; // the "position" (not "offset") values for the popover
14215 var left; //
14216 // compute top and left
14217 top = options.top || 0;
14218 if (options.left !== undefined) {
14219 left = options.left;
14220 }
14221 else if (options.right !== undefined) {
14222 left = options.right - width; // derive the left value from the right value
14223 }
14224 else {
14225 left = 0;
14226 }
14227 if (viewportEl.is(window) || viewportEl.is(document)) {
14228 viewportEl = windowEl;
14229 viewportTop = 0; // the window is always at the top left
14230 viewportLeft = 0; // (and .offset() won't work if called here)
14231 }
14232 else {
14233 viewportOffset = viewportEl.offset();
14234 viewportTop = viewportOffset.top;
14235 viewportLeft = viewportOffset.left;
14236 }
14237 // if the window is scrolled, it causes the visible area to be further down
14238 viewportTop += windowEl.scrollTop();
14239 viewportLeft += windowEl.scrollLeft();
14240 // constrain to the view port. if constrained by two edges, give precedence to top/left
14241 if (options.viewportConstrain !== false) {
14242 top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);
14243 top = Math.max(top, viewportTop + this.margin);
14244 left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);
14245 left = Math.max(left, viewportLeft + this.margin);
14246 }
14247 this.el.css({
14248 top: top - origin.top,
14249 left: left - origin.left
14250 });
14251 };
14252 // Triggers a callback. Calls a function in the option hash of the same name.
14253 // Arguments beyond the first `name` are forwarded on.
14254 // TODO: better code reuse for this. Repeat code
14255 Popover.prototype.trigger = function (name) {
14256 if (this.options[name]) {
14257 this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
14258 }
14259 };
14260 return Popover;
14261 }());
14262 exports.default = Popover;
14263 ListenerMixin_1.default.mixInto(Popover);
14264
14265
14266 /***/ }),
14267 /* 250 */
14268 /***/ (function(module, exports, __webpack_require__) {
14269
14270 Object.defineProperty(exports, "__esModule", { value: true });
14271 var tslib_1 = __webpack_require__(2);
14272 var $ = __webpack_require__(3);
14273 var util_1 = __webpack_require__(4);
14274 var EventRenderer_1 = __webpack_require__(42);
14275 /* Event-rendering methods for the DayGrid class
14276 ----------------------------------------------------------------------------------------------------------------------*/
14277 var DayGridEventRenderer = /** @class */ (function (_super) {
14278 tslib_1.__extends(DayGridEventRenderer, _super);
14279 function DayGridEventRenderer(dayGrid, fillRenderer) {
14280 var _this = _super.call(this, dayGrid, fillRenderer) || this;
14281 _this.dayGrid = dayGrid;
14282 return _this;
14283 }
14284 DayGridEventRenderer.prototype.renderBgRanges = function (eventRanges) {
14285 // don't render timed background events
14286 eventRanges = $.grep(eventRanges, function (eventRange) {
14287 return eventRange.eventDef.isAllDay();
14288 });
14289 _super.prototype.renderBgRanges.call(this, eventRanges);
14290 };
14291 // Renders the given foreground event segments onto the grid
14292 DayGridEventRenderer.prototype.renderFgSegs = function (segs) {
14293 var rowStructs = this.rowStructs = this.renderSegRows(segs);
14294 // append to each row's content skeleton
14295 this.dayGrid.rowEls.each(function (i, rowNode) {
14296 $(rowNode).find('.fc-content-skeleton > table').append(rowStructs[i].tbodyEl);
14297 });
14298 };
14299 // Unrenders all currently rendered foreground event segments
14300 DayGridEventRenderer.prototype.unrenderFgSegs = function () {
14301 var rowStructs = this.rowStructs || [];
14302 var rowStruct;
14303 while ((rowStruct = rowStructs.pop())) {
14304 rowStruct.tbodyEl.remove();
14305 }
14306 this.rowStructs = null;
14307 };
14308 // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
14309 // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
14310 // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
14311 DayGridEventRenderer.prototype.renderSegRows = function (segs) {
14312 var rowStructs = [];
14313 var segRows;
14314 var row;
14315 segRows = this.groupSegRows(segs); // group into nested arrays
14316 // iterate each row of segment groupings
14317 for (row = 0; row < segRows.length; row++) {
14318 rowStructs.push(this.renderSegRow(row, segRows[row]));
14319 }
14320 return rowStructs;
14321 };
14322 // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
14323 // the segments. Returns object with a bunch of internal data about how the render was calculated.
14324 // NOTE: modifies rowSegs
14325 DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
14326 var colCnt = this.dayGrid.colCnt;
14327 var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
14328 var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
14329 var tbody = $('<tbody/>');
14330 var segMatrix = []; // lookup for which segments are rendered into which level+col cells
14331 var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
14332 var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
14333 var i;
14334 var levelSegs;
14335 var col;
14336 var tr;
14337 var j;
14338 var seg;
14339 var td;
14340 // populates empty cells from the current column (`col`) to `endCol`
14341 function emptyCellsUntil(endCol) {
14342 while (col < endCol) {
14343 // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
14344 td = (loneCellMatrix[i - 1] || [])[col];
14345 if (td) {
14346 td.attr('rowspan', parseInt(td.attr('rowspan') || 1, 10) + 1);
14347 }
14348 else {
14349 td = $('<td/>');
14350 tr.append(td);
14351 }
14352 cellMatrix[i][col] = td;
14353 loneCellMatrix[i][col] = td;
14354 col++;
14355 }
14356 }
14357 for (i = 0; i < levelCnt; i++) {
14358 levelSegs = segLevels[i];
14359 col = 0;
14360 tr = $('<tr/>');
14361 segMatrix.push([]);
14362 cellMatrix.push([]);
14363 loneCellMatrix.push([]);
14364 // levelCnt might be 1 even though there are no actual levels. protect against this.
14365 // this single empty row is useful for styling.
14366 if (levelSegs) {
14367 for (j = 0; j < levelSegs.length; j++) {
14368 seg = levelSegs[j];
14369 emptyCellsUntil(seg.leftCol);
14370 // create a container that occupies or more columns. append the event element.
14371 td = $('<td class="fc-event-container"/>').append(seg.el);
14372 if (seg.leftCol !== seg.rightCol) {
14373 td.attr('colspan', seg.rightCol - seg.leftCol + 1);
14374 }
14375 else {
14376 loneCellMatrix[i][col] = td;
14377 }
14378 while (col <= seg.rightCol) {
14379 cellMatrix[i][col] = td;
14380 segMatrix[i][col] = seg;
14381 col++;
14382 }
14383 tr.append(td);
14384 }
14385 }
14386 emptyCellsUntil(colCnt); // finish off the row
14387 this.dayGrid.bookendCells(tr);
14388 tbody.append(tr);
14389 }
14390 return {
14391 row: row,
14392 tbodyEl: tbody,
14393 cellMatrix: cellMatrix,
14394 segMatrix: segMatrix,
14395 segLevels: segLevels,
14396 segs: rowSegs
14397 };
14398 };
14399 // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
14400 // NOTE: modifies segs
14401 DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
14402 var levels = [];
14403 var i;
14404 var seg;
14405 var j;
14406 // Give preference to elements with certain criteria, so they have
14407 // a chance to be closer to the top.
14408 this.sortEventSegs(segs);
14409 for (i = 0; i < segs.length; i++) {
14410 seg = segs[i];
14411 // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
14412 for (j = 0; j < levels.length; j++) {
14413 if (!isDaySegCollision(seg, levels[j])) {
14414 break;
14415 }
14416 }
14417 // `j` now holds the desired subrow index
14418 seg.level = j;
14419 // create new level array if needed and append segment
14420 (levels[j] || (levels[j] = [])).push(seg);
14421 }
14422 // order segments left-to-right. very important if calendar is RTL
14423 for (j = 0; j < levels.length; j++) {
14424 levels[j].sort(compareDaySegCols);
14425 }
14426 return levels;
14427 };
14428 // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
14429 DayGridEventRenderer.prototype.groupSegRows = function (segs) {
14430 var segRows = [];
14431 var i;
14432 for (i = 0; i < this.dayGrid.rowCnt; i++) {
14433 segRows.push([]);
14434 }
14435 for (i = 0; i < segs.length; i++) {
14436 segRows[segs[i].row].push(segs[i]);
14437 }
14438 return segRows;
14439 };
14440 // Computes a default event time formatting string if `timeFormat` is not explicitly defined
14441 DayGridEventRenderer.prototype.computeEventTimeFormat = function () {
14442 return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p"
14443 };
14444 // Computes a default `displayEventEnd` value if one is not expliclty defined
14445 DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
14446 return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
14447 };
14448 // Builds the HTML to be used for the default element for an individual segment
14449 DayGridEventRenderer.prototype.fgSegHtml = function (seg, disableResizing) {
14450 var view = this.view;
14451 var eventDef = seg.footprint.eventDef;
14452 var isAllDay = seg.footprint.componentFootprint.isAllDay;
14453 var isDraggable = view.isEventDefDraggable(eventDef);
14454 var isResizableFromStart = !disableResizing && isAllDay &&
14455 seg.isStart && view.isEventDefResizableFromStart(eventDef);
14456 var isResizableFromEnd = !disableResizing && isAllDay &&
14457 seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
14458 var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
14459 var skinCss = util_1.cssToStr(this.getSkinCss(eventDef));
14460 var timeHtml = '';
14461 var timeText;
14462 var titleHtml;
14463 classes.unshift('fc-day-grid-event', 'fc-h-event');
14464 // Only display a timed events time if it is the starting segment
14465 if (seg.isStart) {
14466 timeText = this.getTimeText(seg.footprint);
14467 if (timeText) {
14468 timeHtml = '<span class="fc-time">' + util_1.htmlEscape(timeText) + '</span>';
14469 }
14470 }
14471 titleHtml =
14472 '<span class="fc-title">' +
14473 (util_1.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
14474 '</span>';
14475 return '<a class="' + classes.join(' ') + '"' +
14476 (eventDef.url ?
14477 ' href="' + util_1.htmlEscape(eventDef.url) + '"' :
14478 '') +
14479 (skinCss ?
14480 ' style="' + skinCss + '"' :
14481 '') +
14482 '>' +
14483 '<div class="fc-content">' +
14484 (this.dayGrid.isRTL ?
14485 titleHtml + ' ' + timeHtml : // put a natural space in between
14486 timeHtml + ' ' + titleHtml //
14487 ) +
14488 '</div>' +
14489 (isResizableFromStart ?
14490 '<div class="fc-resizer fc-start-resizer" />' :
14491 '') +
14492 (isResizableFromEnd ?
14493 '<div class="fc-resizer fc-end-resizer" />' :
14494 '') +
14495 '</a>';
14496 };
14497 return DayGridEventRenderer;
14498 }(EventRenderer_1.default));
14499 exports.default = DayGridEventRenderer;
14500 // Computes whether two segments' columns collide. They are assumed to be in the same row.
14501 function isDaySegCollision(seg, otherSegs) {
14502 var i;
14503 var otherSeg;
14504 for (i = 0; i < otherSegs.length; i++) {
14505 otherSeg = otherSegs[i];
14506 if (otherSeg.leftCol <= seg.rightCol &&
14507 otherSeg.rightCol >= seg.leftCol) {
14508 return true;
14509 }
14510 }
14511 return false;
14512 }
14513 // A cmp function for determining the leftmost event
14514 function compareDaySegCols(a, b) {
14515 return a.leftCol - b.leftCol;
14516 }
14517
14518
14519 /***/ }),
14520 /* 251 */
14521 /***/ (function(module, exports, __webpack_require__) {
14522
14523 Object.defineProperty(exports, "__esModule", { value: true });
14524 var tslib_1 = __webpack_require__(2);
14525 var $ = __webpack_require__(3);
14526 var HelperRenderer_1 = __webpack_require__(58);
14527 var DayGridHelperRenderer = /** @class */ (function (_super) {
14528 tslib_1.__extends(DayGridHelperRenderer, _super);
14529 function DayGridHelperRenderer() {
14530 return _super !== null && _super.apply(this, arguments) || this;
14531 }
14532 // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null.
14533 DayGridHelperRenderer.prototype.renderSegs = function (segs, sourceSeg) {
14534 var helperNodes = [];
14535 var rowStructs;
14536 // TODO: not good to call eventRenderer this way
14537 rowStructs = this.eventRenderer.renderSegRows(segs);
14538 // inject each new event skeleton into each associated row
14539 this.component.rowEls.each(function (row, rowNode) {
14540 var rowEl = $(rowNode); // the .fc-row
14541 var skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned
14542 var skeletonTopEl;
14543 var skeletonTop;
14544 // If there is an original segment, match the top position. Otherwise, put it at the row's top level
14545 if (sourceSeg && sourceSeg.row === row) {
14546 skeletonTop = sourceSeg.el.position().top;
14547 }
14548 else {
14549 skeletonTopEl = rowEl.find('.fc-content-skeleton tbody');
14550 if (!skeletonTopEl.length) {
14551 skeletonTopEl = rowEl.find('.fc-content-skeleton table');
14552 }
14553 skeletonTop = skeletonTopEl.position().top;
14554 }
14555 skeletonEl.css('top', skeletonTop)
14556 .find('table')
14557 .append(rowStructs[row].tbodyEl);
14558 rowEl.append(skeletonEl);
14559 helperNodes.push(skeletonEl[0]);
14560 });
14561 return $(helperNodes); // must return the elements rendered
14562 };
14563 return DayGridHelperRenderer;
14564 }(HelperRenderer_1.default));
14565 exports.default = DayGridHelperRenderer;
14566
14567
14568 /***/ }),
14569 /* 252 */
14570 /***/ (function(module, exports, __webpack_require__) {
14571
14572 Object.defineProperty(exports, "__esModule", { value: true });
14573 var tslib_1 = __webpack_require__(2);
14574 var $ = __webpack_require__(3);
14575 var FillRenderer_1 = __webpack_require__(57);
14576 var DayGridFillRenderer = /** @class */ (function (_super) {
14577 tslib_1.__extends(DayGridFillRenderer, _super);
14578 function DayGridFillRenderer() {
14579 var _this = _super !== null && _super.apply(this, arguments) || this;
14580 _this.fillSegTag = 'td'; // override the default tag name
14581 return _this;
14582 }
14583 DayGridFillRenderer.prototype.attachSegEls = function (type, segs) {
14584 var nodes = [];
14585 var i;
14586 var seg;
14587 var skeletonEl;
14588 for (i = 0; i < segs.length; i++) {
14589 seg = segs[i];
14590 skeletonEl = this.renderFillRow(type, seg);
14591 this.component.rowEls.eq(seg.row).append(skeletonEl);
14592 nodes.push(skeletonEl[0]);
14593 }
14594 return nodes;
14595 };
14596 // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
14597 DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
14598 var colCnt = this.component.colCnt;
14599 var startCol = seg.leftCol;
14600 var endCol = seg.rightCol + 1;
14601 var className;
14602 var skeletonEl;
14603 var trEl;
14604 if (type === 'businessHours') {
14605 className = 'bgevent';
14606 }
14607 else {
14608 className = type.toLowerCase();
14609 }
14610 skeletonEl = $('<div class="fc-' + className + '-skeleton">' +
14611 '<table><tr/></table>' +
14612 '</div>');
14613 trEl = skeletonEl.find('tr');
14614 if (startCol > 0) {
14615 trEl.append('<td colspan="' + startCol + '"/>');
14616 }
14617 trEl.append(seg.el.attr('colspan', endCol - startCol));
14618 if (endCol < colCnt) {
14619 trEl.append('<td colspan="' + (colCnt - endCol) + '"/>');
14620 }
14621 this.component.bookendCells(trEl);
14622 return skeletonEl;
14623 };
14624 return DayGridFillRenderer;
14625 }(FillRenderer_1.default));
14626 exports.default = DayGridFillRenderer;
14627
14628
14629 /***/ }),
14630 /* 253 */
14631 /***/ (function(module, exports, __webpack_require__) {
14632
14633 Object.defineProperty(exports, "__esModule", { value: true });
14634 var tslib_1 = __webpack_require__(2);
14635 var BasicViewDateProfileGenerator_1 = __webpack_require__(228);
14636 var UnzonedRange_1 = __webpack_require__(5);
14637 var MonthViewDateProfileGenerator = /** @class */ (function (_super) {
14638 tslib_1.__extends(MonthViewDateProfileGenerator, _super);
14639 function MonthViewDateProfileGenerator() {
14640 return _super !== null && _super.apply(this, arguments) || this;
14641 }
14642 // Computes the date range that will be rendered.
14643 MonthViewDateProfileGenerator.prototype.buildRenderRange = function (currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
14644 var renderUnzonedRange = _super.prototype.buildRenderRange.call(this, currentUnzonedRange, currentRangeUnit, isRangeAllDay);
14645 var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
14646 var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
14647 var rowCnt;
14648 // ensure 6 weeks
14649 if (this.opt('fixedWeekCount')) {
14650 rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
14651 end.diff(start, 'weeks', true) // dontRound=true
14652 );
14653 end.add(6 - rowCnt, 'weeks');
14654 }
14655 return new UnzonedRange_1.default(start, end);
14656 };
14657 return MonthViewDateProfileGenerator;
14658 }(BasicViewDateProfileGenerator_1.default));
14659 exports.default = MonthViewDateProfileGenerator;
14660
14661
14662 /***/ }),
14663 /* 254 */
14664 /***/ (function(module, exports, __webpack_require__) {
14665
14666 Object.defineProperty(exports, "__esModule", { value: true });
14667 var tslib_1 = __webpack_require__(2);
14668 var util_1 = __webpack_require__(4);
14669 var EventRenderer_1 = __webpack_require__(42);
14670 var ListEventRenderer = /** @class */ (function (_super) {
14671 tslib_1.__extends(ListEventRenderer, _super);
14672 function ListEventRenderer() {
14673 return _super !== null && _super.apply(this, arguments) || this;
14674 }
14675 ListEventRenderer.prototype.renderFgSegs = function (segs) {
14676 if (!segs.length) {
14677 this.component.renderEmptyMessage();
14678 }
14679 else {
14680 this.component.renderSegList(segs);
14681 }
14682 };
14683 // generates the HTML for a single event row
14684 ListEventRenderer.prototype.fgSegHtml = function (seg) {
14685 var view = this.view;
14686 var calendar = view.calendar;
14687 var theme = calendar.theme;
14688 var eventFootprint = seg.footprint;
14689 var eventDef = eventFootprint.eventDef;
14690 var componentFootprint = eventFootprint.componentFootprint;
14691 var url = eventDef.url;
14692 var classes = ['fc-list-item'].concat(this.getClasses(eventDef));
14693 var bgColor = this.getBgColor(eventDef);
14694 var timeHtml;
14695 if (componentFootprint.isAllDay) {
14696 timeHtml = view.getAllDayHtml();
14697 }
14698 else if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
14699 if (seg.isStart || seg.isEnd) {
14700 timeHtml = util_1.htmlEscape(this._getTimeText(calendar.msToMoment(seg.startMs), calendar.msToMoment(seg.endMs), componentFootprint.isAllDay));
14701 }
14702 else {
14703 timeHtml = view.getAllDayHtml();
14704 }
14705 }
14706 else {
14707 // Display the normal time text for the *event's* times
14708 timeHtml = util_1.htmlEscape(this.getTimeText(eventFootprint));
14709 }
14710 if (url) {
14711 classes.push('fc-has-url');
14712 }
14713 return '<tr class="' + classes.join(' ') + '">' +
14714 (this.displayEventTime ?
14715 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' +
14716 (timeHtml || '') +
14717 '</td>' :
14718 '') +
14719 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' +
14720 '<span class="fc-event-dot"' +
14721 (bgColor ?
14722 ' style="background-color:' + bgColor + '"' :
14723 '') +
14724 '></span>' +
14725 '</td>' +
14726 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' +
14727 '<a' + (url ? ' href="' + util_1.htmlEscape(url) + '"' : '') + '>' +
14728 util_1.htmlEscape(eventDef.title || '') +
14729 '</a>' +
14730 '</td>' +
14731 '</tr>';
14732 };
14733 // like "4:00am"
14734 ListEventRenderer.prototype.computeEventTimeFormat = function () {
14735 return this.opt('mediumTimeFormat');
14736 };
14737 return ListEventRenderer;
14738 }(EventRenderer_1.default));
14739 exports.default = ListEventRenderer;
14740
14741
14742 /***/ }),
14743 /* 255 */
14744 /***/ (function(module, exports, __webpack_require__) {
14745
14746 Object.defineProperty(exports, "__esModule", { value: true });
14747 var tslib_1 = __webpack_require__(2);
14748 var $ = __webpack_require__(3);
14749 var EventPointing_1 = __webpack_require__(59);
14750 var ListEventPointing = /** @class */ (function (_super) {
14751 tslib_1.__extends(ListEventPointing, _super);
14752 function ListEventPointing() {
14753 return _super !== null && _super.apply(this, arguments) || this;
14754 }
14755 // for events with a url, the whole <tr> should be clickable,
14756 // but it's impossible to wrap with an <a> tag. simulate this.
14757 ListEventPointing.prototype.handleClick = function (seg, ev) {
14758 var url;
14759 _super.prototype.handleClick.call(this, seg, ev); // might prevent the default action
14760 // not clicking on or within an <a> with an href
14761 if (!$(ev.target).closest('a[href]').length) {
14762 url = seg.footprint.eventDef.url;
14763 if (url && !ev.isDefaultPrevented()) {
14764 window.location.href = url; // simulate link click
14765 }
14766 }
14767 };
14768 return ListEventPointing;
14769 }(EventPointing_1.default));
14770 exports.default = ListEventPointing;
14771
14772
14773 /***/ }),
14774 /* 256 */
14775 /***/ (function(module, exports, __webpack_require__) {
14776
14777 Object.defineProperty(exports, "__esModule", { value: true });
14778 var EventSourceParser_1 = __webpack_require__(38);
14779 var ArrayEventSource_1 = __webpack_require__(52);
14780 var FuncEventSource_1 = __webpack_require__(215);
14781 var JsonFeedEventSource_1 = __webpack_require__(216);
14782 EventSourceParser_1.default.registerClass(ArrayEventSource_1.default);
14783 EventSourceParser_1.default.registerClass(FuncEventSource_1.default);
14784 EventSourceParser_1.default.registerClass(JsonFeedEventSource_1.default);
14785
14786
14787 /***/ }),
14788 /* 257 */
14789 /***/ (function(module, exports, __webpack_require__) {
14790
14791 Object.defineProperty(exports, "__esModule", { value: true });
14792 var ThemeRegistry_1 = __webpack_require__(51);
14793 var StandardTheme_1 = __webpack_require__(213);
14794 var JqueryUiTheme_1 = __webpack_require__(214);
14795 var Bootstrap3Theme_1 = __webpack_require__(258);
14796 var Bootstrap4Theme_1 = __webpack_require__(259);
14797 ThemeRegistry_1.defineThemeSystem('standard', StandardTheme_1.default);
14798 ThemeRegistry_1.defineThemeSystem('jquery-ui', JqueryUiTheme_1.default);
14799 ThemeRegistry_1.defineThemeSystem('bootstrap3', Bootstrap3Theme_1.default);
14800 ThemeRegistry_1.defineThemeSystem('bootstrap4', Bootstrap4Theme_1.default);
14801
14802
14803 /***/ }),
14804 /* 258 */
14805 /***/ (function(module, exports, __webpack_require__) {
14806
14807 Object.defineProperty(exports, "__esModule", { value: true });
14808 var tslib_1 = __webpack_require__(2);
14809 var Theme_1 = __webpack_require__(19);
14810 var Bootstrap3Theme = /** @class */ (function (_super) {
14811 tslib_1.__extends(Bootstrap3Theme, _super);
14812 function Bootstrap3Theme() {
14813 return _super !== null && _super.apply(this, arguments) || this;
14814 }
14815 return Bootstrap3Theme;
14816 }(Theme_1.default));
14817 exports.default = Bootstrap3Theme;
14818 Bootstrap3Theme.prototype.classes = {
14819 widget: 'fc-bootstrap3',
14820 tableGrid: 'table-bordered',
14821 tableList: 'table',
14822 tableListHeading: 'active',
14823 buttonGroup: 'btn-group',
14824 button: 'btn btn-default',
14825 stateActive: 'active',
14826 stateDisabled: 'disabled',
14827 today: 'alert alert-info',
14828 popover: 'panel panel-default',
14829 popoverHeader: 'panel-heading',
14830 popoverContent: 'panel-body',
14831 // day grid
14832 // for left/right border color when border is inset from edges (all-day in agenda view)
14833 // avoid `panel` class b/c don't want margins/radius. only border color.
14834 headerRow: 'panel-default',
14835 dayRow: 'panel-default',
14836 // list view
14837 listView: 'panel panel-default'
14838 };
14839 Bootstrap3Theme.prototype.baseIconClass = 'glyphicon';
14840 Bootstrap3Theme.prototype.iconClasses = {
14841 close: 'glyphicon-remove',
14842 prev: 'glyphicon-chevron-left',
14843 next: 'glyphicon-chevron-right',
14844 prevYear: 'glyphicon-backward',
14845 nextYear: 'glyphicon-forward'
14846 };
14847 Bootstrap3Theme.prototype.iconOverrideOption = 'bootstrapGlyphicons';
14848 Bootstrap3Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapGlyphicon';
14849 Bootstrap3Theme.prototype.iconOverridePrefix = 'glyphicon-';
14850
14851
14852 /***/ }),
14853 /* 259 */
14854 /***/ (function(module, exports, __webpack_require__) {
14855
14856 Object.defineProperty(exports, "__esModule", { value: true });
14857 var tslib_1 = __webpack_require__(2);
14858 var Theme_1 = __webpack_require__(19);
14859 var Bootstrap4Theme = /** @class */ (function (_super) {
14860 tslib_1.__extends(Bootstrap4Theme, _super);
14861 function Bootstrap4Theme() {
14862 return _super !== null && _super.apply(this, arguments) || this;
14863 }
14864 return Bootstrap4Theme;
14865 }(Theme_1.default));
14866 exports.default = Bootstrap4Theme;
14867 Bootstrap4Theme.prototype.classes = {
14868 widget: 'fc-bootstrap4',
14869 tableGrid: 'table-bordered',
14870 tableList: 'table',
14871 tableListHeading: 'table-active',
14872 buttonGroup: 'btn-group',
14873 button: 'btn btn-primary',
14874 stateActive: 'active',
14875 stateDisabled: 'disabled',
14876 today: 'alert alert-info',
14877 popover: 'card card-primary',
14878 popoverHeader: 'card-header',
14879 popoverContent: 'card-body',
14880 // day grid
14881 // for left/right border color when border is inset from edges (all-day in agenda view)
14882 // avoid `table` class b/c don't want margins/padding/structure. only border color.
14883 headerRow: 'table-bordered',
14884 dayRow: 'table-bordered',
14885 // list view
14886 listView: 'card card-primary'
14887 };
14888 Bootstrap4Theme.prototype.baseIconClass = 'fa';
14889 Bootstrap4Theme.prototype.iconClasses = {
14890 close: 'fa-times',
14891 prev: 'fa-chevron-left',
14892 next: 'fa-chevron-right',
14893 prevYear: 'fa-angle-double-left',
14894 nextYear: 'fa-angle-double-right'
14895 };
14896 Bootstrap4Theme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
14897 Bootstrap4Theme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome';
14898 Bootstrap4Theme.prototype.iconOverridePrefix = 'fa-';
14899
14900
14901 /***/ }),
14902 /* 260 */
14903 /***/ (function(module, exports, __webpack_require__) {
14904
14905 Object.defineProperty(exports, "__esModule", { value: true });
14906 var ViewRegistry_1 = __webpack_require__(22);
14907 var BasicView_1 = __webpack_require__(62);
14908 var MonthView_1 = __webpack_require__(229);
14909 ViewRegistry_1.defineView('basic', {
14910 'class': BasicView_1.default
14911 });
14912 ViewRegistry_1.defineView('basicDay', {
14913 type: 'basic',
14914 duration: { days: 1 }
14915 });
14916 ViewRegistry_1.defineView('basicWeek', {
14917 type: 'basic',
14918 duration: { weeks: 1 }
14919 });
14920 ViewRegistry_1.defineView('month', {
14921 'class': MonthView_1.default,
14922 duration: { months: 1 },
14923 defaults: {
14924 fixedWeekCount: true
14925 }
14926 });
14927
14928
14929 /***/ }),
14930 /* 261 */
14931 /***/ (function(module, exports, __webpack_require__) {
14932
14933 Object.defineProperty(exports, "__esModule", { value: true });
14934 var ViewRegistry_1 = __webpack_require__(22);
14935 var AgendaView_1 = __webpack_require__(226);
14936 ViewRegistry_1.defineView('agenda', {
14937 'class': AgendaView_1.default,
14938 defaults: {
14939 allDaySlot: true,
14940 slotDuration: '00:30:00',
14941 slotEventOverlap: true // a bad name. confused with overlap/constraint system
14942 }
14943 });
14944 ViewRegistry_1.defineView('agendaDay', {
14945 type: 'agenda',
14946 duration: { days: 1 }
14947 });
14948 ViewRegistry_1.defineView('agendaWeek', {
14949 type: 'agenda',
14950 duration: { weeks: 1 }
14951 });
14952
14953
14954 /***/ }),
14955 /* 262 */
14956 /***/ (function(module, exports, __webpack_require__) {
14957
14958 Object.defineProperty(exports, "__esModule", { value: true });
14959 var ViewRegistry_1 = __webpack_require__(22);
14960 var ListView_1 = __webpack_require__(230);
14961 ViewRegistry_1.defineView('list', {
14962 'class': ListView_1.default,
14963 buttonTextKey: 'list',
14964 defaults: {
14965 buttonText: 'list',
14966 listDayFormat: 'LL',
14967 noEventsMessage: 'No events to display'
14968 }
14969 });
14970 ViewRegistry_1.defineView('listDay', {
14971 type: 'list',
14972 duration: { days: 1 },
14973 defaults: {
14974 listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header
14975 }
14976 });
14977 ViewRegistry_1.defineView('listWeek', {
14978 type: 'list',
14979 duration: { weeks: 1 },
14980 defaults: {
14981 listDayFormat: 'dddd',
14982 listDayAltFormat: 'LL'
14983 }
14984 });
14985 ViewRegistry_1.defineView('listMonth', {
14986 type: 'list',
14987 duration: { month: 1 },
14988 defaults: {
14989 listDayAltFormat: 'dddd' // day-of-week is nice-to-have
14990 }
14991 });
14992 ViewRegistry_1.defineView('listYear', {
14993 type: 'list',
14994 duration: { year: 1 },
14995 defaults: {
14996 listDayAltFormat: 'dddd' // day-of-week is nice-to-have
14997 }
14998 });
14999
15000
15001 /***/ }),
15002 /* 263 */
15003 /***/ (function(module, exports) {
15004
15005 Object.defineProperty(exports, "__esModule", { value: true });
15006
15007
15008 /***/ })
15009 /******/ ]);
15010 });