懒羊羊
2023-08-30 71e81ed1d12e4d69f53c8ad9e066650ad4186293
提交 | 用户 | 时间
71e81e 1 /*!
2 FullCalendar Time Grid Plugin v4.3.0
3 Docs & License: https://fullcalendar.io/
4 (c) 2019 Adam Shaw
5 */
6
7 (function (global, factory) {
8     typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core'), require('@fullcalendar/daygrid')) :
9     typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core', '@fullcalendar/daygrid'], factory) :
10     (global = global || self, factory(global.FullCalendarTimeGrid = {}, global.FullCalendar, global.FullCalendarDayGrid));
11 }(this, function (exports, core, daygrid) { 'use strict';
12
13     /*! *****************************************************************************
14     Copyright (c) Microsoft Corporation. All rights reserved.
15     Licensed under the Apache License, Version 2.0 (the "License"); you may not use
16     this file except in compliance with the License. You may obtain a copy of the
17     License at http://www.apache.org/licenses/LICENSE-2.0
18
19     THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20     KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
21     WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
22     MERCHANTABLITY OR NON-INFRINGEMENT.
23
24     See the Apache Version 2.0 License for specific language governing permissions
25     and limitations under the License.
26     ***************************************************************************** */
27     /* global Reflect, Promise */
28
29     var extendStatics = function(d, b) {
30         extendStatics = Object.setPrototypeOf ||
31             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
32             function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
33         return extendStatics(d, b);
34     };
35
36     function __extends(d, b) {
37         extendStatics(d, b);
38         function __() { this.constructor = d; }
39         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
40     }
41
42     var __assign = function() {
43         __assign = Object.assign || function __assign(t) {
44             for (var s, i = 1, n = arguments.length; i < n; i++) {
45                 s = arguments[i];
46                 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
47             }
48             return t;
49         };
50         return __assign.apply(this, arguments);
51     };
52
53     /*
54     Only handles foreground segs.
55     Does not own rendering. Use for low-level util methods by TimeGrid.
56     */
57     var TimeGridEventRenderer = /** @class */ (function (_super) {
58         __extends(TimeGridEventRenderer, _super);
59         function TimeGridEventRenderer(timeGrid) {
60             var _this = _super.call(this, timeGrid.context) || this;
61             _this.timeGrid = timeGrid;
62             _this.fullTimeFormat = core.createFormatter({
63                 hour: 'numeric',
64                 minute: '2-digit',
65                 separator: _this.context.options.defaultRangeSeparator
66             });
67             return _this;
68         }
69         // Given an array of foreground segments, render a DOM element for each, computes position,
70         // and attaches to the column inner-container elements.
71         TimeGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
72             var segsByCol = this.timeGrid.groupSegsByCol(segs);
73             // order the segs within each column
74             // TODO: have groupSegsByCol do this?
75             for (var col = 0; col < segsByCol.length; col++) {
76                 segsByCol[col] = this.sortEventSegs(segsByCol[col]);
77             }
78             this.segsByCol = segsByCol;
79             this.timeGrid.attachSegsByCol(segsByCol, this.timeGrid.fgContainerEls);
80         };
81         TimeGridEventRenderer.prototype.detachSegs = function (segs) {
82             segs.forEach(function (seg) {
83                 core.removeElement(seg.el);
84             });
85             this.segsByCol = null;
86         };
87         TimeGridEventRenderer.prototype.computeSegSizes = function (allSegs) {
88             var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
89             var colCnt = timeGrid.colCnt;
90             timeGrid.computeSegVerticals(allSegs); // horizontals relies on this
91             if (segsByCol) {
92                 for (var col = 0; col < colCnt; col++) {
93                     this.computeSegHorizontals(segsByCol[col]); // compute horizontal coordinates, z-index's, and reorder the array
94                 }
95             }
96         };
97         TimeGridEventRenderer.prototype.assignSegSizes = function (allSegs) {
98             var _a = this, timeGrid = _a.timeGrid, segsByCol = _a.segsByCol;
99             var colCnt = timeGrid.colCnt;
100             timeGrid.assignSegVerticals(allSegs); // horizontals relies on this
101             if (segsByCol) {
102                 for (var col = 0; col < colCnt; col++) {
103                     this.assignSegCss(segsByCol[col]);
104                 }
105             }
106         };
107         // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
108         TimeGridEventRenderer.prototype.computeEventTimeFormat = function () {
109             return {
110                 hour: 'numeric',
111                 minute: '2-digit',
112                 meridiem: false
113             };
114         };
115         // Computes a default `displayEventEnd` value if one is not expliclty defined
116         TimeGridEventRenderer.prototype.computeDisplayEventEnd = function () {
117             return true;
118         };
119         // Renders the HTML for a single event segment's default rendering
120         TimeGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
121             var view = this.context.view;
122             var eventRange = seg.eventRange;
123             var eventDef = eventRange.def;
124             var eventUi = eventRange.ui;
125             var allDay = eventDef.allDay;
126             var isDraggable = view.computeEventDraggable(eventDef, eventUi);
127             var isResizableFromStart = seg.isStart && view.computeEventStartResizable(eventDef, eventUi);
128             var isResizableFromEnd = seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
129             var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
130             var skinCss = core.cssToStr(this.getSkinCss(eventUi));
131             var timeText;
132             var fullTimeText; // more verbose time text. for the print stylesheet
133             var startTimeText; // just the start time text
134             classes.unshift('fc-time-grid-event');
135             // if the event appears to span more than one day...
136             if (core.isMultiDayRange(eventRange.range)) {
137                 // Don't display time text on segments that run entirely through a day.
138                 // That would appear as midnight-midnight and would look dumb.
139                 // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
140                 if (seg.isStart || seg.isEnd) {
141                     var unzonedStart = seg.start;
142                     var unzonedEnd = seg.end;
143                     timeText = this._getTimeText(unzonedStart, unzonedEnd, allDay); // TODO: give the timezones
144                     fullTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, this.fullTimeFormat);
145                     startTimeText = this._getTimeText(unzonedStart, unzonedEnd, allDay, null, false); // displayEnd=false
146                 }
147             }
148             else {
149                 // Display the normal time text for the *event's* times
150                 timeText = this.getTimeText(eventRange);
151                 fullTimeText = this.getTimeText(eventRange, this.fullTimeFormat);
152                 startTimeText = this.getTimeText(eventRange, null, false); // displayEnd=false
153             }
154             return '<a class="' + classes.join(' ') + '"' +
155                 (eventDef.url ?
156                     ' href="' + core.htmlEscape(eventDef.url) + '"' :
157                     '') +
158                 (skinCss ?
159                     ' style="' + skinCss + '"' :
160                     '') +
161                 '>' +
162                 '<div class="fc-content">' +
163                 (timeText ?
164                     '<div class="fc-time"' +
165                         ' data-start="' + core.htmlEscape(startTimeText) + '"' +
166                         ' data-full="' + core.htmlEscape(fullTimeText) + '"' +
167                         '>' +
168                         '<span>' + core.htmlEscape(timeText) + '</span>' +
169                         '</div>' :
170                     '') +
171                 (eventDef.title ?
172                     '<div class="fc-title">' +
173                         core.htmlEscape(eventDef.title) +
174                         '</div>' :
175                     '') +
176                 '</div>' +
177                 /* TODO: write CSS for this
178                 (isResizableFromStart ?
179                   '<div class="fc-resizer fc-start-resizer"></div>' :
180                   ''
181                   ) +
182                 */
183                 (isResizableFromEnd ?
184                     '<div class="fc-resizer fc-end-resizer"></div>' :
185                     '') +
186                 '</a>';
187         };
188         // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
189         // Assumed the segs are already ordered.
190         // NOTE: Also reorders the given array by date!
191         TimeGridEventRenderer.prototype.computeSegHorizontals = function (segs) {
192             var levels;
193             var level0;
194             var i;
195             levels = buildSlotSegLevels(segs);
196             computeForwardSlotSegs(levels);
197             if ((level0 = levels[0])) {
198                 for (i = 0; i < level0.length; i++) {
199                     computeSlotSegPressures(level0[i]);
200                 }
201                 for (i = 0; i < level0.length; i++) {
202                     this.computeSegForwardBack(level0[i], 0, 0);
203                 }
204             }
205         };
206         // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
207         // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
208         // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
209         //
210         // The segment might be part of a "series", which means consecutive segments with the same pressure
211         // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
212         // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
213         // coordinate of the first segment in the series.
214         TimeGridEventRenderer.prototype.computeSegForwardBack = function (seg, seriesBackwardPressure, seriesBackwardCoord) {
215             var forwardSegs = seg.forwardSegs;
216             var i;
217             if (seg.forwardCoord === undefined) { // not already computed
218                 if (!forwardSegs.length) {
219                     // if there are no forward segments, this segment should butt up against the edge
220                     seg.forwardCoord = 1;
221                 }
222                 else {
223                     // sort highest pressure first
224                     this.sortForwardSegs(forwardSegs);
225                     // this segment's forwardCoord will be calculated from the backwardCoord of the
226                     // highest-pressure forward segment.
227                     this.computeSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
228                     seg.forwardCoord = forwardSegs[0].backwardCoord;
229                 }
230                 // calculate the backwardCoord from the forwardCoord. consider the series
231                 seg.backwardCoord = seg.forwardCoord -
232                     (seg.forwardCoord - seriesBackwardCoord) / // available width for series
233                         (seriesBackwardPressure + 1); // # of segments in the series
234                 // use this segment's coordinates to computed the coordinates of the less-pressurized
235                 // forward segments
236                 for (i = 0; i < forwardSegs.length; i++) {
237                     this.computeSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
238                 }
239             }
240         };
241         TimeGridEventRenderer.prototype.sortForwardSegs = function (forwardSegs) {
242             var objs = forwardSegs.map(buildTimeGridSegCompareObj);
243             var specs = [
244                 // put higher-pressure first
245                 { field: 'forwardPressure', order: -1 },
246                 // put segments that are closer to initial edge first (and favor ones with no coords yet)
247                 { field: 'backwardCoord', order: 1 }
248             ].concat(this.context.view.eventOrderSpecs);
249             objs.sort(function (obj0, obj1) {
250                 return core.compareByFieldSpecs(obj0, obj1, specs);
251             });
252             return objs.map(function (c) {
253                 return c._seg;
254             });
255         };
256         // Given foreground event segments that have already had their position coordinates computed,
257         // assigns position-related CSS values to their elements.
258         TimeGridEventRenderer.prototype.assignSegCss = function (segs) {
259             for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
260                 var seg = segs_1[_i];
261                 core.applyStyle(seg.el, this.generateSegCss(seg));
262                 if (seg.level > 0) {
263                     seg.el.classList.add('fc-time-grid-event-inset');
264                 }
265                 // if the event is short that the title will be cut off,
266                 // attach a className that condenses the title into the time area.
267                 if (seg.eventRange.def.title && seg.bottom - seg.top < 30) {
268                     seg.el.classList.add('fc-short'); // TODO: "condensed" is a better name
269                 }
270             }
271         };
272         // Generates an object with CSS properties/values that should be applied to an event segment element.
273         // Contains important positioning-related properties that should be applied to any event element, customized or not.
274         TimeGridEventRenderer.prototype.generateSegCss = function (seg) {
275             var shouldOverlap = this.context.options.slotEventOverlap;
276             var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
277             var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
278             var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
279             var isRtl = this.timeGrid.isRtl;
280             var left; // amount of space from left edge, a fraction of the total width
281             var right; // amount of space from right edge, a fraction of the total width
282             if (shouldOverlap) {
283                 // double the width, but don't go beyond the maximum forward coordinate (1.0)
284                 forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
285             }
286             if (isRtl) {
287                 left = 1 - forwardCoord;
288                 right = backwardCoord;
289             }
290             else {
291                 left = backwardCoord;
292                 right = 1 - forwardCoord;
293             }
294             props.zIndex = seg.level + 1; // convert from 0-base to 1-based
295             props.left = left * 100 + '%';
296             props.right = right * 100 + '%';
297             if (shouldOverlap && seg.forwardPressure) {
298                 // add padding to the edge so that forward stacked events don't cover the resizer's icon
299                 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
300             }
301             return props;
302         };
303         return TimeGridEventRenderer;
304     }(core.FgEventRenderer));
305     // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
306     // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
307     function buildSlotSegLevels(segs) {
308         var levels = [];
309         var i;
310         var seg;
311         var j;
312         for (i = 0; i < segs.length; i++) {
313             seg = segs[i];
314             // go through all the levels and stop on the first level where there are no collisions
315             for (j = 0; j < levels.length; j++) {
316                 if (!computeSlotSegCollisions(seg, levels[j]).length) {
317                     break;
318                 }
319             }
320             seg.level = j;
321             (levels[j] || (levels[j] = [])).push(seg);
322         }
323         return levels;
324     }
325     // For every segment, figure out the other segments that are in subsequent
326     // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
327     function computeForwardSlotSegs(levels) {
328         var i;
329         var level;
330         var j;
331         var seg;
332         var k;
333         for (i = 0; i < levels.length; i++) {
334             level = levels[i];
335             for (j = 0; j < level.length; j++) {
336                 seg = level[j];
337                 seg.forwardSegs = [];
338                 for (k = i + 1; k < levels.length; k++) {
339                     computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
340                 }
341             }
342         }
343     }
344     // Figure out which path forward (via seg.forwardSegs) results in the longest path until
345     // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
346     function computeSlotSegPressures(seg) {
347         var forwardSegs = seg.forwardSegs;
348         var forwardPressure = 0;
349         var i;
350         var forwardSeg;
351         if (seg.forwardPressure === undefined) { // not already computed
352             for (i = 0; i < forwardSegs.length; i++) {
353                 forwardSeg = forwardSegs[i];
354                 // figure out the child's maximum forward path
355                 computeSlotSegPressures(forwardSeg);
356                 // either use the existing maximum, or use the child's forward pressure
357                 // plus one (for the forwardSeg itself)
358                 forwardPressure = Math.max(forwardPressure, 1 + forwardSeg.forwardPressure);
359             }
360             seg.forwardPressure = forwardPressure;
361         }
362     }
363     // Find all the segments in `otherSegs` that vertically collide with `seg`.
364     // Append into an optionally-supplied `results` array and return.
365     function computeSlotSegCollisions(seg, otherSegs, results) {
366         if (results === void 0) { results = []; }
367         for (var i = 0; i < otherSegs.length; i++) {
368             if (isSlotSegCollision(seg, otherSegs[i])) {
369                 results.push(otherSegs[i]);
370             }
371         }
372         return results;
373     }
374     // Do these segments occupy the same vertical space?
375     function isSlotSegCollision(seg1, seg2) {
376         return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
377     }
378     function buildTimeGridSegCompareObj(seg) {
379         var obj = core.buildSegCompareObj(seg);
380         obj.forwardPressure = seg.forwardPressure;
381         obj.backwardCoord = seg.backwardCoord;
382         return obj;
383     }
384
385     var TimeGridMirrorRenderer = /** @class */ (function (_super) {
386         __extends(TimeGridMirrorRenderer, _super);
387         function TimeGridMirrorRenderer() {
388             return _super !== null && _super.apply(this, arguments) || this;
389         }
390         TimeGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
391             this.segsByCol = this.timeGrid.groupSegsByCol(segs);
392             this.timeGrid.attachSegsByCol(this.segsByCol, this.timeGrid.mirrorContainerEls);
393             this.sourceSeg = mirrorInfo.sourceSeg;
394         };
395         TimeGridMirrorRenderer.prototype.generateSegCss = function (seg) {
396             var props = _super.prototype.generateSegCss.call(this, seg);
397             var sourceSeg = this.sourceSeg;
398             if (sourceSeg && sourceSeg.col === seg.col) {
399                 var sourceSegProps = _super.prototype.generateSegCss.call(this, sourceSeg);
400                 props.left = sourceSegProps.left;
401                 props.right = sourceSegProps.right;
402                 props.marginLeft = sourceSegProps.marginLeft;
403                 props.marginRight = sourceSegProps.marginRight;
404             }
405             return props;
406         };
407         return TimeGridMirrorRenderer;
408     }(TimeGridEventRenderer));
409
410     var TimeGridFillRenderer = /** @class */ (function (_super) {
411         __extends(TimeGridFillRenderer, _super);
412         function TimeGridFillRenderer(timeGrid) {
413             var _this = _super.call(this, timeGrid.context) || this;
414             _this.timeGrid = timeGrid;
415             return _this;
416         }
417         TimeGridFillRenderer.prototype.attachSegs = function (type, segs) {
418             var timeGrid = this.timeGrid;
419             var containerEls;
420             // TODO: more efficient lookup
421             if (type === 'bgEvent') {
422                 containerEls = timeGrid.bgContainerEls;
423             }
424             else if (type === 'businessHours') {
425                 containerEls = timeGrid.businessContainerEls;
426             }
427             else if (type === 'highlight') {
428                 containerEls = timeGrid.highlightContainerEls;
429             }
430             timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
431             return segs.map(function (seg) {
432                 return seg.el;
433             });
434         };
435         TimeGridFillRenderer.prototype.computeSegSizes = function (segs) {
436             this.timeGrid.computeSegVerticals(segs);
437         };
438         TimeGridFillRenderer.prototype.assignSegSizes = function (segs) {
439             this.timeGrid.assignSegVerticals(segs);
440         };
441         return TimeGridFillRenderer;
442     }(core.FillRenderer));
443
444     /* A component that renders one or more columns of vertical time slots
445     ----------------------------------------------------------------------------------------------------------------------*/
446     // potential nice values for the slot-duration and interval-duration
447     // from largest to smallest
448     var AGENDA_STOCK_SUB_DURATIONS = [
449         { hours: 1 },
450         { minutes: 30 },
451         { minutes: 15 },
452         { seconds: 30 },
453         { seconds: 15 }
454     ];
455     var TimeGrid = /** @class */ (function (_super) {
456         __extends(TimeGrid, _super);
457         function TimeGrid(context, el, renderProps) {
458             var _this = _super.call(this, context, el) || this;
459             _this.isSlatSizesDirty = false;
460             _this.isColSizesDirty = false;
461             _this.renderSlats = core.memoizeRendering(_this._renderSlats);
462             var eventRenderer = _this.eventRenderer = new TimeGridEventRenderer(_this);
463             var fillRenderer = _this.fillRenderer = new TimeGridFillRenderer(_this);
464             _this.mirrorRenderer = new TimeGridMirrorRenderer(_this);
465             var renderColumns = _this.renderColumns = core.memoizeRendering(_this._renderColumns, _this._unrenderColumns);
466             _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderColumns]);
467             _this.renderDateSelection = core.memoizeRendering(_this._renderDateSelection, _this._unrenderDateSelection, [renderColumns]);
468             _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderColumns]);
469             _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderColumns]);
470             _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
471             _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderColumns]);
472             _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderColumns]);
473             _this.processOptions();
474             el.innerHTML =
475                 '<div class="fc-bg"></div>' +
476                     '<div class="fc-slats"></div>' +
477                     '<hr class="fc-divider ' + _this.theme.getClass('widgetHeader') + '" style="display:none" />';
478             _this.rootBgContainerEl = el.querySelector('.fc-bg');
479             _this.slatContainerEl = el.querySelector('.fc-slats');
480             _this.bottomRuleEl = el.querySelector('.fc-divider');
481             _this.renderProps = renderProps;
482             return _this;
483         }
484         /* Options
485         ------------------------------------------------------------------------------------------------------------------*/
486         // Parses various options into properties of this object
487         TimeGrid.prototype.processOptions = function () {
488             var slotDuration = this.opt('slotDuration');
489             var snapDuration = this.opt('snapDuration');
490             var snapsPerSlot;
491             var input;
492             slotDuration = core.createDuration(slotDuration);
493             snapDuration = snapDuration ? core.createDuration(snapDuration) : slotDuration;
494             snapsPerSlot = core.wholeDivideDurations(slotDuration, snapDuration);
495             if (snapsPerSlot === null) {
496                 snapDuration = slotDuration;
497                 snapsPerSlot = 1;
498                 // TODO: say warning?
499             }
500             this.slotDuration = slotDuration;
501             this.snapDuration = snapDuration;
502             this.snapsPerSlot = snapsPerSlot;
503             // might be an array value (for TimelineView).
504             // if so, getting the most granular entry (the last one probably).
505             input = this.opt('slotLabelFormat');
506             if (Array.isArray(input)) {
507                 input = input[input.length - 1];
508             }
509             this.labelFormat = core.createFormatter(input || {
510                 hour: 'numeric',
511                 minute: '2-digit',
512                 omitZeroMinute: true,
513                 meridiem: 'short'
514             });
515             input = this.opt('slotLabelInterval');
516             this.labelInterval = input ?
517                 core.createDuration(input) :
518                 this.computeLabelInterval(slotDuration);
519         };
520         // Computes an automatic value for slotLabelInterval
521         TimeGrid.prototype.computeLabelInterval = function (slotDuration) {
522             var i;
523             var labelInterval;
524             var slotsPerLabel;
525             // find the smallest stock label interval that results in more than one slots-per-label
526             for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
527                 labelInterval = core.createDuration(AGENDA_STOCK_SUB_DURATIONS[i]);
528                 slotsPerLabel = core.wholeDivideDurations(labelInterval, slotDuration);
529                 if (slotsPerLabel !== null && slotsPerLabel > 1) {
530                     return labelInterval;
531                 }
532             }
533             return slotDuration; // fall back
534         };
535         /* Rendering
536         ------------------------------------------------------------------------------------------------------------------*/
537         TimeGrid.prototype.render = function (props) {
538             var cells = props.cells;
539             this.colCnt = cells.length;
540             this.renderSlats(props.dateProfile);
541             this.renderColumns(props.cells, props.dateProfile);
542             this.renderBusinessHours(props.businessHourSegs);
543             this.renderDateSelection(props.dateSelectionSegs);
544             this.renderFgEvents(props.fgEventSegs);
545             this.renderBgEvents(props.bgEventSegs);
546             this.renderEventSelection(props.eventSelection);
547             this.renderEventDrag(props.eventDrag);
548             this.renderEventResize(props.eventResize);
549         };
550         TimeGrid.prototype.destroy = function () {
551             _super.prototype.destroy.call(this);
552             // should unrender everything else too
553             this.renderSlats.unrender();
554             this.renderColumns.unrender();
555         };
556         TimeGrid.prototype.updateSize = function (isResize) {
557             var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer, mirrorRenderer = _a.mirrorRenderer;
558             if (isResize || this.isSlatSizesDirty) {
559                 this.buildSlatPositions();
560                 this.isSlatSizesDirty = false;
561             }
562             if (isResize || this.isColSizesDirty) {
563                 this.buildColPositions();
564                 this.isColSizesDirty = false;
565             }
566             fillRenderer.computeSizes(isResize);
567             eventRenderer.computeSizes(isResize);
568             mirrorRenderer.computeSizes(isResize);
569             fillRenderer.assignSizes(isResize);
570             eventRenderer.assignSizes(isResize);
571             mirrorRenderer.assignSizes(isResize);
572         };
573         TimeGrid.prototype._renderSlats = function (dateProfile) {
574             var theme = this.theme;
575             this.slatContainerEl.innerHTML =
576                 '<table class="' + theme.getClass('tableGrid') + '">' +
577                     this.renderSlatRowHtml(dateProfile) +
578                     '</table>';
579             this.slatEls = core.findElements(this.slatContainerEl, 'tr');
580             this.slatPositions = new core.PositionCache(this.el, this.slatEls, false, true // vertical
581             );
582             this.isSlatSizesDirty = true;
583         };
584         // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
585         TimeGrid.prototype.renderSlatRowHtml = function (dateProfile) {
586             var _a = this, dateEnv = _a.dateEnv, theme = _a.theme, isRtl = _a.isRtl;
587             var html = '';
588             var dayStart = core.startOfDay(dateProfile.renderRange.start);
589             var slotTime = dateProfile.minTime;
590             var slotIterator = core.createDuration(0);
591             var slotDate; // will be on the view's first day, but we only care about its time
592             var isLabeled;
593             var axisHtml;
594             // Calculate the time for each slot
595             while (core.asRoughMs(slotTime) < core.asRoughMs(dateProfile.maxTime)) {
596                 slotDate = dateEnv.add(dayStart, slotTime);
597                 isLabeled = core.wholeDivideDurations(slotIterator, this.labelInterval) !== null;
598                 axisHtml =
599                     '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '">' +
600                         (isLabeled ?
601                             '<span>' + // for matchCellWidths
602                                 core.htmlEscape(dateEnv.format(slotDate, this.labelFormat)) +
603                                 '</span>' :
604                             '') +
605                         '</td>';
606                 html +=
607                     '<tr data-time="' + core.formatIsoTimeString(slotDate) + '"' +
608                         (isLabeled ? '' : ' class="fc-minor"') +
609                         '>' +
610                         (!isRtl ? axisHtml : '') +
611                         '<td class="' + theme.getClass('widgetContent') + '"></td>' +
612                         (isRtl ? axisHtml : '') +
613                         '</tr>';
614                 slotTime = core.addDurations(slotTime, this.slotDuration);
615                 slotIterator = core.addDurations(slotIterator, this.slotDuration);
616             }
617             return html;
618         };
619         TimeGrid.prototype._renderColumns = function (cells, dateProfile) {
620             var _a = this, theme = _a.theme, dateEnv = _a.dateEnv, view = _a.view;
621             var bgRow = new daygrid.DayBgRow(this.context);
622             this.rootBgContainerEl.innerHTML =
623                 '<table class="' + theme.getClass('tableGrid') + '">' +
624                     bgRow.renderHtml({
625                         cells: cells,
626                         dateProfile: dateProfile,
627                         renderIntroHtml: this.renderProps.renderBgIntroHtml
628                     }) +
629                     '</table>';
630             this.colEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
631             for (var col = 0; col < this.colCnt; col++) {
632                 this.publiclyTrigger('dayRender', [
633                     {
634                         date: dateEnv.toDate(cells[col].date),
635                         el: this.colEls[col],
636                         view: view
637                     }
638                 ]);
639             }
640             if (this.isRtl) {
641                 this.colEls.reverse();
642             }
643             this.colPositions = new core.PositionCache(this.el, this.colEls, true, // horizontal
644             false);
645             this.renderContentSkeleton();
646             this.isColSizesDirty = true;
647         };
648         TimeGrid.prototype._unrenderColumns = function () {
649             this.unrenderContentSkeleton();
650         };
651         /* Content Skeleton
652         ------------------------------------------------------------------------------------------------------------------*/
653         // Renders the DOM that the view's content will live in
654         TimeGrid.prototype.renderContentSkeleton = function () {
655             var parts = [];
656             var skeletonEl;
657             parts.push(this.renderProps.renderIntroHtml());
658             for (var i = 0; i < this.colCnt; i++) {
659                 parts.push('<td>' +
660                     '<div class="fc-content-col">' +
661                     '<div class="fc-event-container fc-mirror-container"></div>' +
662                     '<div class="fc-event-container"></div>' +
663                     '<div class="fc-highlight-container"></div>' +
664                     '<div class="fc-bgevent-container"></div>' +
665                     '<div class="fc-business-container"></div>' +
666                     '</div>' +
667                     '</td>');
668             }
669             if (this.isRtl) {
670                 parts.reverse();
671             }
672             skeletonEl = this.contentSkeletonEl = core.htmlToElement('<div class="fc-content-skeleton">' +
673                 '<table>' +
674                 '<tr>' + parts.join('') + '</tr>' +
675                 '</table>' +
676                 '</div>');
677             this.colContainerEls = core.findElements(skeletonEl, '.fc-content-col');
678             this.mirrorContainerEls = core.findElements(skeletonEl, '.fc-mirror-container');
679             this.fgContainerEls = core.findElements(skeletonEl, '.fc-event-container:not(.fc-mirror-container)');
680             this.bgContainerEls = core.findElements(skeletonEl, '.fc-bgevent-container');
681             this.highlightContainerEls = core.findElements(skeletonEl, '.fc-highlight-container');
682             this.businessContainerEls = core.findElements(skeletonEl, '.fc-business-container');
683             if (this.isRtl) {
684                 this.colContainerEls.reverse();
685                 this.mirrorContainerEls.reverse();
686                 this.fgContainerEls.reverse();
687                 this.bgContainerEls.reverse();
688                 this.highlightContainerEls.reverse();
689                 this.businessContainerEls.reverse();
690             }
691             this.el.appendChild(skeletonEl);
692         };
693         TimeGrid.prototype.unrenderContentSkeleton = function () {
694             core.removeElement(this.contentSkeletonEl);
695         };
696         // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
697         TimeGrid.prototype.groupSegsByCol = function (segs) {
698             var segsByCol = [];
699             var i;
700             for (i = 0; i < this.colCnt; i++) {
701                 segsByCol.push([]);
702             }
703             for (i = 0; i < segs.length; i++) {
704                 segsByCol[segs[i].col].push(segs[i]);
705             }
706             return segsByCol;
707         };
708         // Given segments grouped by column, insert the segments' elements into a parallel array of container
709         // elements, each living within a column.
710         TimeGrid.prototype.attachSegsByCol = function (segsByCol, containerEls) {
711             var col;
712             var segs;
713             var i;
714             for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
715                 segs = segsByCol[col];
716                 for (i = 0; i < segs.length; i++) {
717                     containerEls[col].appendChild(segs[i].el);
718                 }
719             }
720         };
721         /* Now Indicator
722         ------------------------------------------------------------------------------------------------------------------*/
723         TimeGrid.prototype.getNowIndicatorUnit = function () {
724             return 'minute'; // will refresh on the minute
725         };
726         TimeGrid.prototype.renderNowIndicator = function (segs, date) {
727             // HACK: if date columns not ready for some reason (scheduler)
728             if (!this.colContainerEls) {
729                 return;
730             }
731             var top = this.computeDateTop(date);
732             var nodes = [];
733             var i;
734             // render lines within the columns
735             for (i = 0; i < segs.length; i++) {
736                 var lineEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-line' });
737                 lineEl.style.top = top + 'px';
738                 this.colContainerEls[segs[i].col].appendChild(lineEl);
739                 nodes.push(lineEl);
740             }
741             // render an arrow over the axis
742             if (segs.length > 0) { // is the current time in view?
743                 var arrowEl = core.createElement('div', { className: 'fc-now-indicator fc-now-indicator-arrow' });
744                 arrowEl.style.top = top + 'px';
745                 this.contentSkeletonEl.appendChild(arrowEl);
746                 nodes.push(arrowEl);
747             }
748             this.nowIndicatorEls = nodes;
749         };
750         TimeGrid.prototype.unrenderNowIndicator = function () {
751             if (this.nowIndicatorEls) {
752                 this.nowIndicatorEls.forEach(core.removeElement);
753                 this.nowIndicatorEls = null;
754             }
755         };
756         /* Coordinates
757         ------------------------------------------------------------------------------------------------------------------*/
758         TimeGrid.prototype.getTotalSlatHeight = function () {
759             return this.slatContainerEl.getBoundingClientRect().height;
760         };
761         // Computes the top coordinate, relative to the bounds of the grid, of the given date.
762         // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
763         TimeGrid.prototype.computeDateTop = function (when, startOfDayDate) {
764             if (!startOfDayDate) {
765                 startOfDayDate = core.startOfDay(when);
766             }
767             return this.computeTimeTop(core.createDuration(when.valueOf() - startOfDayDate.valueOf()));
768         };
769         // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
770         TimeGrid.prototype.computeTimeTop = function (duration) {
771             var len = this.slatEls.length;
772             var dateProfile = this.props.dateProfile;
773             var slatCoverage = (duration.milliseconds - core.asRoughMs(dateProfile.minTime)) / core.asRoughMs(this.slotDuration); // floating-point value of # of slots covered
774             var slatIndex;
775             var slatRemainder;
776             // compute a floating-point number for how many slats should be progressed through.
777             // from 0 to number of slats (inclusive)
778             // constrained because minTime/maxTime might be customized.
779             slatCoverage = Math.max(0, slatCoverage);
780             slatCoverage = Math.min(len, slatCoverage);
781             // an integer index of the furthest whole slat
782             // from 0 to number slats (*exclusive*, so len-1)
783             slatIndex = Math.floor(slatCoverage);
784             slatIndex = Math.min(slatIndex, len - 1);
785             // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
786             // could be 1.0 if slatCoverage is covering *all* the slots
787             slatRemainder = slatCoverage - slatIndex;
788             return this.slatPositions.tops[slatIndex] +
789                 this.slatPositions.getHeight(slatIndex) * slatRemainder;
790         };
791         // For each segment in an array, computes and assigns its top and bottom properties
792         TimeGrid.prototype.computeSegVerticals = function (segs) {
793             var eventMinHeight = this.opt('timeGridEventMinHeight');
794             var i;
795             var seg;
796             var dayDate;
797             for (i = 0; i < segs.length; i++) {
798                 seg = segs[i];
799                 dayDate = this.props.cells[seg.col].date;
800                 seg.top = this.computeDateTop(seg.start, dayDate);
801                 seg.bottom = Math.max(seg.top + eventMinHeight, this.computeDateTop(seg.end, dayDate));
802             }
803         };
804         // Given segments that already have their top/bottom properties computed, applies those values to
805         // the segments' elements.
806         TimeGrid.prototype.assignSegVerticals = function (segs) {
807             var i;
808             var seg;
809             for (i = 0; i < segs.length; i++) {
810                 seg = segs[i];
811                 core.applyStyle(seg.el, this.generateSegVerticalCss(seg));
812             }
813         };
814         // Generates an object with CSS properties for the top/bottom coordinates of a segment element
815         TimeGrid.prototype.generateSegVerticalCss = function (seg) {
816             return {
817                 top: seg.top,
818                 bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
819             };
820         };
821         /* Sizing
822         ------------------------------------------------------------------------------------------------------------------*/
823         TimeGrid.prototype.buildPositionCaches = function () {
824             this.buildColPositions();
825             this.buildSlatPositions();
826         };
827         TimeGrid.prototype.buildColPositions = function () {
828             this.colPositions.build();
829         };
830         TimeGrid.prototype.buildSlatPositions = function () {
831             this.slatPositions.build();
832         };
833         /* Hit System
834         ------------------------------------------------------------------------------------------------------------------*/
835         TimeGrid.prototype.positionToHit = function (positionLeft, positionTop) {
836             var _a = this, dateEnv = _a.dateEnv, snapsPerSlot = _a.snapsPerSlot, slatPositions = _a.slatPositions, colPositions = _a.colPositions;
837             var colIndex = colPositions.leftToIndex(positionLeft);
838             var slatIndex = slatPositions.topToIndex(positionTop);
839             if (colIndex != null && slatIndex != null) {
840                 var slatTop = slatPositions.tops[slatIndex];
841                 var slatHeight = slatPositions.getHeight(slatIndex);
842                 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
843                 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
844                 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
845                 var dayDate = this.props.cells[colIndex].date;
846                 var time = core.addDurations(this.props.dateProfile.minTime, core.multiplyDuration(this.snapDuration, snapIndex));
847                 var start = dateEnv.add(dayDate, time);
848                 var end = dateEnv.add(start, this.snapDuration);
849                 return {
850                     col: colIndex,
851                     dateSpan: {
852                         range: { start: start, end: end },
853                         allDay: false
854                     },
855                     dayEl: this.colEls[colIndex],
856                     relativeRect: {
857                         left: colPositions.lefts[colIndex],
858                         right: colPositions.rights[colIndex],
859                         top: slatTop,
860                         bottom: slatTop + slatHeight
861                     }
862                 };
863             }
864         };
865         /* Event Drag Visualization
866         ------------------------------------------------------------------------------------------------------------------*/
867         TimeGrid.prototype._renderEventDrag = function (state) {
868             if (state) {
869                 this.eventRenderer.hideByHash(state.affectedInstances);
870                 if (state.isEvent) {
871                     this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
872                 }
873                 else {
874                     this.fillRenderer.renderSegs('highlight', state.segs);
875                 }
876             }
877         };
878         TimeGrid.prototype._unrenderEventDrag = function (state) {
879             if (state) {
880                 this.eventRenderer.showByHash(state.affectedInstances);
881                 this.mirrorRenderer.unrender(state.segs, { isDragging: true, sourceSeg: state.sourceSeg });
882                 this.fillRenderer.unrender('highlight');
883             }
884         };
885         /* Event Resize Visualization
886         ------------------------------------------------------------------------------------------------------------------*/
887         TimeGrid.prototype._renderEventResize = function (state) {
888             if (state) {
889                 this.eventRenderer.hideByHash(state.affectedInstances);
890                 this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
891             }
892         };
893         TimeGrid.prototype._unrenderEventResize = function (state) {
894             if (state) {
895                 this.eventRenderer.showByHash(state.affectedInstances);
896                 this.mirrorRenderer.unrender(state.segs, { isResizing: true, sourceSeg: state.sourceSeg });
897             }
898         };
899         /* Selection
900         ------------------------------------------------------------------------------------------------------------------*/
901         // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
902         TimeGrid.prototype._renderDateSelection = function (segs) {
903             if (segs) {
904                 if (this.opt('selectMirror')) {
905                     this.mirrorRenderer.renderSegs(segs, { isSelecting: true });
906                 }
907                 else {
908                     this.fillRenderer.renderSegs('highlight', segs);
909                 }
910             }
911         };
912         TimeGrid.prototype._unrenderDateSelection = function (segs) {
913             this.mirrorRenderer.unrender(segs, { isSelecting: true });
914             this.fillRenderer.unrender('highlight');
915         };
916         return TimeGrid;
917     }(core.DateComponent));
918
919     var AllDaySplitter = /** @class */ (function (_super) {
920         __extends(AllDaySplitter, _super);
921         function AllDaySplitter() {
922             return _super !== null && _super.apply(this, arguments) || this;
923         }
924         AllDaySplitter.prototype.getKeyInfo = function () {
925             return {
926                 allDay: {},
927                 timed: {}
928             };
929         };
930         AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) {
931             if (dateSpan.allDay) {
932                 return ['allDay'];
933             }
934             else {
935                 return ['timed'];
936             }
937         };
938         AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) {
939             if (!eventDef.allDay) {
940                 return ['timed'];
941             }
942             else if (core.hasBgRendering(eventDef)) {
943                 return ['timed', 'allDay'];
944             }
945             else {
946                 return ['allDay'];
947             }
948         };
949         return AllDaySplitter;
950     }(core.Splitter));
951
952     var TIMEGRID_ALL_DAY_EVENT_LIMIT = 5;
953     var WEEK_HEADER_FORMAT = core.createFormatter({ week: 'short' });
954     /* An abstract class for all timegrid-related views. Displays one more columns with time slots running vertically.
955     ----------------------------------------------------------------------------------------------------------------------*/
956     // Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
957     // Responsible for managing width/height.
958     var TimeGridView = /** @class */ (function (_super) {
959         __extends(TimeGridView, _super);
960         function TimeGridView(context, viewSpec, dateProfileGenerator, parentEl) {
961             var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
962             _this.splitter = new AllDaySplitter();
963             /* Header Render Methods
964             ------------------------------------------------------------------------------------------------------------------*/
965             // Generates the HTML that will go before the day-of week header cells
966             _this.renderHeadIntroHtml = function () {
967                 var _a = _this, theme = _a.theme, dateEnv = _a.dateEnv;
968                 var range = _this.props.dateProfile.renderRange;
969                 var dayCnt = core.diffDays(range.start, range.end);
970                 var weekText;
971                 if (_this.opt('weekNumbers')) {
972                     weekText = dateEnv.format(range.start, WEEK_HEADER_FORMAT);
973                     return '' +
974                         '<th class="fc-axis fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '>' +
975                         core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
976                         _this, { date: range.start, type: 'week', forceOff: dayCnt > 1 }, core.htmlEscape(weekText) // inner HTML
977                         ) +
978                         '</th>';
979                 }
980                 else {
981                     return '<th class="fc-axis ' + theme.getClass('widgetHeader') + '" ' + _this.axisStyleAttr() + '></th>';
982                 }
983             };
984             /* Time Grid Render Methods
985             ------------------------------------------------------------------------------------------------------------------*/
986             // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
987             _this.renderTimeGridBgIntroHtml = function () {
988                 var theme = _this.theme;
989                 return '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '></td>';
990             };
991             // Generates the HTML that goes before all other types of cells.
992             // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
993             _this.renderTimeGridIntroHtml = function () {
994                 return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
995             };
996             /* Day Grid Render Methods
997             ------------------------------------------------------------------------------------------------------------------*/
998             // Generates the HTML that goes before the all-day cells
999             _this.renderDayGridBgIntroHtml = function () {
1000                 var theme = _this.theme;
1001                 return '' +
1002                     '<td class="fc-axis ' + theme.getClass('widgetContent') + '" ' + _this.axisStyleAttr() + '>' +
1003                     '<span>' + // needed for matchCellWidths
1004                     core.getAllDayHtml(_this) +
1005                     '</span>' +
1006                     '</td>';
1007             };
1008             // Generates the HTML that goes before all other types of cells.
1009             // Affects content-skeleton, mirror-skeleton, highlight-skeleton for both the time-grid and day-grid.
1010             _this.renderDayGridIntroHtml = function () {
1011                 return '<td class="fc-axis" ' + _this.axisStyleAttr() + '></td>';
1012             };
1013             _this.el.classList.add('fc-timeGrid-view');
1014             _this.el.innerHTML = _this.renderSkeletonHtml();
1015             _this.scroller = new core.ScrollComponent('hidden', // overflow x
1016             'auto' // overflow y
1017             );
1018             var timeGridWrapEl = _this.scroller.el;
1019             _this.el.querySelector('.fc-body > tr > td').appendChild(timeGridWrapEl);
1020             timeGridWrapEl.classList.add('fc-time-grid-container');
1021             var timeGridEl = core.createElement('div', { className: 'fc-time-grid' });
1022             timeGridWrapEl.appendChild(timeGridEl);
1023             _this.timeGrid = new TimeGrid(_this.context, timeGridEl, {
1024                 renderBgIntroHtml: _this.renderTimeGridBgIntroHtml,
1025                 renderIntroHtml: _this.renderTimeGridIntroHtml
1026             });
1027             if (_this.opt('allDaySlot')) { // should we display the "all-day" area?
1028                 _this.dayGrid = new daygrid.DayGrid(// the all-day subcomponent of this view
1029                 _this.context, _this.el.querySelector('.fc-day-grid'), {
1030                     renderNumberIntroHtml: _this.renderDayGridIntroHtml,
1031                     renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
1032                     renderIntroHtml: _this.renderDayGridIntroHtml,
1033                     colWeekNumbersVisible: false,
1034                     cellWeekNumbersVisible: false
1035                 });
1036                 // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
1037                 var dividerEl = _this.el.querySelector('.fc-divider');
1038                 _this.dayGrid.bottomCoordPadding = dividerEl.getBoundingClientRect().height;
1039             }
1040             return _this;
1041         }
1042         TimeGridView.prototype.destroy = function () {
1043             _super.prototype.destroy.call(this);
1044             this.timeGrid.destroy();
1045             if (this.dayGrid) {
1046                 this.dayGrid.destroy();
1047             }
1048             this.scroller.destroy();
1049         };
1050         /* Rendering
1051         ------------------------------------------------------------------------------------------------------------------*/
1052         // Builds the HTML skeleton for the view.
1053         // The day-grid and time-grid components will render inside containers defined by this HTML.
1054         TimeGridView.prototype.renderSkeletonHtml = function () {
1055             var theme = this.theme;
1056             return '' +
1057                 '<table class="' + theme.getClass('tableGrid') + '">' +
1058                 (this.opt('columnHeader') ?
1059                     '<thead class="fc-head">' +
1060                         '<tr>' +
1061                         '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
1062                         '</tr>' +
1063                         '</thead>' :
1064                     '') +
1065                 '<tbody class="fc-body">' +
1066                 '<tr>' +
1067                 '<td class="' + theme.getClass('widgetContent') + '">' +
1068                 (this.opt('allDaySlot') ?
1069                     '<div class="fc-day-grid"></div>' +
1070                         '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" />' :
1071                     '') +
1072                 '</td>' +
1073                 '</tr>' +
1074                 '</tbody>' +
1075                 '</table>';
1076         };
1077         /* Now Indicator
1078         ------------------------------------------------------------------------------------------------------------------*/
1079         TimeGridView.prototype.getNowIndicatorUnit = function () {
1080             return this.timeGrid.getNowIndicatorUnit();
1081         };
1082         // subclasses should implement
1083         // renderNowIndicator(date: DateMarker) {
1084         // }
1085         TimeGridView.prototype.unrenderNowIndicator = function () {
1086             this.timeGrid.unrenderNowIndicator();
1087         };
1088         /* Dimensions
1089         ------------------------------------------------------------------------------------------------------------------*/
1090         TimeGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
1091             _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
1092             this.timeGrid.updateSize(isResize);
1093             if (this.dayGrid) {
1094                 this.dayGrid.updateSize(isResize);
1095             }
1096         };
1097         // Adjusts the vertical dimensions of the view to the specified values
1098         TimeGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
1099             var _this = this;
1100             var eventLimit;
1101             var scrollerHeight;
1102             var scrollbarWidths;
1103             // make all axis cells line up
1104             this.axisWidth = core.matchCellWidths(core.findElements(this.el, '.fc-axis'));
1105             // hack to give the view some height prior to timeGrid's columns being rendered
1106             // TODO: separate setting height from scroller VS timeGrid.
1107             if (!this.timeGrid.colEls) {
1108                 if (!isAuto) {
1109                     scrollerHeight = this.computeScrollerHeight(viewHeight);
1110                     this.scroller.setHeight(scrollerHeight);
1111                 }
1112                 return;
1113             }
1114             // set of fake row elements that must compensate when scroller has scrollbars
1115             var noScrollRowEls = core.findElements(this.el, '.fc-row').filter(function (node) {
1116                 return !_this.scroller.el.contains(node);
1117             });
1118             // reset all dimensions back to the original state
1119             this.timeGrid.bottomRuleEl.style.display = 'none'; // will be shown later if this <hr> is necessary
1120             this.scroller.clear(); // sets height to 'auto' and clears overflow
1121             noScrollRowEls.forEach(core.uncompensateScroll);
1122             // limit number of events in the all-day area
1123             if (this.dayGrid) {
1124                 this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
1125                 eventLimit = this.opt('eventLimit');
1126                 if (eventLimit && typeof eventLimit !== 'number') {
1127                     eventLimit = TIMEGRID_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
1128                 }
1129                 if (eventLimit) {
1130                     this.dayGrid.limitRows(eventLimit);
1131                 }
1132             }
1133             if (!isAuto) { // should we force dimensions of the scroll container?
1134                 scrollerHeight = this.computeScrollerHeight(viewHeight);
1135                 this.scroller.setHeight(scrollerHeight);
1136                 scrollbarWidths = this.scroller.getScrollbarWidths();
1137                 if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
1138                     // make the all-day and header rows lines up
1139                     noScrollRowEls.forEach(function (rowEl) {
1140                         core.compensateScroll(rowEl, scrollbarWidths);
1141                     });
1142                     // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
1143                     // and reapply the desired height to the scroller.
1144                     scrollerHeight = this.computeScrollerHeight(viewHeight);
1145                     this.scroller.setHeight(scrollerHeight);
1146                 }
1147                 // guarantees the same scrollbar widths
1148                 this.scroller.lockOverflow(scrollbarWidths);
1149                 // if there's any space below the slats, show the horizontal rule.
1150                 // this won't cause any new overflow, because lockOverflow already called.
1151                 if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
1152                     this.timeGrid.bottomRuleEl.style.display = '';
1153                 }
1154             }
1155         };
1156         // given a desired total height of the view, returns what the height of the scroller should be
1157         TimeGridView.prototype.computeScrollerHeight = function (viewHeight) {
1158             return viewHeight -
1159                 core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
1160         };
1161         /* Scroll
1162         ------------------------------------------------------------------------------------------------------------------*/
1163         // Computes the initial pre-configured scroll state prior to allowing the user to change it
1164         TimeGridView.prototype.computeDateScroll = function (duration) {
1165             var top = this.timeGrid.computeTimeTop(duration);
1166             // zoom can give weird floating-point values. rather scroll a little bit further
1167             top = Math.ceil(top);
1168             if (top) {
1169                 top++; // to overcome top border that slots beyond the first have. looks better
1170             }
1171             return { top: top };
1172         };
1173         TimeGridView.prototype.queryDateScroll = function () {
1174             return { top: this.scroller.getScrollTop() };
1175         };
1176         TimeGridView.prototype.applyDateScroll = function (scroll) {
1177             if (scroll.top !== undefined) {
1178                 this.scroller.setScrollTop(scroll.top);
1179             }
1180         };
1181         // Generates an HTML attribute string for setting the width of the axis, if it is known
1182         TimeGridView.prototype.axisStyleAttr = function () {
1183             if (this.axisWidth != null) {
1184                 return 'style="width:' + this.axisWidth + 'px"';
1185             }
1186             return '';
1187         };
1188         return TimeGridView;
1189     }(core.View));
1190     TimeGridView.prototype.usesMinMaxTime = true; // indicates that minTime/maxTime affects rendering
1191
1192     var SimpleTimeGrid = /** @class */ (function (_super) {
1193         __extends(SimpleTimeGrid, _super);
1194         function SimpleTimeGrid(context, timeGrid) {
1195             var _this = _super.call(this, context, timeGrid.el) || this;
1196             _this.buildDayRanges = core.memoize(buildDayRanges);
1197             _this.slicer = new TimeGridSlicer();
1198             _this.timeGrid = timeGrid;
1199             context.calendar.registerInteractiveComponent(_this, {
1200                 el: _this.timeGrid.el
1201             });
1202             return _this;
1203         }
1204         SimpleTimeGrid.prototype.destroy = function () {
1205             _super.prototype.destroy.call(this);
1206             this.calendar.unregisterInteractiveComponent(this);
1207         };
1208         SimpleTimeGrid.prototype.render = function (props) {
1209             var dateProfile = props.dateProfile, dayTable = props.dayTable;
1210             var dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv);
1211             this.timeGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), { dateProfile: dateProfile, cells: dayTable.cells[0] }));
1212         };
1213         SimpleTimeGrid.prototype.renderNowIndicator = function (date) {
1214             this.timeGrid.renderNowIndicator(this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges), date);
1215         };
1216         SimpleTimeGrid.prototype.buildPositionCaches = function () {
1217             this.timeGrid.buildPositionCaches();
1218         };
1219         SimpleTimeGrid.prototype.queryHit = function (positionLeft, positionTop) {
1220             var rawHit = this.timeGrid.positionToHit(positionLeft, positionTop);
1221             if (rawHit) {
1222                 return {
1223                     component: this.timeGrid,
1224                     dateSpan: rawHit.dateSpan,
1225                     dayEl: rawHit.dayEl,
1226                     rect: {
1227                         left: rawHit.relativeRect.left,
1228                         right: rawHit.relativeRect.right,
1229                         top: rawHit.relativeRect.top,
1230                         bottom: rawHit.relativeRect.bottom
1231                     },
1232                     layer: 0
1233                 };
1234             }
1235         };
1236         return SimpleTimeGrid;
1237     }(core.DateComponent));
1238     function buildDayRanges(dayTable, dateProfile, dateEnv) {
1239         var ranges = [];
1240         for (var _i = 0, _a = dayTable.headerDates; _i < _a.length; _i++) {
1241             var date = _a[_i];
1242             ranges.push({
1243                 start: dateEnv.add(date, dateProfile.minTime),
1244                 end: dateEnv.add(date, dateProfile.maxTime)
1245             });
1246         }
1247         return ranges;
1248     }
1249     var TimeGridSlicer = /** @class */ (function (_super) {
1250         __extends(TimeGridSlicer, _super);
1251         function TimeGridSlicer() {
1252             return _super !== null && _super.apply(this, arguments) || this;
1253         }
1254         TimeGridSlicer.prototype.sliceRange = function (range, dayRanges) {
1255             var segs = [];
1256             for (var col = 0; col < dayRanges.length; col++) {
1257                 var segRange = core.intersectRanges(range, dayRanges[col]);
1258                 if (segRange) {
1259                     segs.push({
1260                         start: segRange.start,
1261                         end: segRange.end,
1262                         isStart: segRange.start.valueOf() === range.start.valueOf(),
1263                         isEnd: segRange.end.valueOf() === range.end.valueOf(),
1264                         col: col
1265                     });
1266                 }
1267             }
1268             return segs;
1269         };
1270         return TimeGridSlicer;
1271     }(core.Slicer));
1272
1273     var TimeGridView$1 = /** @class */ (function (_super) {
1274         __extends(TimeGridView, _super);
1275         function TimeGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
1276             var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
1277             _this.buildDayTable = core.memoize(buildDayTable);
1278             if (_this.opt('columnHeader')) {
1279                 _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
1280             }
1281             _this.simpleTimeGrid = new SimpleTimeGrid(_this.context, _this.timeGrid);
1282             if (_this.dayGrid) {
1283                 _this.simpleDayGrid = new daygrid.SimpleDayGrid(_this.context, _this.dayGrid);
1284             }
1285             return _this;
1286         }
1287         TimeGridView.prototype.destroy = function () {
1288             _super.prototype.destroy.call(this);
1289             if (this.header) {
1290                 this.header.destroy();
1291             }
1292             this.simpleTimeGrid.destroy();
1293             if (this.simpleDayGrid) {
1294                 this.simpleDayGrid.destroy();
1295             }
1296         };
1297         TimeGridView.prototype.render = function (props) {
1298             _super.prototype.render.call(this, props); // for flags for updateSize
1299             var dateProfile = this.props.dateProfile;
1300             var dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator);
1301             var splitProps = this.splitter.splitProps(props);
1302             if (this.header) {
1303                 this.header.receiveProps({
1304                     dateProfile: dateProfile,
1305                     dates: dayTable.headerDates,
1306                     datesRepDistinctDays: true,
1307                     renderIntroHtml: this.renderHeadIntroHtml
1308                 });
1309             }
1310             this.simpleTimeGrid.receiveProps(__assign({}, splitProps['timed'], { dateProfile: dateProfile,
1311                 dayTable: dayTable }));
1312             if (this.simpleDayGrid) {
1313                 this.simpleDayGrid.receiveProps(__assign({}, splitProps['allDay'], { dateProfile: dateProfile,
1314                     dayTable: dayTable, nextDayThreshold: this.nextDayThreshold, isRigid: false }));
1315             }
1316         };
1317         TimeGridView.prototype.renderNowIndicator = function (date) {
1318             this.simpleTimeGrid.renderNowIndicator(date);
1319         };
1320         return TimeGridView;
1321     }(TimeGridView));
1322     function buildDayTable(dateProfile, dateProfileGenerator) {
1323         var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
1324         return new core.DayTable(daySeries, false);
1325     }
1326
1327     var main = core.createPlugin({
1328         defaultView: 'timeGridWeek',
1329         views: {
1330             timeGrid: {
1331                 class: TimeGridView$1,
1332                 allDaySlot: true,
1333                 slotDuration: '00:30:00',
1334                 slotEventOverlap: true // a bad name. confused with overlap/constraint system
1335             },
1336             timeGridDay: {
1337                 type: 'timeGrid',
1338                 duration: { days: 1 }
1339             },
1340             timeGridWeek: {
1341                 type: 'timeGrid',
1342                 duration: { weeks: 1 }
1343             }
1344         }
1345     });
1346
1347     exports.AbstractTimeGridView = TimeGridView;
1348     exports.TimeGrid = TimeGrid;
1349     exports.TimeGridSlicer = TimeGridSlicer;
1350     exports.TimeGridView = TimeGridView$1;
1351     exports.buildDayRanges = buildDayRanges;
1352     exports.buildDayTable = buildDayTable;
1353     exports.default = main;
1354
1355     Object.defineProperty(exports, '__esModule', { value: true });
1356
1357 }));