1 | import * as preact from 'preact';
|
2 | import { Component, createElement, isValidElement, Fragment } from 'preact';
|
3 | import { createPortal } from 'preact/compat';
|
4 |
|
5 | const styleTexts = [];
|
6 | const styleEls = new Map();
|
7 | function injectStyles(styleText) {
|
8 | styleTexts.push(styleText);
|
9 | styleEls.forEach((styleEl) => {
|
10 | appendStylesTo(styleEl, styleText);
|
11 | });
|
12 | }
|
13 | function ensureElHasStyles(el) {
|
14 | if (el.isConnected &&
|
15 | el.getRootNode
|
16 | ) {
|
17 | registerStylesRoot(el.getRootNode());
|
18 | }
|
19 | }
|
20 | function registerStylesRoot(rootNode) {
|
21 | let styleEl = styleEls.get(rootNode);
|
22 | if (!styleEl || !styleEl.isConnected) {
|
23 | styleEl = rootNode.querySelector('style[data-fullcalendar]');
|
24 | if (!styleEl) {
|
25 | styleEl = document.createElement('style');
|
26 | styleEl.setAttribute('data-fullcalendar', '');
|
27 | const nonce = getNonceValue();
|
28 | if (nonce) {
|
29 | styleEl.nonce = nonce;
|
30 | }
|
31 | const parentEl = rootNode === document ? document.head : rootNode;
|
32 | const insertBefore = rootNode === document
|
33 | ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style')
|
34 | : parentEl.firstChild;
|
35 | parentEl.insertBefore(styleEl, insertBefore);
|
36 | }
|
37 | styleEls.set(rootNode, styleEl);
|
38 | hydrateStylesRoot(styleEl);
|
39 | }
|
40 | }
|
41 | function hydrateStylesRoot(styleEl) {
|
42 | for (const styleText of styleTexts) {
|
43 | appendStylesTo(styleEl, styleText);
|
44 | }
|
45 | }
|
46 | function appendStylesTo(styleEl, styleText) {
|
47 | const { sheet } = styleEl;
|
48 | const ruleCnt = sheet.cssRules.length;
|
49 | styleText.split('}').forEach((styleStr, i) => {
|
50 | styleStr = styleStr.trim();
|
51 | if (styleStr) {
|
52 | sheet.insertRule(styleStr + '}', ruleCnt + i);
|
53 | }
|
54 | });
|
55 | }
|
56 |
|
57 |
|
58 | let queriedNonceValue;
|
59 | function getNonceValue() {
|
60 | if (queriedNonceValue === undefined) {
|
61 | queriedNonceValue = queryNonceValue();
|
62 | }
|
63 | return queriedNonceValue;
|
64 | }
|
65 |
|
66 |
|
67 |
|
68 | function queryNonceValue() {
|
69 | const metaWithNonce = document.querySelector('meta[name="csp-nonce"]');
|
70 | if (metaWithNonce && metaWithNonce.hasAttribute('content')) {
|
71 | return metaWithNonce.getAttribute('content');
|
72 | }
|
73 | const elWithNonce = document.querySelector('script[nonce]');
|
74 | if (elWithNonce) {
|
75 | return elWithNonce.nonce || '';
|
76 | }
|
77 | return '';
|
78 | }
|
79 |
|
80 |
|
81 | if (typeof document !== 'undefined') {
|
82 | registerStylesRoot(document);
|
83 | }
|
84 |
|
85 | var css_248z = ":root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url(\"data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\") format(\"truetype\")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:\"\\e900\"}.fc-icon-chevron-right:before{content:\"\\e901\"}.fc-icon-chevrons-left:before{content:\"\\e902\"}.fc-icon-chevrons-right:before{content:\"\\e903\"}.fc-icon-minus-square:before{content:\"\\e904\"}.fc-icon-plus-square:before{content:\"\\e905\"}.fc-icon-x:before{content:\"\\e906\"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:\"\";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:\"\";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}";
|
86 | injectStyles(css_248z);
|
87 |
|
88 | class DelayedRunner {
|
89 | constructor(drainedOption) {
|
90 | this.drainedOption = drainedOption;
|
91 | this.isRunning = false;
|
92 | this.isDirty = false;
|
93 | this.pauseDepths = {};
|
94 | this.timeoutId = 0;
|
95 | }
|
96 | request(delay) {
|
97 | this.isDirty = true;
|
98 | if (!this.isPaused()) {
|
99 | this.clearTimeout();
|
100 | if (delay == null) {
|
101 | this.tryDrain();
|
102 | }
|
103 | else {
|
104 | this.timeoutId = setTimeout(
|
105 | this.tryDrain.bind(this), delay);
|
106 | }
|
107 | }
|
108 | }
|
109 | pause(scope = '') {
|
110 | let { pauseDepths } = this;
|
111 | pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
|
112 | this.clearTimeout();
|
113 | }
|
114 | resume(scope = '', force) {
|
115 | let { pauseDepths } = this;
|
116 | if (scope in pauseDepths) {
|
117 | if (force) {
|
118 | delete pauseDepths[scope];
|
119 | }
|
120 | else {
|
121 | pauseDepths[scope] -= 1;
|
122 | let depth = pauseDepths[scope];
|
123 | if (depth <= 0) {
|
124 | delete pauseDepths[scope];
|
125 | }
|
126 | }
|
127 | this.tryDrain();
|
128 | }
|
129 | }
|
130 | isPaused() {
|
131 | return Object.keys(this.pauseDepths).length;
|
132 | }
|
133 | tryDrain() {
|
134 | if (!this.isRunning && !this.isPaused()) {
|
135 | this.isRunning = true;
|
136 | while (this.isDirty) {
|
137 | this.isDirty = false;
|
138 | this.drained();
|
139 | }
|
140 | this.isRunning = false;
|
141 | }
|
142 | }
|
143 | clear() {
|
144 | this.clearTimeout();
|
145 | this.isDirty = false;
|
146 | this.pauseDepths = {};
|
147 | }
|
148 | clearTimeout() {
|
149 | if (this.timeoutId) {
|
150 | clearTimeout(this.timeoutId);
|
151 | this.timeoutId = 0;
|
152 | }
|
153 | }
|
154 | drained() {
|
155 | if (this.drainedOption) {
|
156 | this.drainedOption();
|
157 | }
|
158 | }
|
159 | }
|
160 |
|
161 | function removeElement(el) {
|
162 | if (el.parentNode) {
|
163 | el.parentNode.removeChild(el);
|
164 | }
|
165 | }
|
166 |
|
167 |
|
168 | function elementClosest(el, selector) {
|
169 | if (el.closest) {
|
170 | return el.closest(selector);
|
171 |
|
172 |
|
173 | }
|
174 | if (!document.documentElement.contains(el)) {
|
175 | return null;
|
176 | }
|
177 | do {
|
178 | if (elementMatches(el, selector)) {
|
179 | return el;
|
180 | }
|
181 | el = (el.parentElement || el.parentNode);
|
182 | } while (el !== null && el.nodeType === 1);
|
183 | return null;
|
184 | }
|
185 | function elementMatches(el, selector) {
|
186 | let method = el.matches || el.matchesSelector || el.msMatchesSelector;
|
187 | return method.call(el, selector);
|
188 | }
|
189 |
|
190 |
|
191 |
|
192 | function findElements(container, selector) {
|
193 | let containers = container instanceof HTMLElement ? [container] : container;
|
194 | let allMatches = [];
|
195 | for (let i = 0; i < containers.length; i += 1) {
|
196 | let matches = containers[i].querySelectorAll(selector);
|
197 | for (let j = 0; j < matches.length; j += 1) {
|
198 | allMatches.push(matches[j]);
|
199 | }
|
200 | }
|
201 | return allMatches;
|
202 | }
|
203 |
|
204 |
|
205 | function findDirectChildren(parent, selector) {
|
206 | let parents = parent instanceof HTMLElement ? [parent] : parent;
|
207 | let allMatches = [];
|
208 | for (let i = 0; i < parents.length; i += 1) {
|
209 | let childNodes = parents[i].children;
|
210 | for (let j = 0; j < childNodes.length; j += 1) {
|
211 | let childNode = childNodes[j];
|
212 | if (!selector || elementMatches(childNode, selector)) {
|
213 | allMatches.push(childNode);
|
214 | }
|
215 | }
|
216 | }
|
217 | return allMatches;
|
218 | }
|
219 |
|
220 |
|
221 | const PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
|
222 | function applyStyle(el, props) {
|
223 | for (let propName in props) {
|
224 | applyStyleProp(el, propName, props[propName]);
|
225 | }
|
226 | }
|
227 | function applyStyleProp(el, name, val) {
|
228 | if (val == null) {
|
229 | el.style[name] = '';
|
230 | }
|
231 | else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
|
232 | el.style[name] = `${val}px`;
|
233 | }
|
234 | else {
|
235 | el.style[name] = val;
|
236 | }
|
237 | }
|
238 |
|
239 |
|
240 |
|
241 |
|
242 |
|
243 | function getEventTargetViaRoot(ev) {
|
244 | var _a, _b;
|
245 | return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target;
|
246 | }
|
247 |
|
248 | let guid$1 = 0;
|
249 | function getUniqueDomId() {
|
250 | guid$1 += 1;
|
251 | return 'fc-dom-' + guid$1;
|
252 | }
|
253 |
|
254 |
|
255 | function preventDefault(ev) {
|
256 | ev.preventDefault();
|
257 | }
|
258 |
|
259 |
|
260 | function buildDelegationHandler(selector, handler) {
|
261 | return (ev) => {
|
262 | let matchedChild = elementClosest(ev.target, selector);
|
263 | if (matchedChild) {
|
264 | handler.call(matchedChild, ev, matchedChild);
|
265 | }
|
266 | };
|
267 | }
|
268 | function listenBySelector(container, eventType, selector, handler) {
|
269 | let attachedHandler = buildDelegationHandler(selector, handler);
|
270 | container.addEventListener(eventType, attachedHandler);
|
271 | return () => {
|
272 | container.removeEventListener(eventType, attachedHandler);
|
273 | };
|
274 | }
|
275 | function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
|
276 | let currentMatchedChild;
|
277 | return listenBySelector(container, 'mouseover', selector, (mouseOverEv, matchedChild) => {
|
278 | if (matchedChild !== currentMatchedChild) {
|
279 | currentMatchedChild = matchedChild;
|
280 | onMouseEnter(mouseOverEv, matchedChild);
|
281 | let realOnMouseLeave = (mouseLeaveEv) => {
|
282 | currentMatchedChild = null;
|
283 | onMouseLeave(mouseLeaveEv, matchedChild);
|
284 | matchedChild.removeEventListener('mouseleave', realOnMouseLeave);
|
285 | };
|
286 |
|
287 | matchedChild.addEventListener('mouseleave', realOnMouseLeave);
|
288 | }
|
289 | });
|
290 | }
|
291 |
|
292 |
|
293 | const transitionEventNames = [
|
294 | 'webkitTransitionEnd',
|
295 | 'otransitionend',
|
296 | 'oTransitionEnd',
|
297 | 'msTransitionEnd',
|
298 | 'transitionend',
|
299 | ];
|
300 |
|
301 | function whenTransitionDone(el, callback) {
|
302 | let realCallback = (ev) => {
|
303 | callback(ev);
|
304 | transitionEventNames.forEach((eventName) => {
|
305 | el.removeEventListener(eventName, realCallback);
|
306 | });
|
307 | };
|
308 | transitionEventNames.forEach((eventName) => {
|
309 | el.addEventListener(eventName, realCallback);
|
310 | });
|
311 | }
|
312 |
|
313 |
|
314 | function createAriaClickAttrs(handler) {
|
315 | return Object.assign({ onClick: handler }, createAriaKeyboardAttrs(handler));
|
316 | }
|
317 | function createAriaKeyboardAttrs(handler) {
|
318 | return {
|
319 | tabIndex: 0,
|
320 | onKeyDown(ev) {
|
321 | if (ev.key === 'Enter' || ev.key === ' ') {
|
322 | handler(ev);
|
323 | ev.preventDefault();
|
324 | }
|
325 | },
|
326 | };
|
327 | }
|
328 |
|
329 | let guidNumber = 0;
|
330 | function guid() {
|
331 | guidNumber += 1;
|
332 | return String(guidNumber);
|
333 | }
|
334 |
|
335 |
|
336 |
|
337 | function disableCursor() {
|
338 | document.body.classList.add('fc-not-allowed');
|
339 | }
|
340 |
|
341 | function enableCursor() {
|
342 | document.body.classList.remove('fc-not-allowed');
|
343 | }
|
344 |
|
345 |
|
346 | function preventSelection(el) {
|
347 | el.style.userSelect = 'none';
|
348 | el.style.webkitUserSelect = 'none';
|
349 | el.addEventListener('selectstart', preventDefault);
|
350 | }
|
351 | function allowSelection(el) {
|
352 | el.style.userSelect = '';
|
353 | el.style.webkitUserSelect = '';
|
354 | el.removeEventListener('selectstart', preventDefault);
|
355 | }
|
356 |
|
357 |
|
358 | function preventContextMenu(el) {
|
359 | el.addEventListener('contextmenu', preventDefault);
|
360 | }
|
361 | function allowContextMenu(el) {
|
362 | el.removeEventListener('contextmenu', preventDefault);
|
363 | }
|
364 | function parseFieldSpecs(input) {
|
365 | let specs = [];
|
366 | let tokens = [];
|
367 | let i;
|
368 | let token;
|
369 | if (typeof input === 'string') {
|
370 | tokens = input.split(/\s*,\s*/);
|
371 | }
|
372 | else if (typeof input === 'function') {
|
373 | tokens = [input];
|
374 | }
|
375 | else if (Array.isArray(input)) {
|
376 | tokens = input;
|
377 | }
|
378 | for (i = 0; i < tokens.length; i += 1) {
|
379 | token = tokens[i];
|
380 | if (typeof token === 'string') {
|
381 | specs.push(token.charAt(0) === '-' ?
|
382 | { field: token.substring(1), order: -1 } :
|
383 | { field: token, order: 1 });
|
384 | }
|
385 | else if (typeof token === 'function') {
|
386 | specs.push({ func: token });
|
387 | }
|
388 | }
|
389 | return specs;
|
390 | }
|
391 | function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
|
392 | let i;
|
393 | let cmp;
|
394 | for (i = 0; i < fieldSpecs.length; i += 1) {
|
395 | cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
|
396 | if (cmp) {
|
397 | return cmp;
|
398 | }
|
399 | }
|
400 | return 0;
|
401 | }
|
402 | function compareByFieldSpec(obj0, obj1, fieldSpec) {
|
403 | if (fieldSpec.func) {
|
404 | return fieldSpec.func(obj0, obj1);
|
405 | }
|
406 | return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])
|
407 | * (fieldSpec.order || 1);
|
408 | }
|
409 | function flexibleCompare(a, b) {
|
410 | if (!a && !b) {
|
411 | return 0;
|
412 | }
|
413 | if (b == null) {
|
414 | return -1;
|
415 | }
|
416 | if (a == null) {
|
417 | return 1;
|
418 | }
|
419 | if (typeof a === 'string' || typeof b === 'string') {
|
420 | return String(a).localeCompare(String(b));
|
421 | }
|
422 | return a - b;
|
423 | }
|
424 |
|
425 |
|
426 | function padStart(val, len) {
|
427 | let s = String(val);
|
428 | return '000'.substr(0, len - s.length) + s;
|
429 | }
|
430 | function formatWithOrdinals(formatter, args, fallbackText) {
|
431 | if (typeof formatter === 'function') {
|
432 | return formatter(...args);
|
433 | }
|
434 | if (typeof formatter === 'string') {
|
435 | return args.reduce((str, arg, index) => (str.replace('$' + index, arg || '')), formatter);
|
436 | }
|
437 | return fallbackText;
|
438 | }
|
439 |
|
440 |
|
441 | function compareNumbers(a, b) {
|
442 | return a - b;
|
443 | }
|
444 | function isInt(n) {
|
445 | return n % 1 === 0;
|
446 | }
|
447 |
|
448 |
|
449 | function computeSmallestCellWidth(cellEl) {
|
450 | let allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
|
451 | let contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
|
452 | if (!allWidthEl) {
|
453 | throw new Error('needs fc-scrollgrid-shrink-frame className');
|
454 | }
|
455 | if (!contentWidthEl) {
|
456 | throw new Error('needs fc-scrollgrid-shrink-cushion className');
|
457 | }
|
458 | return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width +
|
459 | contentWidthEl.getBoundingClientRect().width;
|
460 | }
|
461 |
|
462 | const INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
|
463 | const PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
|
464 |
|
465 | function createDuration(input, unit) {
|
466 | if (typeof input === 'string') {
|
467 | return parseString(input);
|
468 | }
|
469 | if (typeof input === 'object' && input) {
|
470 | return parseObject(input);
|
471 | }
|
472 | if (typeof input === 'number') {
|
473 | return parseObject({ [unit || 'milliseconds']: input });
|
474 | }
|
475 | return null;
|
476 | }
|
477 | function parseString(s) {
|
478 | let m = PARSE_RE.exec(s);
|
479 | if (m) {
|
480 | let sign = m[1] ? -1 : 1;
|
481 | return {
|
482 | years: 0,
|
483 | months: 0,
|
484 | days: sign * (m[2] ? parseInt(m[2], 10) : 0),
|
485 | milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 +
|
486 | (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 +
|
487 | (m[5] ? parseInt(m[5], 10) : 0) * 1000 +
|
488 | (m[6] ? parseInt(m[6], 10) : 0)
|
489 | ),
|
490 | };
|
491 | }
|
492 | return null;
|
493 | }
|
494 | function parseObject(obj) {
|
495 | let duration = {
|
496 | years: obj.years || obj.year || 0,
|
497 | months: obj.months || obj.month || 0,
|
498 | days: obj.days || obj.day || 0,
|
499 | milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 +
|
500 | (obj.minutes || obj.minute || 0) * 60 * 1000 +
|
501 | (obj.seconds || obj.second || 0) * 1000 +
|
502 | (obj.milliseconds || obj.millisecond || obj.ms || 0),
|
503 | };
|
504 | let weeks = obj.weeks || obj.week;
|
505 | if (weeks) {
|
506 | duration.days += weeks * 7;
|
507 | duration.specifiedWeeks = true;
|
508 | }
|
509 | return duration;
|
510 | }
|
511 |
|
512 | function durationsEqual(d0, d1) {
|
513 | return d0.years === d1.years &&
|
514 | d0.months === d1.months &&
|
515 | d0.days === d1.days &&
|
516 | d0.milliseconds === d1.milliseconds;
|
517 | }
|
518 | function asCleanDays(dur) {
|
519 | if (!dur.years && !dur.months && !dur.milliseconds) {
|
520 | return dur.days;
|
521 | }
|
522 | return 0;
|
523 | }
|
524 |
|
525 | function addDurations(d0, d1) {
|
526 | return {
|
527 | years: d0.years + d1.years,
|
528 | months: d0.months + d1.months,
|
529 | days: d0.days + d1.days,
|
530 | milliseconds: d0.milliseconds + d1.milliseconds,
|
531 | };
|
532 | }
|
533 | function subtractDurations(d1, d0) {
|
534 | return {
|
535 | years: d1.years - d0.years,
|
536 | months: d1.months - d0.months,
|
537 | days: d1.days - d0.days,
|
538 | milliseconds: d1.milliseconds - d0.milliseconds,
|
539 | };
|
540 | }
|
541 | function multiplyDuration(d, n) {
|
542 | return {
|
543 | years: d.years * n,
|
544 | months: d.months * n,
|
545 | days: d.days * n,
|
546 | milliseconds: d.milliseconds * n,
|
547 | };
|
548 | }
|
549 |
|
550 |
|
551 | function asRoughYears(dur) {
|
552 | return asRoughDays(dur) / 365;
|
553 | }
|
554 | function asRoughMonths(dur) {
|
555 | return asRoughDays(dur) / 30;
|
556 | }
|
557 | function asRoughDays(dur) {
|
558 | return asRoughMs(dur) / 864e5;
|
559 | }
|
560 | function asRoughMinutes(dur) {
|
561 | return asRoughMs(dur) / (1000 * 60);
|
562 | }
|
563 | function asRoughSeconds(dur) {
|
564 | return asRoughMs(dur) / 1000;
|
565 | }
|
566 | function asRoughMs(dur) {
|
567 | return dur.years * (365 * 864e5) +
|
568 | dur.months * (30 * 864e5) +
|
569 | dur.days * 864e5 +
|
570 | dur.milliseconds;
|
571 | }
|
572 |
|
573 | function wholeDivideDurations(numerator, denominator) {
|
574 | let res = null;
|
575 | for (let i = 0; i < INTERNAL_UNITS.length; i += 1) {
|
576 | let unit = INTERNAL_UNITS[i];
|
577 | if (denominator[unit]) {
|
578 | let localRes = numerator[unit] / denominator[unit];
|
579 | if (!isInt(localRes) || (res !== null && res !== localRes)) {
|
580 | return null;
|
581 | }
|
582 | res = localRes;
|
583 | }
|
584 | else if (numerator[unit]) {
|
585 |
|
586 | return null;
|
587 | }
|
588 | }
|
589 | return res;
|
590 | }
|
591 | function greatestDurationDenominator(dur) {
|
592 | let ms = dur.milliseconds;
|
593 | if (ms) {
|
594 | if (ms % 1000 !== 0) {
|
595 | return { unit: 'millisecond', value: ms };
|
596 | }
|
597 | if (ms % (1000 * 60) !== 0) {
|
598 | return { unit: 'second', value: ms / 1000 };
|
599 | }
|
600 | if (ms % (1000 * 60 * 60) !== 0) {
|
601 | return { unit: 'minute', value: ms / (1000 * 60) };
|
602 | }
|
603 | if (ms) {
|
604 | return { unit: 'hour', value: ms / (1000 * 60 * 60) };
|
605 | }
|
606 | }
|
607 | if (dur.days) {
|
608 | if (dur.specifiedWeeks && dur.days % 7 === 0) {
|
609 | return { unit: 'week', value: dur.days / 7 };
|
610 | }
|
611 | return { unit: 'day', value: dur.days };
|
612 | }
|
613 | if (dur.months) {
|
614 | return { unit: 'month', value: dur.months };
|
615 | }
|
616 | if (dur.years) {
|
617 | return { unit: 'year', value: dur.years };
|
618 | }
|
619 | return { unit: 'millisecond', value: 0 };
|
620 | }
|
621 |
|
622 |
|
623 | function removeExact(array, exactVal) {
|
624 | let removeCnt = 0;
|
625 | let i = 0;
|
626 | while (i < array.length) {
|
627 | if (array[i] === exactVal) {
|
628 | array.splice(i, 1);
|
629 | removeCnt += 1;
|
630 | }
|
631 | else {
|
632 | i += 1;
|
633 | }
|
634 | }
|
635 | return removeCnt;
|
636 | }
|
637 | function isArraysEqual(a0, a1, equalityFunc) {
|
638 | if (a0 === a1) {
|
639 | return true;
|
640 | }
|
641 | let len = a0.length;
|
642 | let i;
|
643 | if (len !== a1.length) {
|
644 | return false;
|
645 | }
|
646 | for (i = 0; i < len; i += 1) {
|
647 | if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
|
648 | return false;
|
649 | }
|
650 | }
|
651 | return true;
|
652 | }
|
653 |
|
654 | const DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
|
655 |
|
656 | function addWeeks(m, n) {
|
657 | let a = dateToUtcArray(m);
|
658 | a[2] += n * 7;
|
659 | return arrayToUtcDate(a);
|
660 | }
|
661 | function addDays(m, n) {
|
662 | let a = dateToUtcArray(m);
|
663 | a[2] += n;
|
664 | return arrayToUtcDate(a);
|
665 | }
|
666 | function addMs(m, n) {
|
667 | let a = dateToUtcArray(m);
|
668 | a[6] += n;
|
669 | return arrayToUtcDate(a);
|
670 | }
|
671 |
|
672 |
|
673 | function diffWeeks(m0, m1) {
|
674 | return diffDays(m0, m1) / 7;
|
675 | }
|
676 | function diffDays(m0, m1) {
|
677 | return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
|
678 | }
|
679 | function diffHours(m0, m1) {
|
680 | return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
|
681 | }
|
682 | function diffMinutes(m0, m1) {
|
683 | return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
|
684 | }
|
685 | function diffSeconds(m0, m1) {
|
686 | return (m1.valueOf() - m0.valueOf()) / 1000;
|
687 | }
|
688 | function diffDayAndTime(m0, m1) {
|
689 | let m0day = startOfDay(m0);
|
690 | let m1day = startOfDay(m1);
|
691 | return {
|
692 | years: 0,
|
693 | months: 0,
|
694 | days: Math.round(diffDays(m0day, m1day)),
|
695 | milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),
|
696 | };
|
697 | }
|
698 |
|
699 | function diffWholeWeeks(m0, m1) {
|
700 | let d = diffWholeDays(m0, m1);
|
701 | if (d !== null && d % 7 === 0) {
|
702 | return d / 7;
|
703 | }
|
704 | return null;
|
705 | }
|
706 | function diffWholeDays(m0, m1) {
|
707 | if (timeAsMs(m0) === timeAsMs(m1)) {
|
708 | return Math.round(diffDays(m0, m1));
|
709 | }
|
710 | return null;
|
711 | }
|
712 |
|
713 | function startOfDay(m) {
|
714 | return arrayToUtcDate([
|
715 | m.getUTCFullYear(),
|
716 | m.getUTCMonth(),
|
717 | m.getUTCDate(),
|
718 | ]);
|
719 | }
|
720 | function startOfHour(m) {
|
721 | return arrayToUtcDate([
|
722 | m.getUTCFullYear(),
|
723 | m.getUTCMonth(),
|
724 | m.getUTCDate(),
|
725 | m.getUTCHours(),
|
726 | ]);
|
727 | }
|
728 | function startOfMinute(m) {
|
729 | return arrayToUtcDate([
|
730 | m.getUTCFullYear(),
|
731 | m.getUTCMonth(),
|
732 | m.getUTCDate(),
|
733 | m.getUTCHours(),
|
734 | m.getUTCMinutes(),
|
735 | ]);
|
736 | }
|
737 | function startOfSecond(m) {
|
738 | return arrayToUtcDate([
|
739 | m.getUTCFullYear(),
|
740 | m.getUTCMonth(),
|
741 | m.getUTCDate(),
|
742 | m.getUTCHours(),
|
743 | m.getUTCMinutes(),
|
744 | m.getUTCSeconds(),
|
745 | ]);
|
746 | }
|
747 |
|
748 | function weekOfYear(marker, dow, doy) {
|
749 | let y = marker.getUTCFullYear();
|
750 | let w = weekOfGivenYear(marker, y, dow, doy);
|
751 | if (w < 1) {
|
752 | return weekOfGivenYear(marker, y - 1, dow, doy);
|
753 | }
|
754 | let nextW = weekOfGivenYear(marker, y + 1, dow, doy);
|
755 | if (nextW >= 1) {
|
756 | return Math.min(w, nextW);
|
757 | }
|
758 | return w;
|
759 | }
|
760 | function weekOfGivenYear(marker, year, dow, doy) {
|
761 | let firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
|
762 | let dayStart = startOfDay(marker);
|
763 | let days = Math.round(diffDays(firstWeekStart, dayStart));
|
764 | return Math.floor(days / 7) + 1;
|
765 | }
|
766 |
|
767 | function firstWeekOffset(year, dow, doy) {
|
768 |
|
769 | let fwd = 7 + dow - doy;
|
770 |
|
771 | let fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
|
772 | return -fwdlw + fwd - 1;
|
773 | }
|
774 |
|
775 | function dateToLocalArray(date) {
|
776 | return [
|
777 | date.getFullYear(),
|
778 | date.getMonth(),
|
779 | date.getDate(),
|
780 | date.getHours(),
|
781 | date.getMinutes(),
|
782 | date.getSeconds(),
|
783 | date.getMilliseconds(),
|
784 | ];
|
785 | }
|
786 | function arrayToLocalDate(a) {
|
787 | return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2],
|
788 | a[3] || 0, a[4] || 0, a[5] || 0);
|
789 | }
|
790 | function dateToUtcArray(date) {
|
791 | return [
|
792 | date.getUTCFullYear(),
|
793 | date.getUTCMonth(),
|
794 | date.getUTCDate(),
|
795 | date.getUTCHours(),
|
796 | date.getUTCMinutes(),
|
797 | date.getUTCSeconds(),
|
798 | date.getUTCMilliseconds(),
|
799 | ];
|
800 | }
|
801 | function arrayToUtcDate(a) {
|
802 |
|
803 |
|
804 | if (a.length === 1) {
|
805 | a = a.concat([0]);
|
806 | }
|
807 | return new Date(Date.UTC(...a));
|
808 | }
|
809 |
|
810 | function isValidDate(m) {
|
811 | return !isNaN(m.valueOf());
|
812 | }
|
813 | function timeAsMs(m) {
|
814 | return m.getUTCHours() * 1000 * 60 * 60 +
|
815 | m.getUTCMinutes() * 1000 * 60 +
|
816 | m.getUTCSeconds() * 1000 +
|
817 | m.getUTCMilliseconds();
|
818 | }
|
819 |
|
820 |
|
821 | function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {
|
822 | let s = marker.toISOString();
|
823 | s = s.replace('.000', '');
|
824 | if (stripZeroTime) {
|
825 | s = s.replace('T00:00:00Z', '');
|
826 | }
|
827 | if (s.length > 10) {
|
828 | if (timeZoneOffset == null) {
|
829 | s = s.replace('Z', '');
|
830 | }
|
831 | else if (timeZoneOffset !== 0) {
|
832 | s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
|
833 | }
|
834 |
|
835 | }
|
836 | return s;
|
837 | }
|
838 |
|
839 |
|
840 |
|
841 | function formatDayString(marker) {
|
842 | return marker.toISOString().replace(/T.*$/, '');
|
843 | }
|
844 | function formatIsoMonthStr(marker) {
|
845 | return marker.toISOString().match(/^\d{4}-\d{2}/)[0];
|
846 | }
|
847 |
|
848 | function formatIsoTimeString(marker) {
|
849 | return padStart(marker.getUTCHours(), 2) + ':' +
|
850 | padStart(marker.getUTCMinutes(), 2) + ':' +
|
851 | padStart(marker.getUTCSeconds(), 2);
|
852 | }
|
853 | function formatTimeZoneOffset(minutes, doIso = false) {
|
854 | let sign = minutes < 0 ? '-' : '+';
|
855 | let abs = Math.abs(minutes);
|
856 | let hours = Math.floor(abs / 60);
|
857 | let mins = Math.round(abs % 60);
|
858 | if (doIso) {
|
859 | return `${sign + padStart(hours, 2)}:${padStart(mins, 2)}`;
|
860 | }
|
861 | return `GMT${sign}${hours}${mins ? `:${padStart(mins, 2)}` : ''}`;
|
862 | }
|
863 |
|
864 | function memoize(workerFunc, resEquality, teardownFunc) {
|
865 | let currentArgs;
|
866 | let currentRes;
|
867 | return function (...newArgs) {
|
868 | if (!currentArgs) {
|
869 | currentRes = workerFunc.apply(this, newArgs);
|
870 | }
|
871 | else if (!isArraysEqual(currentArgs, newArgs)) {
|
872 | if (teardownFunc) {
|
873 | teardownFunc(currentRes);
|
874 | }
|
875 | let res = workerFunc.apply(this, newArgs);
|
876 | if (!resEquality || !resEquality(res, currentRes)) {
|
877 | currentRes = res;
|
878 | }
|
879 | }
|
880 | currentArgs = newArgs;
|
881 | return currentRes;
|
882 | };
|
883 | }
|
884 | function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
|
885 | let currentArg;
|
886 | let currentRes;
|
887 | return (newArg) => {
|
888 | if (!currentArg) {
|
889 | currentRes = workerFunc.call(this, newArg);
|
890 | }
|
891 | else if (!isPropsEqual(currentArg, newArg)) {
|
892 | if (teardownFunc) {
|
893 | teardownFunc(currentRes);
|
894 | }
|
895 | let res = workerFunc.call(this, newArg);
|
896 | if (!resEquality || !resEquality(res, currentRes)) {
|
897 | currentRes = res;
|
898 | }
|
899 | }
|
900 | currentArg = newArg;
|
901 | return currentRes;
|
902 | };
|
903 | }
|
904 | function memoizeArraylike(// used at all?
|
905 | workerFunc, resEquality, teardownFunc) {
|
906 | let currentArgSets = [];
|
907 | let currentResults = [];
|
908 | return (newArgSets) => {
|
909 | let currentLen = currentArgSets.length;
|
910 | let newLen = newArgSets.length;
|
911 | let i = 0;
|
912 | for (; i < currentLen; i += 1) {
|
913 | if (!newArgSets[i]) {
|
914 | if (teardownFunc) {
|
915 | teardownFunc(currentResults[i]);
|
916 | }
|
917 | }
|
918 | else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
|
919 | if (teardownFunc) {
|
920 | teardownFunc(currentResults[i]);
|
921 | }
|
922 | let res = workerFunc.apply(this, newArgSets[i]);
|
923 | if (!resEquality || !resEquality(res, currentResults[i])) {
|
924 | currentResults[i] = res;
|
925 | }
|
926 | }
|
927 | }
|
928 | for (; i < newLen; i += 1) {
|
929 | currentResults[i] = workerFunc.apply(this, newArgSets[i]);
|
930 | }
|
931 | currentArgSets = newArgSets;
|
932 | currentResults.splice(newLen);
|
933 | return currentResults;
|
934 | };
|
935 | }
|
936 | function memoizeHashlike(workerFunc, resEquality, teardownFunc) {
|
937 | let currentArgHash = {};
|
938 | let currentResHash = {};
|
939 | return (newArgHash) => {
|
940 | let newResHash = {};
|
941 | for (let key in newArgHash) {
|
942 | if (!currentResHash[key]) {
|
943 | newResHash[key] = workerFunc.apply(this, newArgHash[key]);
|
944 | }
|
945 | else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
|
946 | if (teardownFunc) {
|
947 | teardownFunc(currentResHash[key]);
|
948 | }
|
949 | let res = workerFunc.apply(this, newArgHash[key]);
|
950 | newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))
|
951 | ? currentResHash[key]
|
952 | : res;
|
953 | }
|
954 | else {
|
955 | newResHash[key] = currentResHash[key];
|
956 | }
|
957 | }
|
958 | currentArgHash = newArgHash;
|
959 | currentResHash = newResHash;
|
960 | return newResHash;
|
961 | };
|
962 | }
|
963 |
|
964 | const EXTENDED_SETTINGS_AND_SEVERITIES = {
|
965 | week: 3,
|
966 | separator: 0,
|
967 | omitZeroMinute: 0,
|
968 | meridiem: 0,
|
969 | omitCommas: 0,
|
970 | };
|
971 | const STANDARD_DATE_PROP_SEVERITIES = {
|
972 | timeZoneName: 7,
|
973 | era: 6,
|
974 | year: 5,
|
975 | month: 4,
|
976 | day: 2,
|
977 | weekday: 2,
|
978 | hour: 1,
|
979 | minute: 1,
|
980 | second: 1,
|
981 | };
|
982 | const MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
|
983 | const COMMA_RE = /,/g;
|
984 | const MULTI_SPACE_RE = /\s+/g;
|
985 | const LTR_RE = /\u200e/g;
|
986 | const UTC_RE = /UTC|GMT/;
|
987 | class NativeFormatter {
|
988 | constructor(formatSettings) {
|
989 | let standardDateProps = {};
|
990 | let extendedSettings = {};
|
991 | let severity = 0;
|
992 | for (let name in formatSettings) {
|
993 | if (name in EXTENDED_SETTINGS_AND_SEVERITIES) {
|
994 | extendedSettings[name] = formatSettings[name];
|
995 | severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name], severity);
|
996 | }
|
997 | else {
|
998 | standardDateProps[name] = formatSettings[name];
|
999 | if (name in STANDARD_DATE_PROP_SEVERITIES) {
|
1000 | severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name], severity);
|
1001 | }
|
1002 | }
|
1003 | }
|
1004 | this.standardDateProps = standardDateProps;
|
1005 | this.extendedSettings = extendedSettings;
|
1006 | this.severity = severity;
|
1007 | this.buildFormattingFunc = memoize(buildFormattingFunc);
|
1008 | }
|
1009 | format(date, context) {
|
1010 | return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
|
1011 | }
|
1012 | formatRange(start, end, context, betterDefaultSeparator) {
|
1013 | let { standardDateProps, extendedSettings } = this;
|
1014 | let diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
|
1015 | if (!diffSeverity) {
|
1016 | return this.format(start, context);
|
1017 | }
|
1018 | let biggestUnitForPartial = diffSeverity;
|
1019 | if (biggestUnitForPartial > 1 &&
|
1020 | (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&
|
1021 | (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&
|
1022 | (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
|
1023 | biggestUnitForPartial = 1;
|
1024 | }
|
1025 | let full0 = this.format(start, context);
|
1026 | let full1 = this.format(end, context);
|
1027 | if (full0 === full1) {
|
1028 | return full0;
|
1029 | }
|
1030 | let partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
|
1031 | let partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
|
1032 | let partial0 = partialFormattingFunc(start);
|
1033 | let partial1 = partialFormattingFunc(end);
|
1034 | let insertion = findCommonInsertion(full0, partial0, full1, partial1);
|
1035 | let separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
|
1036 | if (insertion) {
|
1037 | return insertion.before + partial0 + separator + partial1 + insertion.after;
|
1038 | }
|
1039 | return full0 + separator + full1;
|
1040 | }
|
1041 | getLargestUnit() {
|
1042 | switch (this.severity) {
|
1043 | case 7:
|
1044 | case 6:
|
1045 | case 5:
|
1046 | return 'year';
|
1047 | case 4:
|
1048 | return 'month';
|
1049 | case 3:
|
1050 | return 'week';
|
1051 | case 2:
|
1052 | return 'day';
|
1053 | default:
|
1054 | return 'time';
|
1055 | }
|
1056 | }
|
1057 | }
|
1058 | function buildFormattingFunc(standardDateProps, extendedSettings, context) {
|
1059 | let standardDatePropCnt = Object.keys(standardDateProps).length;
|
1060 | if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
|
1061 | return (date) => (formatTimeZoneOffset(date.timeZoneOffset));
|
1062 | }
|
1063 | if (standardDatePropCnt === 0 && extendedSettings.week) {
|
1064 | return (date) => (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week));
|
1065 | }
|
1066 | return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
|
1067 | }
|
1068 | function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
|
1069 | standardDateProps = Object.assign({}, standardDateProps);
|
1070 | extendedSettings = Object.assign({}, extendedSettings);
|
1071 | sanitizeSettings(standardDateProps, extendedSettings);
|
1072 | standardDateProps.timeZone = 'UTC';
|
1073 | let normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
|
1074 | let zeroFormat;
|
1075 | if (extendedSettings.omitZeroMinute) {
|
1076 | let zeroProps = Object.assign({}, standardDateProps);
|
1077 | delete zeroProps.minute;
|
1078 | zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
|
1079 | }
|
1080 | return (date) => {
|
1081 | let { marker } = date;
|
1082 | let format;
|
1083 | if (zeroFormat && !marker.getUTCMinutes()) {
|
1084 | format = zeroFormat;
|
1085 | }
|
1086 | else {
|
1087 | format = normalFormat;
|
1088 | }
|
1089 | let s = format.format(marker);
|
1090 | return postProcess(s, date, standardDateProps, extendedSettings, context);
|
1091 | };
|
1092 | }
|
1093 | function sanitizeSettings(standardDateProps, extendedSettings) {
|
1094 |
|
1095 |
|
1096 | if (standardDateProps.timeZoneName) {
|
1097 | if (!standardDateProps.hour) {
|
1098 | standardDateProps.hour = '2-digit';
|
1099 | }
|
1100 | if (!standardDateProps.minute) {
|
1101 | standardDateProps.minute = '2-digit';
|
1102 | }
|
1103 | }
|
1104 |
|
1105 | if (standardDateProps.timeZoneName === 'long') {
|
1106 | standardDateProps.timeZoneName = 'short';
|
1107 | }
|
1108 |
|
1109 | if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
|
1110 | delete extendedSettings.omitZeroMinute;
|
1111 | }
|
1112 | }
|
1113 | function postProcess(s, date, standardDateProps, extendedSettings, context) {
|
1114 | s = s.replace(LTR_RE, '');
|
1115 | if (standardDateProps.timeZoneName === 'short') {
|
1116 | s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?
|
1117 | 'UTC' :
|
1118 | formatTimeZoneOffset(date.timeZoneOffset));
|
1119 | }
|
1120 | if (extendedSettings.omitCommas) {
|
1121 | s = s.replace(COMMA_RE, '').trim();
|
1122 | }
|
1123 | if (extendedSettings.omitZeroMinute) {
|
1124 | s = s.replace(':00', '');
|
1125 | }
|
1126 |
|
1127 |
|
1128 | if (extendedSettings.meridiem === false) {
|
1129 | s = s.replace(MERIDIEM_RE, '').trim();
|
1130 | }
|
1131 | else if (extendedSettings.meridiem === 'narrow') {
|
1132 | s = s.replace(MERIDIEM_RE, (m0, m1) => m1.toLocaleLowerCase());
|
1133 | }
|
1134 | else if (extendedSettings.meridiem === 'short') {
|
1135 | s = s.replace(MERIDIEM_RE, (m0, m1) => `${m1.toLocaleLowerCase()}m`);
|
1136 | }
|
1137 | else if (extendedSettings.meridiem === 'lowercase') {
|
1138 | s = s.replace(MERIDIEM_RE, (m0) => m0.toLocaleLowerCase());
|
1139 | }
|
1140 | s = s.replace(MULTI_SPACE_RE, ' ');
|
1141 | s = s.trim();
|
1142 | return s;
|
1143 | }
|
1144 | function injectTzoStr(s, tzoStr) {
|
1145 | let replaced = false;
|
1146 | s = s.replace(UTC_RE, () => {
|
1147 | replaced = true;
|
1148 | return tzoStr;
|
1149 | });
|
1150 |
|
1151 | if (!replaced) {
|
1152 | s += ` ${tzoStr}`;
|
1153 | }
|
1154 | return s;
|
1155 | }
|
1156 | function formatWeekNumber(num, weekText, weekTextLong, locale, display) {
|
1157 | let parts = [];
|
1158 | if (display === 'long') {
|
1159 | parts.push(weekTextLong);
|
1160 | }
|
1161 | else if (display === 'short' || display === 'narrow') {
|
1162 | parts.push(weekText);
|
1163 | }
|
1164 | if (display === 'long' || display === 'short') {
|
1165 | parts.push(' ');
|
1166 | }
|
1167 | parts.push(locale.simpleNumberFormat.format(num));
|
1168 | if (locale.options.direction === 'rtl') {
|
1169 | parts.reverse();
|
1170 | }
|
1171 | return parts.join('');
|
1172 | }
|
1173 |
|
1174 |
|
1175 |
|
1176 |
|
1177 | function computeMarkerDiffSeverity(d0, d1, ca) {
|
1178 | if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
|
1179 | return 5;
|
1180 | }
|
1181 | if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
|
1182 | return 4;
|
1183 | }
|
1184 | if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
|
1185 | return 2;
|
1186 | }
|
1187 | if (timeAsMs(d0) !== timeAsMs(d1)) {
|
1188 | return 1;
|
1189 | }
|
1190 | return 0;
|
1191 | }
|
1192 | function computePartialFormattingOptions(options, biggestUnit) {
|
1193 | let partialOptions = {};
|
1194 | for (let name in options) {
|
1195 | if (!(name in STANDARD_DATE_PROP_SEVERITIES) ||
|
1196 | STANDARD_DATE_PROP_SEVERITIES[name] <= biggestUnit) {
|
1197 | partialOptions[name] = options[name];
|
1198 | }
|
1199 | }
|
1200 | return partialOptions;
|
1201 | }
|
1202 | function findCommonInsertion(full0, partial0, full1, partial1) {
|
1203 | let i0 = 0;
|
1204 | while (i0 < full0.length) {
|
1205 | let found0 = full0.indexOf(partial0, i0);
|
1206 | if (found0 === -1) {
|
1207 | break;
|
1208 | }
|
1209 | let before0 = full0.substr(0, found0);
|
1210 | i0 = found0 + partial0.length;
|
1211 | let after0 = full0.substr(i0);
|
1212 | let i1 = 0;
|
1213 | while (i1 < full1.length) {
|
1214 | let found1 = full1.indexOf(partial1, i1);
|
1215 | if (found1 === -1) {
|
1216 | break;
|
1217 | }
|
1218 | let before1 = full1.substr(0, found1);
|
1219 | i1 = found1 + partial1.length;
|
1220 | let after1 = full1.substr(i1);
|
1221 | if (before0 === before1 && after0 === after1) {
|
1222 | return {
|
1223 | before: before0,
|
1224 | after: after0,
|
1225 | };
|
1226 | }
|
1227 | }
|
1228 | }
|
1229 | return null;
|
1230 | }
|
1231 |
|
1232 | function expandZonedMarker(dateInfo, calendarSystem) {
|
1233 | let a = calendarSystem.markerToArray(dateInfo.marker);
|
1234 | return {
|
1235 | marker: dateInfo.marker,
|
1236 | timeZoneOffset: dateInfo.timeZoneOffset,
|
1237 | array: a,
|
1238 | year: a[0],
|
1239 | month: a[1],
|
1240 | day: a[2],
|
1241 | hour: a[3],
|
1242 | minute: a[4],
|
1243 | second: a[5],
|
1244 | millisecond: a[6],
|
1245 | };
|
1246 | }
|
1247 |
|
1248 | function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
|
1249 | let startInfo = expandZonedMarker(start, context.calendarSystem);
|
1250 | let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
|
1251 | return {
|
1252 | date: startInfo,
|
1253 | start: startInfo,
|
1254 | end: endInfo,
|
1255 | timeZone: context.timeZone,
|
1256 | localeCodes: context.locale.codes,
|
1257 | defaultSeparator: betterDefaultSeparator || context.defaultSeparator,
|
1258 | };
|
1259 | }
|
1260 |
|
1261 |
|
1262 |
|
1263 |
|
1264 |
|
1265 |
|
1266 |
|
1267 |
|
1268 | class CmdFormatter {
|
1269 | constructor(cmdStr) {
|
1270 | this.cmdStr = cmdStr;
|
1271 | }
|
1272 | format(date, context, betterDefaultSeparator) {
|
1273 | return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
|
1274 | }
|
1275 | formatRange(start, end, context, betterDefaultSeparator) {
|
1276 | return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
|
1277 | }
|
1278 | }
|
1279 |
|
1280 | class FuncFormatter {
|
1281 | constructor(func) {
|
1282 | this.func = func;
|
1283 | }
|
1284 | format(date, context, betterDefaultSeparator) {
|
1285 | return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
|
1286 | }
|
1287 | formatRange(start, end, context, betterDefaultSeparator) {
|
1288 | return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
|
1289 | }
|
1290 | }
|
1291 |
|
1292 | function createFormatter(input) {
|
1293 | if (typeof input === 'object' && input) {
|
1294 | return new NativeFormatter(input);
|
1295 | }
|
1296 | if (typeof input === 'string') {
|
1297 | return new CmdFormatter(input);
|
1298 | }
|
1299 | if (typeof input === 'function') {
|
1300 | return new FuncFormatter(input);
|
1301 | }
|
1302 | return null;
|
1303 | }
|
1304 |
|
1305 |
|
1306 |
|
1307 | const BASE_OPTION_REFINERS = {
|
1308 | navLinkDayClick: identity,
|
1309 | navLinkWeekClick: identity,
|
1310 | duration: createDuration,
|
1311 | bootstrapFontAwesome: identity,
|
1312 | buttonIcons: identity,
|
1313 | customButtons: identity,
|
1314 | defaultAllDayEventDuration: createDuration,
|
1315 | defaultTimedEventDuration: createDuration,
|
1316 | nextDayThreshold: createDuration,
|
1317 | scrollTime: createDuration,
|
1318 | scrollTimeReset: Boolean,
|
1319 | slotMinTime: createDuration,
|
1320 | slotMaxTime: createDuration,
|
1321 | dayPopoverFormat: createFormatter,
|
1322 | slotDuration: createDuration,
|
1323 | snapDuration: createDuration,
|
1324 | headerToolbar: identity,
|
1325 | footerToolbar: identity,
|
1326 | defaultRangeSeparator: String,
|
1327 | titleRangeSeparator: String,
|
1328 | forceEventDuration: Boolean,
|
1329 | dayHeaders: Boolean,
|
1330 | dayHeaderFormat: createFormatter,
|
1331 | dayHeaderClassNames: identity,
|
1332 | dayHeaderContent: identity,
|
1333 | dayHeaderDidMount: identity,
|
1334 | dayHeaderWillUnmount: identity,
|
1335 | dayCellClassNames: identity,
|
1336 | dayCellContent: identity,
|
1337 | dayCellDidMount: identity,
|
1338 | dayCellWillUnmount: identity,
|
1339 | initialView: String,
|
1340 | aspectRatio: Number,
|
1341 | weekends: Boolean,
|
1342 | weekNumberCalculation: identity,
|
1343 | weekNumbers: Boolean,
|
1344 | weekNumberClassNames: identity,
|
1345 | weekNumberContent: identity,
|
1346 | weekNumberDidMount: identity,
|
1347 | weekNumberWillUnmount: identity,
|
1348 | editable: Boolean,
|
1349 | viewClassNames: identity,
|
1350 | viewDidMount: identity,
|
1351 | viewWillUnmount: identity,
|
1352 | nowIndicator: Boolean,
|
1353 | nowIndicatorClassNames: identity,
|
1354 | nowIndicatorContent: identity,
|
1355 | nowIndicatorDidMount: identity,
|
1356 | nowIndicatorWillUnmount: identity,
|
1357 | showNonCurrentDates: Boolean,
|
1358 | lazyFetching: Boolean,
|
1359 | startParam: String,
|
1360 | endParam: String,
|
1361 | timeZoneParam: String,
|
1362 | timeZone: String,
|
1363 | locales: identity,
|
1364 | locale: identity,
|
1365 | themeSystem: String,
|
1366 | dragRevertDuration: Number,
|
1367 | dragScroll: Boolean,
|
1368 | allDayMaintainDuration: Boolean,
|
1369 | unselectAuto: Boolean,
|
1370 | dropAccept: identity,
|
1371 | eventOrder: parseFieldSpecs,
|
1372 | eventOrderStrict: Boolean,
|
1373 | handleWindowResize: Boolean,
|
1374 | windowResizeDelay: Number,
|
1375 | longPressDelay: Number,
|
1376 | eventDragMinDistance: Number,
|
1377 | expandRows: Boolean,
|
1378 | height: identity,
|
1379 | contentHeight: identity,
|
1380 | direction: String,
|
1381 | weekNumberFormat: createFormatter,
|
1382 | eventResizableFromStart: Boolean,
|
1383 | displayEventTime: Boolean,
|
1384 | displayEventEnd: Boolean,
|
1385 | weekText: String,
|
1386 | weekTextLong: String,
|
1387 | progressiveEventRendering: Boolean,
|
1388 | businessHours: identity,
|
1389 | initialDate: identity,
|
1390 | now: identity,
|
1391 | eventDataTransform: identity,
|
1392 | stickyHeaderDates: identity,
|
1393 | stickyFooterScrollbar: identity,
|
1394 | viewHeight: identity,
|
1395 | defaultAllDay: Boolean,
|
1396 | eventSourceFailure: identity,
|
1397 | eventSourceSuccess: identity,
|
1398 | eventDisplay: String,
|
1399 | eventStartEditable: Boolean,
|
1400 | eventDurationEditable: Boolean,
|
1401 | eventOverlap: identity,
|
1402 | eventConstraint: identity,
|
1403 | eventAllow: identity,
|
1404 | eventBackgroundColor: String,
|
1405 | eventBorderColor: String,
|
1406 | eventTextColor: String,
|
1407 | eventColor: String,
|
1408 | eventClassNames: identity,
|
1409 | eventContent: identity,
|
1410 | eventDidMount: identity,
|
1411 | eventWillUnmount: identity,
|
1412 | selectConstraint: identity,
|
1413 | selectOverlap: identity,
|
1414 | selectAllow: identity,
|
1415 | droppable: Boolean,
|
1416 | unselectCancel: String,
|
1417 | slotLabelFormat: identity,
|
1418 | slotLaneClassNames: identity,
|
1419 | slotLaneContent: identity,
|
1420 | slotLaneDidMount: identity,
|
1421 | slotLaneWillUnmount: identity,
|
1422 | slotLabelClassNames: identity,
|
1423 | slotLabelContent: identity,
|
1424 | slotLabelDidMount: identity,
|
1425 | slotLabelWillUnmount: identity,
|
1426 | dayMaxEvents: identity,
|
1427 | dayMaxEventRows: identity,
|
1428 | dayMinWidth: Number,
|
1429 | slotLabelInterval: createDuration,
|
1430 | allDayText: String,
|
1431 | allDayClassNames: identity,
|
1432 | allDayContent: identity,
|
1433 | allDayDidMount: identity,
|
1434 | allDayWillUnmount: identity,
|
1435 | slotMinWidth: Number,
|
1436 | navLinks: Boolean,
|
1437 | eventTimeFormat: createFormatter,
|
1438 | rerenderDelay: Number,
|
1439 | moreLinkText: identity,
|
1440 | moreLinkHint: identity,
|
1441 | selectMinDistance: Number,
|
1442 | selectable: Boolean,
|
1443 | selectLongPressDelay: Number,
|
1444 | eventLongPressDelay: Number,
|
1445 | selectMirror: Boolean,
|
1446 | eventMaxStack: Number,
|
1447 | eventMinHeight: Number,
|
1448 | eventMinWidth: Number,
|
1449 | eventShortHeight: Number,
|
1450 | slotEventOverlap: Boolean,
|
1451 | plugins: identity,
|
1452 | firstDay: Number,
|
1453 | dayCount: Number,
|
1454 | dateAlignment: String,
|
1455 | dateIncrement: createDuration,
|
1456 | hiddenDays: identity,
|
1457 | fixedWeekCount: Boolean,
|
1458 | validRange: identity,
|
1459 | visibleRange: identity,
|
1460 | titleFormat: identity,
|
1461 | eventInteractive: Boolean,
|
1462 |
|
1463 | noEventsText: String,
|
1464 | viewHint: identity,
|
1465 | navLinkHint: identity,
|
1466 | closeHint: String,
|
1467 | timeHint: String,
|
1468 | eventHint: String,
|
1469 | moreLinkClick: identity,
|
1470 | moreLinkClassNames: identity,
|
1471 | moreLinkContent: identity,
|
1472 | moreLinkDidMount: identity,
|
1473 | moreLinkWillUnmount: identity,
|
1474 | monthStartFormat: createFormatter,
|
1475 |
|
1476 |
|
1477 | handleCustomRendering: identity,
|
1478 | customRenderingMetaMap: identity,
|
1479 | customRenderingReplaces: Boolean,
|
1480 | };
|
1481 |
|
1482 |
|
1483 | const BASE_OPTION_DEFAULTS = {
|
1484 | eventDisplay: 'auto',
|
1485 | defaultRangeSeparator: ' - ',
|
1486 | titleRangeSeparator: ' \u2013 ',
|
1487 | defaultTimedEventDuration: '01:00:00',
|
1488 | defaultAllDayEventDuration: { day: 1 },
|
1489 | forceEventDuration: false,
|
1490 | nextDayThreshold: '00:00:00',
|
1491 | dayHeaders: true,
|
1492 | initialView: '',
|
1493 | aspectRatio: 1.35,
|
1494 | headerToolbar: {
|
1495 | start: 'title',
|
1496 | center: '',
|
1497 | end: 'today prev,next',
|
1498 | },
|
1499 | weekends: true,
|
1500 | weekNumbers: false,
|
1501 | weekNumberCalculation: 'local',
|
1502 | editable: false,
|
1503 | nowIndicator: false,
|
1504 | scrollTime: '06:00:00',
|
1505 | scrollTimeReset: true,
|
1506 | slotMinTime: '00:00:00',
|
1507 | slotMaxTime: '24:00:00',
|
1508 | showNonCurrentDates: true,
|
1509 | lazyFetching: true,
|
1510 | startParam: 'start',
|
1511 | endParam: 'end',
|
1512 | timeZoneParam: 'timeZone',
|
1513 | timeZone: 'local',
|
1514 | locales: [],
|
1515 | locale: '',
|
1516 | themeSystem: 'standard',
|
1517 | dragRevertDuration: 500,
|
1518 | dragScroll: true,
|
1519 | allDayMaintainDuration: false,
|
1520 | unselectAuto: true,
|
1521 | dropAccept: '*',
|
1522 | eventOrder: 'start,-duration,allDay,title',
|
1523 | dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },
|
1524 | handleWindowResize: true,
|
1525 | windowResizeDelay: 100,
|
1526 | longPressDelay: 1000,
|
1527 | eventDragMinDistance: 5,
|
1528 | expandRows: false,
|
1529 | navLinks: false,
|
1530 | selectable: false,
|
1531 | eventMinHeight: 15,
|
1532 | eventMinWidth: 30,
|
1533 | eventShortHeight: 30,
|
1534 | monthStartFormat: { month: 'long', day: 'numeric' },
|
1535 | };
|
1536 |
|
1537 |
|
1538 | const CALENDAR_LISTENER_REFINERS = {
|
1539 | datesSet: identity,
|
1540 | eventsSet: identity,
|
1541 | eventAdd: identity,
|
1542 | eventChange: identity,
|
1543 | eventRemove: identity,
|
1544 | windowResize: identity,
|
1545 | eventClick: identity,
|
1546 | eventMouseEnter: identity,
|
1547 | eventMouseLeave: identity,
|
1548 | select: identity,
|
1549 | unselect: identity,
|
1550 | loading: identity,
|
1551 |
|
1552 | _unmount: identity,
|
1553 | _beforeprint: identity,
|
1554 | _afterprint: identity,
|
1555 | _noEventDrop: identity,
|
1556 | _noEventResize: identity,
|
1557 | _resize: identity,
|
1558 | _scrollRequest: identity,
|
1559 | };
|
1560 |
|
1561 |
|
1562 | const CALENDAR_OPTION_REFINERS = {
|
1563 | buttonText: identity,
|
1564 | buttonHints: identity,
|
1565 | views: identity,
|
1566 | plugins: identity,
|
1567 | initialEvents: identity,
|
1568 | events: identity,
|
1569 | eventSources: identity,
|
1570 | };
|
1571 | const COMPLEX_OPTION_COMPARATORS = {
|
1572 | headerToolbar: isMaybeObjectsEqual,
|
1573 | footerToolbar: isMaybeObjectsEqual,
|
1574 | buttonText: isMaybeObjectsEqual,
|
1575 | buttonHints: isMaybeObjectsEqual,
|
1576 | buttonIcons: isMaybeObjectsEqual,
|
1577 | dateIncrement: isMaybeObjectsEqual,
|
1578 | plugins: isMaybeArraysEqual,
|
1579 | events: isMaybeArraysEqual,
|
1580 | eventSources: isMaybeArraysEqual,
|
1581 | ['resources']: isMaybeArraysEqual,
|
1582 | };
|
1583 | function isMaybeObjectsEqual(a, b) {
|
1584 | if (typeof a === 'object' && typeof b === 'object' && a && b) {
|
1585 | return isPropsEqual(a, b);
|
1586 | }
|
1587 | return a === b;
|
1588 | }
|
1589 | function isMaybeArraysEqual(a, b) {
|
1590 | if (Array.isArray(a) && Array.isArray(b)) {
|
1591 | return isArraysEqual(a, b);
|
1592 | }
|
1593 | return a === b;
|
1594 | }
|
1595 |
|
1596 |
|
1597 | const VIEW_OPTION_REFINERS = {
|
1598 | type: String,
|
1599 | component: identity,
|
1600 | buttonText: String,
|
1601 | buttonTextKey: String,
|
1602 | dateProfileGeneratorClass: identity,
|
1603 | usesMinMaxTime: Boolean,
|
1604 | classNames: identity,
|
1605 | content: identity,
|
1606 | didMount: identity,
|
1607 | willUnmount: identity,
|
1608 | };
|
1609 |
|
1610 |
|
1611 | function mergeRawOptions(optionSets) {
|
1612 | return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
|
1613 | }
|
1614 | function refineProps(input, refiners) {
|
1615 | let refined = {};
|
1616 | let extra = {};
|
1617 | for (let propName in refiners) {
|
1618 | if (propName in input) {
|
1619 | refined[propName] = refiners[propName](input[propName]);
|
1620 | }
|
1621 | }
|
1622 | for (let propName in input) {
|
1623 | if (!(propName in refiners)) {
|
1624 | extra[propName] = input[propName];
|
1625 | }
|
1626 | }
|
1627 | return { refined, extra };
|
1628 | }
|
1629 | function identity(raw) {
|
1630 | return raw;
|
1631 | }
|
1632 |
|
1633 | const { hasOwnProperty } = Object.prototype;
|
1634 |
|
1635 |
|
1636 | function mergeProps(propObjs, complexPropsMap) {
|
1637 | let dest = {};
|
1638 | if (complexPropsMap) {
|
1639 | for (let name in complexPropsMap) {
|
1640 | if (complexPropsMap[name] === isMaybeObjectsEqual) {
|
1641 | let complexObjs = [];
|
1642 |
|
1643 | for (let i = propObjs.length - 1; i >= 0; i -= 1) {
|
1644 | let val = propObjs[i][name];
|
1645 | if (typeof val === 'object' && val) {
|
1646 | complexObjs.unshift(val);
|
1647 | }
|
1648 | else if (val !== undefined) {
|
1649 | dest[name] = val;
|
1650 | break;
|
1651 | }
|
1652 | }
|
1653 |
|
1654 | if (complexObjs.length) {
|
1655 | dest[name] = mergeProps(complexObjs);
|
1656 | }
|
1657 | }
|
1658 | }
|
1659 | }
|
1660 |
|
1661 | for (let i = propObjs.length - 1; i >= 0; i -= 1) {
|
1662 | let props = propObjs[i];
|
1663 | for (let name in props) {
|
1664 | if (!(name in dest)) {
|
1665 | dest[name] = props[name];
|
1666 | }
|
1667 | }
|
1668 | }
|
1669 | return dest;
|
1670 | }
|
1671 | function filterHash(hash, func) {
|
1672 | let filtered = {};
|
1673 | for (let key in hash) {
|
1674 | if (func(hash[key], key)) {
|
1675 | filtered[key] = hash[key];
|
1676 | }
|
1677 | }
|
1678 | return filtered;
|
1679 | }
|
1680 | function mapHash(hash, func) {
|
1681 | let newHash = {};
|
1682 | for (let key in hash) {
|
1683 | newHash[key] = func(hash[key], key);
|
1684 | }
|
1685 | return newHash;
|
1686 | }
|
1687 | function arrayToHash(a) {
|
1688 | let hash = {};
|
1689 | for (let item of a) {
|
1690 | hash[item] = true;
|
1691 | }
|
1692 | return hash;
|
1693 | }
|
1694 |
|
1695 |
|
1696 | function hashValuesToArray(obj) {
|
1697 | let a = [];
|
1698 | for (let key in obj) {
|
1699 | a.push(obj[key]);
|
1700 | }
|
1701 | return a;
|
1702 | }
|
1703 | function isPropsEqual(obj0, obj1) {
|
1704 | if (obj0 === obj1) {
|
1705 | return true;
|
1706 | }
|
1707 | for (let key in obj0) {
|
1708 | if (hasOwnProperty.call(obj0, key)) {
|
1709 | if (!(key in obj1)) {
|
1710 | return false;
|
1711 | }
|
1712 | }
|
1713 | }
|
1714 | for (let key in obj1) {
|
1715 | if (hasOwnProperty.call(obj1, key)) {
|
1716 | if (obj0[key] !== obj1[key]) {
|
1717 | return false;
|
1718 | }
|
1719 | }
|
1720 | }
|
1721 | return true;
|
1722 | }
|
1723 | const HANDLER_RE = /^on[A-Z]/;
|
1724 | function isNonHandlerPropsEqual(obj0, obj1) {
|
1725 | const keys = getUnequalProps(obj0, obj1);
|
1726 | for (let key of keys) {
|
1727 | if (!HANDLER_RE.test(key)) {
|
1728 | return false;
|
1729 | }
|
1730 | }
|
1731 | return true;
|
1732 | }
|
1733 | function getUnequalProps(obj0, obj1) {
|
1734 | let keys = [];
|
1735 | for (let key in obj0) {
|
1736 | if (hasOwnProperty.call(obj0, key)) {
|
1737 | if (!(key in obj1)) {
|
1738 | keys.push(key);
|
1739 | }
|
1740 | }
|
1741 | }
|
1742 | for (let key in obj1) {
|
1743 | if (hasOwnProperty.call(obj1, key)) {
|
1744 | if (obj0[key] !== obj1[key]) {
|
1745 | keys.push(key);
|
1746 | }
|
1747 | }
|
1748 | }
|
1749 | return keys;
|
1750 | }
|
1751 | function compareObjs(oldProps, newProps, equalityFuncs = {}) {
|
1752 | if (oldProps === newProps) {
|
1753 | return true;
|
1754 | }
|
1755 | for (let key in newProps) {
|
1756 | if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;
|
1757 | else {
|
1758 | return false;
|
1759 | }
|
1760 | }
|
1761 |
|
1762 | for (let key in oldProps) {
|
1763 | if (!(key in newProps)) {
|
1764 | return false;
|
1765 | }
|
1766 | }
|
1767 | return true;
|
1768 | }
|
1769 |
|
1770 |
|
1771 |
|
1772 | function isObjValsEqual(val0, val1, comparator) {
|
1773 | if (val0 === val1 || comparator === true) {
|
1774 | return true;
|
1775 | }
|
1776 | if (comparator) {
|
1777 | return comparator(val0, val1);
|
1778 | }
|
1779 | return false;
|
1780 | }
|
1781 | function collectFromHash(hash, startIndex = 0, endIndex, step = 1) {
|
1782 | let res = [];
|
1783 | if (endIndex == null) {
|
1784 | endIndex = Object.keys(hash).length;
|
1785 | }
|
1786 | for (let i = startIndex; i < endIndex; i += step) {
|
1787 | let val = hash[i];
|
1788 | if (val !== undefined) {
|
1789 | res.push(val);
|
1790 | }
|
1791 | }
|
1792 | return res;
|
1793 | }
|
1794 |
|
1795 | let calendarSystemClassMap = {};
|
1796 | function registerCalendarSystem(name, theClass) {
|
1797 | calendarSystemClassMap[name] = theClass;
|
1798 | }
|
1799 | function createCalendarSystem(name) {
|
1800 | return new calendarSystemClassMap[name]();
|
1801 | }
|
1802 | class GregorianCalendarSystem {
|
1803 | getMarkerYear(d) {
|
1804 | return d.getUTCFullYear();
|
1805 | }
|
1806 | getMarkerMonth(d) {
|
1807 | return d.getUTCMonth();
|
1808 | }
|
1809 | getMarkerDay(d) {
|
1810 | return d.getUTCDate();
|
1811 | }
|
1812 | arrayToMarker(arr) {
|
1813 | return arrayToUtcDate(arr);
|
1814 | }
|
1815 | markerToArray(marker) {
|
1816 | return dateToUtcArray(marker);
|
1817 | }
|
1818 | }
|
1819 | registerCalendarSystem('gregory', GregorianCalendarSystem);
|
1820 |
|
1821 | const ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
|
1822 | function parse(str) {
|
1823 | let m = ISO_RE.exec(str);
|
1824 | if (m) {
|
1825 | let marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number(`0.${m[12]}`) * 1000 : 0));
|
1826 | if (isValidDate(marker)) {
|
1827 | let timeZoneOffset = null;
|
1828 | if (m[13]) {
|
1829 | timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +
|
1830 | Number(m[18] || 0));
|
1831 | }
|
1832 | return {
|
1833 | marker,
|
1834 | isTimeUnspecified: !m[6],
|
1835 | timeZoneOffset,
|
1836 | };
|
1837 | }
|
1838 | }
|
1839 | return null;
|
1840 | }
|
1841 |
|
1842 | class DateEnv {
|
1843 | constructor(settings) {
|
1844 | let timeZone = this.timeZone = settings.timeZone;
|
1845 | let isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
|
1846 | if (settings.namedTimeZoneImpl && isNamedTimeZone) {
|
1847 | this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
|
1848 | }
|
1849 | this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
|
1850 | this.calendarSystem = createCalendarSystem(settings.calendarSystem);
|
1851 | this.locale = settings.locale;
|
1852 | this.weekDow = settings.locale.week.dow;
|
1853 | this.weekDoy = settings.locale.week.doy;
|
1854 | if (settings.weekNumberCalculation === 'ISO') {
|
1855 | this.weekDow = 1;
|
1856 | this.weekDoy = 4;
|
1857 | }
|
1858 | if (typeof settings.firstDay === 'number') {
|
1859 | this.weekDow = settings.firstDay;
|
1860 | }
|
1861 | if (typeof settings.weekNumberCalculation === 'function') {
|
1862 | this.weekNumberFunc = settings.weekNumberCalculation;
|
1863 | }
|
1864 | this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
|
1865 | this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText;
|
1866 | this.cmdFormatter = settings.cmdFormatter;
|
1867 | this.defaultSeparator = settings.defaultSeparator;
|
1868 | }
|
1869 |
|
1870 | createMarker(input) {
|
1871 | let meta = this.createMarkerMeta(input);
|
1872 | if (meta === null) {
|
1873 | return null;
|
1874 | }
|
1875 | return meta.marker;
|
1876 | }
|
1877 | createNowMarker() {
|
1878 | if (this.canComputeOffset) {
|
1879 | return this.timestampToMarker(new Date().valueOf());
|
1880 | }
|
1881 |
|
1882 |
|
1883 | return arrayToUtcDate(dateToLocalArray(new Date()));
|
1884 | }
|
1885 | createMarkerMeta(input) {
|
1886 | if (typeof input === 'string') {
|
1887 | return this.parse(input);
|
1888 | }
|
1889 | let marker = null;
|
1890 | if (typeof input === 'number') {
|
1891 | marker = this.timestampToMarker(input);
|
1892 | }
|
1893 | else if (input instanceof Date) {
|
1894 | input = input.valueOf();
|
1895 | if (!isNaN(input)) {
|
1896 | marker = this.timestampToMarker(input);
|
1897 | }
|
1898 | }
|
1899 | else if (Array.isArray(input)) {
|
1900 | marker = arrayToUtcDate(input);
|
1901 | }
|
1902 | if (marker === null || !isValidDate(marker)) {
|
1903 | return null;
|
1904 | }
|
1905 | return { marker, isTimeUnspecified: false, forcedTzo: null };
|
1906 | }
|
1907 | parse(s) {
|
1908 | let parts = parse(s);
|
1909 | if (parts === null) {
|
1910 | return null;
|
1911 | }
|
1912 | let { marker } = parts;
|
1913 | let forcedTzo = null;
|
1914 | if (parts.timeZoneOffset !== null) {
|
1915 | if (this.canComputeOffset) {
|
1916 | marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
|
1917 | }
|
1918 | else {
|
1919 | forcedTzo = parts.timeZoneOffset;
|
1920 | }
|
1921 | }
|
1922 | return { marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo };
|
1923 | }
|
1924 |
|
1925 | getYear(marker) {
|
1926 | return this.calendarSystem.getMarkerYear(marker);
|
1927 | }
|
1928 | getMonth(marker) {
|
1929 | return this.calendarSystem.getMarkerMonth(marker);
|
1930 | }
|
1931 | getDay(marker) {
|
1932 | return this.calendarSystem.getMarkerDay(marker);
|
1933 | }
|
1934 |
|
1935 | add(marker, dur) {
|
1936 | let a = this.calendarSystem.markerToArray(marker);
|
1937 | a[0] += dur.years;
|
1938 | a[1] += dur.months;
|
1939 | a[2] += dur.days;
|
1940 | a[6] += dur.milliseconds;
|
1941 | return this.calendarSystem.arrayToMarker(a);
|
1942 | }
|
1943 | subtract(marker, dur) {
|
1944 | let a = this.calendarSystem.markerToArray(marker);
|
1945 | a[0] -= dur.years;
|
1946 | a[1] -= dur.months;
|
1947 | a[2] -= dur.days;
|
1948 | a[6] -= dur.milliseconds;
|
1949 | return this.calendarSystem.arrayToMarker(a);
|
1950 | }
|
1951 | addYears(marker, n) {
|
1952 | let a = this.calendarSystem.markerToArray(marker);
|
1953 | a[0] += n;
|
1954 | return this.calendarSystem.arrayToMarker(a);
|
1955 | }
|
1956 | addMonths(marker, n) {
|
1957 | let a = this.calendarSystem.markerToArray(marker);
|
1958 | a[1] += n;
|
1959 | return this.calendarSystem.arrayToMarker(a);
|
1960 | }
|
1961 |
|
1962 | diffWholeYears(m0, m1) {
|
1963 | let { calendarSystem } = this;
|
1964 | if (timeAsMs(m0) === timeAsMs(m1) &&
|
1965 | calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&
|
1966 | calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
|
1967 | return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
|
1968 | }
|
1969 | return null;
|
1970 | }
|
1971 | diffWholeMonths(m0, m1) {
|
1972 | let { calendarSystem } = this;
|
1973 | if (timeAsMs(m0) === timeAsMs(m1) &&
|
1974 | calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
|
1975 | return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +
|
1976 | (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
|
1977 | }
|
1978 | return null;
|
1979 | }
|
1980 |
|
1981 | greatestWholeUnit(m0, m1) {
|
1982 | let n = this.diffWholeYears(m0, m1);
|
1983 | if (n !== null) {
|
1984 | return { unit: 'year', value: n };
|
1985 | }
|
1986 | n = this.diffWholeMonths(m0, m1);
|
1987 | if (n !== null) {
|
1988 | return { unit: 'month', value: n };
|
1989 | }
|
1990 | n = diffWholeWeeks(m0, m1);
|
1991 | if (n !== null) {
|
1992 | return { unit: 'week', value: n };
|
1993 | }
|
1994 | n = diffWholeDays(m0, m1);
|
1995 | if (n !== null) {
|
1996 | return { unit: 'day', value: n };
|
1997 | }
|
1998 | n = diffHours(m0, m1);
|
1999 | if (isInt(n)) {
|
2000 | return { unit: 'hour', value: n };
|
2001 | }
|
2002 | n = diffMinutes(m0, m1);
|
2003 | if (isInt(n)) {
|
2004 | return { unit: 'minute', value: n };
|
2005 | }
|
2006 | n = diffSeconds(m0, m1);
|
2007 | if (isInt(n)) {
|
2008 | return { unit: 'second', value: n };
|
2009 | }
|
2010 | return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };
|
2011 | }
|
2012 | countDurationsBetween(m0, m1, d) {
|
2013 |
|
2014 | let diff;
|
2015 | if (d.years) {
|
2016 | diff = this.diffWholeYears(m0, m1);
|
2017 | if (diff !== null) {
|
2018 | return diff / asRoughYears(d);
|
2019 | }
|
2020 | }
|
2021 | if (d.months) {
|
2022 | diff = this.diffWholeMonths(m0, m1);
|
2023 | if (diff !== null) {
|
2024 | return diff / asRoughMonths(d);
|
2025 | }
|
2026 | }
|
2027 | if (d.days) {
|
2028 | diff = diffWholeDays(m0, m1);
|
2029 | if (diff !== null) {
|
2030 | return diff / asRoughDays(d);
|
2031 | }
|
2032 | }
|
2033 | return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
|
2034 | }
|
2035 |
|
2036 |
|
2037 | startOf(m, unit) {
|
2038 | if (unit === 'year') {
|
2039 | return this.startOfYear(m);
|
2040 | }
|
2041 | if (unit === 'month') {
|
2042 | return this.startOfMonth(m);
|
2043 | }
|
2044 | if (unit === 'week') {
|
2045 | return this.startOfWeek(m);
|
2046 | }
|
2047 | if (unit === 'day') {
|
2048 | return startOfDay(m);
|
2049 | }
|
2050 | if (unit === 'hour') {
|
2051 | return startOfHour(m);
|
2052 | }
|
2053 | if (unit === 'minute') {
|
2054 | return startOfMinute(m);
|
2055 | }
|
2056 | if (unit === 'second') {
|
2057 | return startOfSecond(m);
|
2058 | }
|
2059 | return null;
|
2060 | }
|
2061 | startOfYear(m) {
|
2062 | return this.calendarSystem.arrayToMarker([
|
2063 | this.calendarSystem.getMarkerYear(m),
|
2064 | ]);
|
2065 | }
|
2066 | startOfMonth(m) {
|
2067 | return this.calendarSystem.arrayToMarker([
|
2068 | this.calendarSystem.getMarkerYear(m),
|
2069 | this.calendarSystem.getMarkerMonth(m),
|
2070 | ]);
|
2071 | }
|
2072 | startOfWeek(m) {
|
2073 | return this.calendarSystem.arrayToMarker([
|
2074 | this.calendarSystem.getMarkerYear(m),
|
2075 | this.calendarSystem.getMarkerMonth(m),
|
2076 | m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),
|
2077 | ]);
|
2078 | }
|
2079 |
|
2080 | computeWeekNumber(marker) {
|
2081 | if (this.weekNumberFunc) {
|
2082 | return this.weekNumberFunc(this.toDate(marker));
|
2083 | }
|
2084 | return weekOfYear(marker, this.weekDow, this.weekDoy);
|
2085 | }
|
2086 |
|
2087 | format(marker, formatter, dateOptions = {}) {
|
2088 | return formatter.format({
|
2089 | marker,
|
2090 | timeZoneOffset: dateOptions.forcedTzo != null ?
|
2091 | dateOptions.forcedTzo :
|
2092 | this.offsetForMarker(marker),
|
2093 | }, this);
|
2094 | }
|
2095 | formatRange(start, end, formatter, dateOptions = {}) {
|
2096 | if (dateOptions.isEndExclusive) {
|
2097 | end = addMs(end, -1);
|
2098 | }
|
2099 | return formatter.formatRange({
|
2100 | marker: start,
|
2101 | timeZoneOffset: dateOptions.forcedStartTzo != null ?
|
2102 | dateOptions.forcedStartTzo :
|
2103 | this.offsetForMarker(start),
|
2104 | }, {
|
2105 | marker: end,
|
2106 | timeZoneOffset: dateOptions.forcedEndTzo != null ?
|
2107 | dateOptions.forcedEndTzo :
|
2108 | this.offsetForMarker(end),
|
2109 | }, this, dateOptions.defaultSeparator);
|
2110 | }
|
2111 | |
2112 |
|
2113 |
|
2114 |
|
2115 | formatIso(marker, extraOptions = {}) {
|
2116 | let timeZoneOffset = null;
|
2117 | if (!extraOptions.omitTimeZoneOffset) {
|
2118 | if (extraOptions.forcedTzo != null) {
|
2119 | timeZoneOffset = extraOptions.forcedTzo;
|
2120 | }
|
2121 | else {
|
2122 | timeZoneOffset = this.offsetForMarker(marker);
|
2123 | }
|
2124 | }
|
2125 | return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
|
2126 | }
|
2127 |
|
2128 | timestampToMarker(ms) {
|
2129 | if (this.timeZone === 'local') {
|
2130 | return arrayToUtcDate(dateToLocalArray(new Date(ms)));
|
2131 | }
|
2132 | if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
|
2133 | return new Date(ms);
|
2134 | }
|
2135 | return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
|
2136 | }
|
2137 | offsetForMarker(m) {
|
2138 | if (this.timeZone === 'local') {
|
2139 | return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset();
|
2140 | }
|
2141 | if (this.timeZone === 'UTC') {
|
2142 | return 0;
|
2143 | }
|
2144 | if (this.namedTimeZoneImpl) {
|
2145 | return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
|
2146 | }
|
2147 | return null;
|
2148 | }
|
2149 |
|
2150 | toDate(m, forcedTzo) {
|
2151 | if (this.timeZone === 'local') {
|
2152 | return arrayToLocalDate(dateToUtcArray(m));
|
2153 | }
|
2154 | if (this.timeZone === 'UTC') {
|
2155 | return new Date(m.valueOf());
|
2156 | }
|
2157 | if (!this.namedTimeZoneImpl) {
|
2158 | return new Date(m.valueOf() - (forcedTzo || 0));
|
2159 | }
|
2160 | return new Date(m.valueOf() -
|
2161 | this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
|
2162 | }
|
2163 | }
|
2164 |
|
2165 | class Theme {
|
2166 | constructor(calendarOptions) {
|
2167 | if (this.iconOverrideOption) {
|
2168 | this.setIconOverride(calendarOptions[this.iconOverrideOption]);
|
2169 | }
|
2170 | }
|
2171 | setIconOverride(iconOverrideHash) {
|
2172 | let iconClassesCopy;
|
2173 | let buttonName;
|
2174 | if (typeof iconOverrideHash === 'object' && iconOverrideHash) {
|
2175 | iconClassesCopy = Object.assign({}, this.iconClasses);
|
2176 | for (buttonName in iconOverrideHash) {
|
2177 | iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
|
2178 | }
|
2179 | this.iconClasses = iconClassesCopy;
|
2180 | }
|
2181 | else if (iconOverrideHash === false) {
|
2182 | this.iconClasses = {};
|
2183 | }
|
2184 | }
|
2185 | applyIconOverridePrefix(className) {
|
2186 | let prefix = this.iconOverridePrefix;
|
2187 | if (prefix && className.indexOf(prefix) !== 0) {
|
2188 | className = prefix + className;
|
2189 | }
|
2190 | return className;
|
2191 | }
|
2192 | getClass(key) {
|
2193 | return this.classes[key] || '';
|
2194 | }
|
2195 | getIconClass(buttonName, isRtl) {
|
2196 | let className;
|
2197 | if (isRtl && this.rtlIconClasses) {
|
2198 | className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
|
2199 | }
|
2200 | else {
|
2201 | className = this.iconClasses[buttonName];
|
2202 | }
|
2203 | if (className) {
|
2204 | return `${this.baseIconClass} ${className}`;
|
2205 | }
|
2206 | return '';
|
2207 | }
|
2208 | getCustomButtonIconClass(customButtonProps) {
|
2209 | let className;
|
2210 | if (this.iconOverrideCustomButtonOption) {
|
2211 | className = customButtonProps[this.iconOverrideCustomButtonOption];
|
2212 | if (className) {
|
2213 | return `${this.baseIconClass} ${this.applyIconOverridePrefix(className)}`;
|
2214 | }
|
2215 | }
|
2216 | return '';
|
2217 | }
|
2218 | }
|
2219 | Theme.prototype.classes = {};
|
2220 | Theme.prototype.iconClasses = {};
|
2221 | Theme.prototype.baseIconClass = '';
|
2222 | Theme.prototype.iconOverridePrefix = '';
|
2223 |
|
2224 |
|
2225 |
|
2226 |
|
2227 |
|
2228 | function flushSync(runBeforeFlush) {
|
2229 | runBeforeFlush();
|
2230 | let oldDebounceRendering = preact.options.debounceRendering;
|
2231 | let callbackQ = [];
|
2232 | function execCallbackSync(callback) {
|
2233 | callbackQ.push(callback);
|
2234 | }
|
2235 | preact.options.debounceRendering = execCallbackSync;
|
2236 | preact.render(preact.createElement(FakeComponent, {}), document.createElement('div'));
|
2237 | while (callbackQ.length) {
|
2238 | callbackQ.shift()();
|
2239 | }
|
2240 | preact.options.debounceRendering = oldDebounceRendering;
|
2241 | }
|
2242 | class FakeComponent extends preact.Component {
|
2243 | render() { return preact.createElement('div', {}); }
|
2244 | componentDidMount() { this.setState({}); }
|
2245 | }
|
2246 |
|
2247 | function createContext(defaultValue) {
|
2248 | let ContextType = preact.createContext(defaultValue);
|
2249 | let origProvider = ContextType.Provider;
|
2250 | ContextType.Provider = function () {
|
2251 | let isNew = !this.getChildContext;
|
2252 | let children = origProvider.apply(this, arguments);
|
2253 | if (isNew) {
|
2254 | let subs = [];
|
2255 | this.shouldComponentUpdate = (_props) => {
|
2256 | if (this.props.value !== _props.value) {
|
2257 | subs.forEach((c) => {
|
2258 | c.context = _props.value;
|
2259 | c.forceUpdate();
|
2260 | });
|
2261 | }
|
2262 | };
|
2263 | this.sub = (c) => {
|
2264 | subs.push(c);
|
2265 | let old = c.componentWillUnmount;
|
2266 | c.componentWillUnmount = () => {
|
2267 | subs.splice(subs.indexOf(c), 1);
|
2268 | old && old.call(c);
|
2269 | };
|
2270 | };
|
2271 | }
|
2272 | return children;
|
2273 | };
|
2274 | return ContextType;
|
2275 | }
|
2276 |
|
2277 | class ScrollResponder {
|
2278 | constructor(execFunc, emitter, scrollTime, scrollTimeReset) {
|
2279 | this.execFunc = execFunc;
|
2280 | this.emitter = emitter;
|
2281 | this.scrollTime = scrollTime;
|
2282 | this.scrollTimeReset = scrollTimeReset;
|
2283 | this.handleScrollRequest = (request) => {
|
2284 | this.queuedRequest = Object.assign({}, this.queuedRequest || {}, request);
|
2285 | this.drain();
|
2286 | };
|
2287 | emitter.on('_scrollRequest', this.handleScrollRequest);
|
2288 | this.fireInitialScroll();
|
2289 | }
|
2290 | detach() {
|
2291 | this.emitter.off('_scrollRequest', this.handleScrollRequest);
|
2292 | }
|
2293 | update(isDatesNew) {
|
2294 | if (isDatesNew && this.scrollTimeReset) {
|
2295 | this.fireInitialScroll();
|
2296 | }
|
2297 | else {
|
2298 | this.drain();
|
2299 | }
|
2300 | }
|
2301 | fireInitialScroll() {
|
2302 | this.handleScrollRequest({
|
2303 | time: this.scrollTime,
|
2304 | });
|
2305 | }
|
2306 | drain() {
|
2307 | if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
|
2308 | this.queuedRequest = null;
|
2309 | }
|
2310 | }
|
2311 | }
|
2312 |
|
2313 | const ViewContextType = createContext({});
|
2314 | function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
|
2315 | return {
|
2316 | dateEnv,
|
2317 | options: viewOptions,
|
2318 | pluginHooks,
|
2319 | emitter,
|
2320 | dispatch,
|
2321 | getCurrentData,
|
2322 | calendarApi,
|
2323 | viewSpec,
|
2324 | viewApi,
|
2325 | dateProfileGenerator,
|
2326 | theme,
|
2327 | isRtl: viewOptions.direction === 'rtl',
|
2328 | addResizeHandler(handler) {
|
2329 | emitter.on('_resize', handler);
|
2330 | },
|
2331 | removeResizeHandler(handler) {
|
2332 | emitter.off('_resize', handler);
|
2333 | },
|
2334 | createScrollResponder(execFunc) {
|
2335 | return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset);
|
2336 | },
|
2337 | registerInteractiveComponent,
|
2338 | unregisterInteractiveComponent,
|
2339 | };
|
2340 | }
|
2341 |
|
2342 |
|
2343 | class PureComponent extends Component {
|
2344 | shouldComponentUpdate(nextProps, nextState) {
|
2345 | if (this.debug) {
|
2346 |
|
2347 | console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));
|
2348 | }
|
2349 | return !compareObjs(this.props, nextProps, this.propEquality) ||
|
2350 | !compareObjs(this.state, nextState, this.stateEquality);
|
2351 | }
|
2352 |
|
2353 | safeSetState(newState) {
|
2354 | if (!compareObjs(this.state, Object.assign(Object.assign({}, this.state), newState), this.stateEquality)) {
|
2355 | this.setState(newState);
|
2356 | }
|
2357 | }
|
2358 | }
|
2359 | PureComponent.addPropsEquality = addPropsEquality;
|
2360 | PureComponent.addStateEquality = addStateEquality;
|
2361 | PureComponent.contextType = ViewContextType;
|
2362 | PureComponent.prototype.propEquality = {};
|
2363 | PureComponent.prototype.stateEquality = {};
|
2364 | class BaseComponent extends PureComponent {
|
2365 | }
|
2366 | BaseComponent.contextType = ViewContextType;
|
2367 | function addPropsEquality(propEquality) {
|
2368 | let hash = Object.create(this.prototype.propEquality);
|
2369 | Object.assign(hash, propEquality);
|
2370 | this.prototype.propEquality = hash;
|
2371 | }
|
2372 | function addStateEquality(stateEquality) {
|
2373 | let hash = Object.create(this.prototype.stateEquality);
|
2374 | Object.assign(hash, stateEquality);
|
2375 | this.prototype.stateEquality = hash;
|
2376 | }
|
2377 |
|
2378 | function setRef(ref, current) {
|
2379 | if (typeof ref === 'function') {
|
2380 | ref(current);
|
2381 | }
|
2382 | else if (ref) {
|
2383 |
|
2384 | ref.current = current;
|
2385 | }
|
2386 | }
|
2387 |
|
2388 | class ContentInjector extends BaseComponent {
|
2389 | constructor() {
|
2390 | super(...arguments);
|
2391 | this.id = guid();
|
2392 | this.queuedDomNodes = [];
|
2393 | this.currentDomNodes = [];
|
2394 | this.handleEl = (el) => {
|
2395 | const { options } = this.context;
|
2396 | const { generatorName } = this.props;
|
2397 | if (!options.customRenderingReplaces || !hasCustomRenderingHandler(generatorName, options)) {
|
2398 | this.updateElRef(el);
|
2399 | }
|
2400 | };
|
2401 | this.updateElRef = (el) => {
|
2402 | if (this.props.elRef) {
|
2403 | setRef(this.props.elRef, el);
|
2404 | }
|
2405 | };
|
2406 | }
|
2407 | render() {
|
2408 | const { props, context } = this;
|
2409 | const { options } = context;
|
2410 | const { customGenerator, defaultGenerator, renderProps } = props;
|
2411 | const attrs = buildElAttrs(props, [], this.handleEl);
|
2412 | let useDefault = false;
|
2413 | let innerContent;
|
2414 | let queuedDomNodes = [];
|
2415 | let currentGeneratorMeta;
|
2416 | if (customGenerator != null) {
|
2417 | const customGeneratorRes = typeof customGenerator === 'function' ?
|
2418 | customGenerator(renderProps, createElement) :
|
2419 | customGenerator;
|
2420 | if (customGeneratorRes === true) {
|
2421 | useDefault = true;
|
2422 | }
|
2423 | else {
|
2424 | const isObject = customGeneratorRes && typeof customGeneratorRes === 'object';
|
2425 | if (isObject && ('html' in customGeneratorRes)) {
|
2426 | attrs.dangerouslySetInnerHTML = { __html: customGeneratorRes.html };
|
2427 | }
|
2428 | else if (isObject && ('domNodes' in customGeneratorRes)) {
|
2429 | queuedDomNodes = Array.prototype.slice.call(customGeneratorRes.domNodes);
|
2430 | }
|
2431 | else if (isObject
|
2432 | ? isValidElement(customGeneratorRes)
|
2433 | : typeof customGeneratorRes !== 'function'
|
2434 | ) {
|
2435 |
|
2436 | innerContent = customGeneratorRes;
|
2437 | }
|
2438 | else {
|
2439 |
|
2440 | currentGeneratorMeta = customGeneratorRes;
|
2441 | }
|
2442 | }
|
2443 | }
|
2444 | else {
|
2445 | useDefault = !hasCustomRenderingHandler(props.generatorName, options);
|
2446 | }
|
2447 | if (useDefault && defaultGenerator) {
|
2448 | innerContent = defaultGenerator(renderProps);
|
2449 | }
|
2450 | this.queuedDomNodes = queuedDomNodes;
|
2451 | this.currentGeneratorMeta = currentGeneratorMeta;
|
2452 | return createElement(props.elTag, attrs, innerContent);
|
2453 | }
|
2454 | componentDidMount() {
|
2455 | this.applyQueueudDomNodes();
|
2456 | this.triggerCustomRendering(true);
|
2457 | }
|
2458 | componentDidUpdate() {
|
2459 | this.applyQueueudDomNodes();
|
2460 | this.triggerCustomRendering(true);
|
2461 | }
|
2462 | componentWillUnmount() {
|
2463 | this.triggerCustomRendering(false);
|
2464 | }
|
2465 | triggerCustomRendering(isActive) {
|
2466 | var _a;
|
2467 | const { props, context } = this;
|
2468 | const { handleCustomRendering, customRenderingMetaMap } = context.options;
|
2469 | if (handleCustomRendering) {
|
2470 | const generatorMeta = (_a = this.currentGeneratorMeta) !== null && _a !== void 0 ? _a : customRenderingMetaMap === null || customRenderingMetaMap === void 0 ? void 0 : customRenderingMetaMap[props.generatorName];
|
2471 | if (generatorMeta) {
|
2472 | handleCustomRendering(Object.assign(Object.assign({ id: this.id, isActive, containerEl: this.base, reportNewContainerEl: this.updateElRef,
|
2473 | generatorMeta }, props), { elClasses: (props.elClasses || []).filter(isTruthy) }));
|
2474 | }
|
2475 | }
|
2476 | }
|
2477 | applyQueueudDomNodes() {
|
2478 | const { queuedDomNodes, currentDomNodes } = this;
|
2479 | const el = this.base;
|
2480 | if (!isArraysEqual(queuedDomNodes, currentDomNodes)) {
|
2481 | currentDomNodes.forEach(removeElement);
|
2482 | for (let newNode of queuedDomNodes) {
|
2483 | el.appendChild(newNode);
|
2484 | }
|
2485 | this.currentDomNodes = queuedDomNodes;
|
2486 | }
|
2487 | }
|
2488 | }
|
2489 | ContentInjector.addPropsEquality({
|
2490 | elClasses: isArraysEqual,
|
2491 | elStyle: isPropsEqual,
|
2492 | elAttrs: isNonHandlerPropsEqual,
|
2493 | renderProps: isPropsEqual,
|
2494 | });
|
2495 |
|
2496 |
|
2497 |
|
2498 |
|
2499 |
|
2500 |
|
2501 | function hasCustomRenderingHandler(generatorName, options) {
|
2502 | var _a;
|
2503 | return Boolean(options.handleCustomRendering &&
|
2504 | generatorName &&
|
2505 | ((_a = options.customRenderingMetaMap) === null || _a === void 0 ? void 0 : _a[generatorName]));
|
2506 | }
|
2507 | function buildElAttrs(props, extraClassNames, elRef) {
|
2508 | const attrs = Object.assign(Object.assign({}, props.elAttrs), { ref: elRef });
|
2509 | if (props.elClasses || extraClassNames) {
|
2510 | attrs.className = (props.elClasses || [])
|
2511 | .concat(extraClassNames || [])
|
2512 | .concat(attrs.className || [])
|
2513 | .filter(Boolean)
|
2514 | .join(' ');
|
2515 | }
|
2516 | if (props.elStyle) {
|
2517 | attrs.style = props.elStyle;
|
2518 | }
|
2519 | return attrs;
|
2520 | }
|
2521 | function isTruthy(val) {
|
2522 | return Boolean(val);
|
2523 | }
|
2524 |
|
2525 | const RenderId = createContext(0);
|
2526 |
|
2527 | class ContentContainer extends Component {
|
2528 | constructor() {
|
2529 | super(...arguments);
|
2530 | this.InnerContent = InnerContentInjector.bind(undefined, this);
|
2531 | this.handleEl = (el) => {
|
2532 | this.el = el;
|
2533 | if (this.props.elRef) {
|
2534 | setRef(this.props.elRef, el);
|
2535 | if (el && this.didMountMisfire) {
|
2536 | this.componentDidMount();
|
2537 | }
|
2538 | }
|
2539 | };
|
2540 | }
|
2541 | render() {
|
2542 | const { props } = this;
|
2543 | const generatedClassNames = generateClassNames(props.classNameGenerator, props.renderProps);
|
2544 | if (props.children) {
|
2545 | const elAttrs = buildElAttrs(props, generatedClassNames, this.handleEl);
|
2546 | const children = props.children(this.InnerContent, props.renderProps, elAttrs);
|
2547 | if (props.elTag) {
|
2548 | return createElement(props.elTag, elAttrs, children);
|
2549 | }
|
2550 | else {
|
2551 | return children;
|
2552 | }
|
2553 | }
|
2554 | else {
|
2555 | return createElement((ContentInjector), Object.assign(Object.assign({}, props), { elRef: this.handleEl, elTag: props.elTag || 'div', elClasses: (props.elClasses || []).concat(generatedClassNames), renderId: this.context }));
|
2556 | }
|
2557 | }
|
2558 | componentDidMount() {
|
2559 | var _a, _b;
|
2560 | if (this.el) {
|
2561 | (_b = (_a = this.props).didMount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.el }));
|
2562 | }
|
2563 | else {
|
2564 | this.didMountMisfire = true;
|
2565 | }
|
2566 | }
|
2567 | componentWillUnmount() {
|
2568 | var _a, _b;
|
2569 | (_b = (_a = this.props).willUnmount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.el }));
|
2570 | }
|
2571 | }
|
2572 | ContentContainer.contextType = RenderId;
|
2573 | function InnerContentInjector(containerComponent, props) {
|
2574 | const parentProps = containerComponent.props;
|
2575 | return createElement((ContentInjector), Object.assign({ renderProps: parentProps.renderProps, generatorName: parentProps.generatorName, customGenerator: parentProps.customGenerator, defaultGenerator: parentProps.defaultGenerator, renderId: containerComponent.context }, props));
|
2576 | }
|
2577 |
|
2578 | function generateClassNames(classNameGenerator, renderProps) {
|
2579 | const classNames = typeof classNameGenerator === 'function' ?
|
2580 | classNameGenerator(renderProps) :
|
2581 | classNameGenerator || [];
|
2582 | return typeof classNames === 'string' ? [classNames] : classNames;
|
2583 | }
|
2584 |
|
2585 | class ViewContainer extends BaseComponent {
|
2586 | render() {
|
2587 | let { props, context } = this;
|
2588 | let { options } = context;
|
2589 | let renderProps = { view: context.viewApi };
|
2590 | return (createElement(ContentContainer, Object.assign({}, props, { elTag: props.elTag || 'div', elClasses: [
|
2591 | ...buildViewClassNames(props.viewSpec),
|
2592 | ...(props.elClasses || []),
|
2593 | ], renderProps: renderProps, classNameGenerator: options.viewClassNames, generatorName: undefined, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount }), () => props.children));
|
2594 | }
|
2595 | }
|
2596 | function buildViewClassNames(viewSpec) {
|
2597 | return [
|
2598 | `fc-${viewSpec.type}-view`,
|
2599 | 'fc-view',
|
2600 | ];
|
2601 | }
|
2602 |
|
2603 | function parseRange(input, dateEnv) {
|
2604 | let start = null;
|
2605 | let end = null;
|
2606 | if (input.start) {
|
2607 | start = dateEnv.createMarker(input.start);
|
2608 | }
|
2609 | if (input.end) {
|
2610 | end = dateEnv.createMarker(input.end);
|
2611 | }
|
2612 | if (!start && !end) {
|
2613 | return null;
|
2614 | }
|
2615 | if (start && end && end < start) {
|
2616 | return null;
|
2617 | }
|
2618 | return { start, end };
|
2619 | }
|
2620 |
|
2621 |
|
2622 | function invertRanges(ranges, constraintRange) {
|
2623 | let invertedRanges = [];
|
2624 | let { start } = constraintRange;
|
2625 | let i;
|
2626 | let dateRange;
|
2627 |
|
2628 | ranges.sort(compareRanges);
|
2629 | for (i = 0; i < ranges.length; i += 1) {
|
2630 | dateRange = ranges[i];
|
2631 |
|
2632 | if (dateRange.start > start) {
|
2633 | invertedRanges.push({ start, end: dateRange.start });
|
2634 | }
|
2635 | if (dateRange.end > start) {
|
2636 | start = dateRange.end;
|
2637 | }
|
2638 | }
|
2639 |
|
2640 | if (start < constraintRange.end) {
|
2641 | invertedRanges.push({ start, end: constraintRange.end });
|
2642 | }
|
2643 | return invertedRanges;
|
2644 | }
|
2645 | function compareRanges(range0, range1) {
|
2646 | return range0.start.valueOf() - range1.start.valueOf();
|
2647 | }
|
2648 | function intersectRanges(range0, range1) {
|
2649 | let { start, end } = range0;
|
2650 | let newRange = null;
|
2651 | if (range1.start !== null) {
|
2652 | if (start === null) {
|
2653 | start = range1.start;
|
2654 | }
|
2655 | else {
|
2656 | start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
|
2657 | }
|
2658 | }
|
2659 | if (range1.end != null) {
|
2660 | if (end === null) {
|
2661 | end = range1.end;
|
2662 | }
|
2663 | else {
|
2664 | end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
|
2665 | }
|
2666 | }
|
2667 | if (start === null || end === null || start < end) {
|
2668 | newRange = { start, end };
|
2669 | }
|
2670 | return newRange;
|
2671 | }
|
2672 | function rangesEqual(range0, range1) {
|
2673 | return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&
|
2674 | (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
|
2675 | }
|
2676 | function rangesIntersect(range0, range1) {
|
2677 | return (range0.end === null || range1.start === null || range0.end > range1.start) &&
|
2678 | (range0.start === null || range1.end === null || range0.start < range1.end);
|
2679 | }
|
2680 | function rangeContainsRange(outerRange, innerRange) {
|
2681 | return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&
|
2682 | (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));
|
2683 | }
|
2684 | function rangeContainsMarker(range, date) {
|
2685 | return (range.start === null || date >= range.start) &&
|
2686 | (range.end === null || date < range.end);
|
2687 | }
|
2688 |
|
2689 |
|
2690 | function constrainMarkerToRange(date, range) {
|
2691 | if (range.start != null && date < range.start) {
|
2692 | return range.start;
|
2693 | }
|
2694 | if (range.end != null && date >= range.end) {
|
2695 | return new Date(range.end.valueOf() - 1);
|
2696 | }
|
2697 | return date;
|
2698 | }
|
2699 |
|
2700 |
|
2701 |
|
2702 |
|
2703 |
|
2704 | function computeAlignedDayRange(timedRange) {
|
2705 | let dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
|
2706 | let start = startOfDay(timedRange.start);
|
2707 | let end = addDays(start, dayCnt);
|
2708 | return { start, end };
|
2709 | }
|
2710 |
|
2711 |
|
2712 | function computeVisibleDayRange(timedRange, nextDayThreshold = createDuration(0)) {
|
2713 | let startDay = null;
|
2714 | let endDay = null;
|
2715 | if (timedRange.end) {
|
2716 | endDay = startOfDay(timedRange.end);
|
2717 | let endTimeMS = timedRange.end.valueOf() - endDay.valueOf();
|
2718 |
|
2719 |
|
2720 |
|
2721 | if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
|
2722 | endDay = addDays(endDay, 1);
|
2723 | }
|
2724 | }
|
2725 | if (timedRange.start) {
|
2726 | startDay = startOfDay(timedRange.start);
|
2727 |
|
2728 | if (endDay && endDay <= startDay) {
|
2729 | endDay = addDays(startDay, 1);
|
2730 | }
|
2731 | }
|
2732 | return { start: startDay, end: endDay };
|
2733 | }
|
2734 |
|
2735 | function isMultiDayRange(range) {
|
2736 | let visibleRange = computeVisibleDayRange(range);
|
2737 | return diffDays(visibleRange.start, visibleRange.end) > 1;
|
2738 | }
|
2739 | function diffDates(date0, date1, dateEnv, largeUnit) {
|
2740 | if (largeUnit === 'year') {
|
2741 | return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
|
2742 | }
|
2743 | if (largeUnit === 'month') {
|
2744 | return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
|
2745 | }
|
2746 | return diffDayAndTime(date0, date1);
|
2747 | }
|
2748 |
|
2749 | function reduceCurrentDate(currentDate, action) {
|
2750 | switch (action.type) {
|
2751 | case 'CHANGE_DATE':
|
2752 | return action.dateMarker;
|
2753 | default:
|
2754 | return currentDate;
|
2755 | }
|
2756 | }
|
2757 | function getInitialDate(options, dateEnv) {
|
2758 | let initialDateInput = options.initialDate;
|
2759 |
|
2760 | if (initialDateInput != null) {
|
2761 | return dateEnv.createMarker(initialDateInput);
|
2762 | }
|
2763 | return getNow(options.now, dateEnv);
|
2764 | }
|
2765 | function getNow(nowInput, dateEnv) {
|
2766 | if (typeof nowInput === 'function') {
|
2767 | nowInput = nowInput();
|
2768 | }
|
2769 | if (nowInput == null) {
|
2770 | return dateEnv.createNowMarker();
|
2771 | }
|
2772 | return dateEnv.createMarker(nowInput);
|
2773 | }
|
2774 |
|
2775 | class DateProfileGenerator {
|
2776 | constructor(props) {
|
2777 | this.props = props;
|
2778 | this.nowDate = getNow(props.nowInput, props.dateEnv);
|
2779 | this.initHiddenDays();
|
2780 | }
|
2781 | |
2782 |
|
2783 |
|
2784 | buildPrev(currentDateProfile, currentDate, forceToValid) {
|
2785 | let { dateEnv } = this.props;
|
2786 | let prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit),
|
2787 | currentDateProfile.dateIncrement);
|
2788 | return this.build(prevDate, -1, forceToValid);
|
2789 | }
|
2790 |
|
2791 | buildNext(currentDateProfile, currentDate, forceToValid) {
|
2792 | let { dateEnv } = this.props;
|
2793 | let nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit),
|
2794 | currentDateProfile.dateIncrement);
|
2795 | return this.build(nextDate, 1, forceToValid);
|
2796 | }
|
2797 |
|
2798 |
|
2799 |
|
2800 | build(currentDate, direction, forceToValid = true) {
|
2801 | let { props } = this;
|
2802 | let validRange;
|
2803 | let currentInfo;
|
2804 | let isRangeAllDay;
|
2805 | let renderRange;
|
2806 | let activeRange;
|
2807 | let isValid;
|
2808 | validRange = this.buildValidRange();
|
2809 | validRange = this.trimHiddenDays(validRange);
|
2810 | if (forceToValid) {
|
2811 | currentDate = constrainMarkerToRange(currentDate, validRange);
|
2812 | }
|
2813 | currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
|
2814 | isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
|
2815 | renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
|
2816 | renderRange = this.trimHiddenDays(renderRange);
|
2817 | activeRange = renderRange;
|
2818 | if (!props.showNonCurrentDates) {
|
2819 | activeRange = intersectRanges(activeRange, currentInfo.range);
|
2820 | }
|
2821 | activeRange = this.adjustActiveRange(activeRange);
|
2822 | activeRange = intersectRanges(activeRange, validRange);
|
2823 |
|
2824 |
|
2825 | isValid = rangesIntersect(currentInfo.range, validRange);
|
2826 |
|
2827 | if (!rangeContainsMarker(renderRange, currentDate)) {
|
2828 | currentDate = renderRange.start;
|
2829 | }
|
2830 | return {
|
2831 | currentDate,
|
2832 |
|
2833 |
|
2834 | validRange,
|
2835 |
|
2836 |
|
2837 | currentRange: currentInfo.range,
|
2838 |
|
2839 | currentRangeUnit: currentInfo.unit,
|
2840 | isRangeAllDay,
|
2841 |
|
2842 |
|
2843 | activeRange,
|
2844 |
|
2845 |
|
2846 | renderRange,
|
2847 |
|
2848 | slotMinTime: props.slotMinTime,
|
2849 |
|
2850 | slotMaxTime: props.slotMaxTime,
|
2851 | isValid,
|
2852 |
|
2853 | dateIncrement: this.buildDateIncrement(currentInfo.duration),
|
2854 |
|
2855 | };
|
2856 | }
|
2857 |
|
2858 |
|
2859 |
|
2860 | buildValidRange() {
|
2861 | let input = this.props.validRangeInput;
|
2862 | let simpleInput = typeof input === 'function'
|
2863 | ? input.call(this.props.calendarApi, this.nowDate)
|
2864 | : input;
|
2865 | return this.refineRange(simpleInput) ||
|
2866 | { start: null, end: null };
|
2867 | }
|
2868 |
|
2869 |
|
2870 |
|
2871 |
|
2872 | buildCurrentRangeInfo(date, direction) {
|
2873 | let { props } = this;
|
2874 | let duration = null;
|
2875 | let unit = null;
|
2876 | let range = null;
|
2877 | let dayCount;
|
2878 | if (props.duration) {
|
2879 | duration = props.duration;
|
2880 | unit = props.durationUnit;
|
2881 | range = this.buildRangeFromDuration(date, direction, duration, unit);
|
2882 | }
|
2883 | else if ((dayCount = this.props.dayCount)) {
|
2884 | unit = 'day';
|
2885 | range = this.buildRangeFromDayCount(date, direction, dayCount);
|
2886 | }
|
2887 | else if ((range = this.buildCustomVisibleRange(date))) {
|
2888 | unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
|
2889 | }
|
2890 | else {
|
2891 | duration = this.getFallbackDuration();
|
2892 | unit = greatestDurationDenominator(duration).unit;
|
2893 | range = this.buildRangeFromDuration(date, direction, duration, unit);
|
2894 | }
|
2895 | return { duration, unit, range };
|
2896 | }
|
2897 | getFallbackDuration() {
|
2898 | return createDuration({ day: 1 });
|
2899 | }
|
2900 |
|
2901 |
|
2902 | adjustActiveRange(range) {
|
2903 | let { dateEnv, usesMinMaxTime, slotMinTime, slotMaxTime } = this.props;
|
2904 | let { start, end } = range;
|
2905 | if (usesMinMaxTime) {
|
2906 |
|
2907 | if (asRoughDays(slotMinTime) < 0) {
|
2908 | start = startOfDay(start);
|
2909 | start = dateEnv.add(start, slotMinTime);
|
2910 | }
|
2911 |
|
2912 | if (asRoughDays(slotMaxTime) > 1) {
|
2913 | end = startOfDay(end);
|
2914 | end = addDays(end, -1);
|
2915 | end = dateEnv.add(end, slotMaxTime);
|
2916 | }
|
2917 | }
|
2918 | return { start, end };
|
2919 | }
|
2920 |
|
2921 |
|
2922 | buildRangeFromDuration(date, direction, duration, unit) {
|
2923 | let { dateEnv, dateAlignment } = this.props;
|
2924 | let start;
|
2925 | let end;
|
2926 | let res;
|
2927 |
|
2928 | if (!dateAlignment) {
|
2929 | let { dateIncrement } = this.props;
|
2930 | if (dateIncrement) {
|
2931 |
|
2932 | if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
|
2933 | dateAlignment = greatestDurationDenominator(dateIncrement).unit;
|
2934 | }
|
2935 | else {
|
2936 | dateAlignment = unit;
|
2937 | }
|
2938 | }
|
2939 | else {
|
2940 | dateAlignment = unit;
|
2941 | }
|
2942 | }
|
2943 |
|
2944 | if (asRoughDays(duration) <= 1) {
|
2945 | if (this.isHiddenDay(start)) {
|
2946 | start = this.skipHiddenDays(start, direction);
|
2947 | start = startOfDay(start);
|
2948 | }
|
2949 | }
|
2950 | function computeRes() {
|
2951 | start = dateEnv.startOf(date, dateAlignment);
|
2952 | end = dateEnv.add(start, duration);
|
2953 | res = { start, end };
|
2954 | }
|
2955 | computeRes();
|
2956 |
|
2957 | if (!this.trimHiddenDays(res)) {
|
2958 | date = this.skipHiddenDays(date, direction);
|
2959 | computeRes();
|
2960 | }
|
2961 | return res;
|
2962 | }
|
2963 |
|
2964 | buildRangeFromDayCount(date, direction, dayCount) {
|
2965 | let { dateEnv, dateAlignment } = this.props;
|
2966 | let runningCount = 0;
|
2967 | let start = date;
|
2968 | let end;
|
2969 | if (dateAlignment) {
|
2970 | start = dateEnv.startOf(start, dateAlignment);
|
2971 | }
|
2972 | start = startOfDay(start);
|
2973 | start = this.skipHiddenDays(start, direction);
|
2974 | end = start;
|
2975 | do {
|
2976 | end = addDays(end, 1);
|
2977 | if (!this.isHiddenDay(end)) {
|
2978 | runningCount += 1;
|
2979 | }
|
2980 | } while (runningCount < dayCount);
|
2981 | return { start, end };
|
2982 | }
|
2983 |
|
2984 |
|
2985 | buildCustomVisibleRange(date) {
|
2986 | let { props } = this;
|
2987 | let input = props.visibleRangeInput;
|
2988 | let simpleInput = typeof input === 'function'
|
2989 | ? input.call(props.calendarApi, props.dateEnv.toDate(date))
|
2990 | : input;
|
2991 | let range = this.refineRange(simpleInput);
|
2992 | if (range && (range.start == null || range.end == null)) {
|
2993 | return null;
|
2994 | }
|
2995 | return range;
|
2996 | }
|
2997 |
|
2998 |
|
2999 |
|
3000 | buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {
|
3001 | return currentRange;
|
3002 | }
|
3003 |
|
3004 |
|
3005 | buildDateIncrement(fallback) {
|
3006 | let { dateIncrement } = this.props;
|
3007 | let customAlignment;
|
3008 | if (dateIncrement) {
|
3009 | return dateIncrement;
|
3010 | }
|
3011 | if ((customAlignment = this.props.dateAlignment)) {
|
3012 | return createDuration(1, customAlignment);
|
3013 | }
|
3014 | if (fallback) {
|
3015 | return fallback;
|
3016 | }
|
3017 | return createDuration({ days: 1 });
|
3018 | }
|
3019 | refineRange(rangeInput) {
|
3020 | if (rangeInput) {
|
3021 | let range = parseRange(rangeInput, this.props.dateEnv);
|
3022 | if (range) {
|
3023 | range = computeVisibleDayRange(range);
|
3024 | }
|
3025 | return range;
|
3026 | }
|
3027 | return null;
|
3028 | }
|
3029 | |
3030 |
|
3031 |
|
3032 | initHiddenDays() {
|
3033 | let hiddenDays = this.props.hiddenDays || [];
|
3034 | let isHiddenDayHash = [];
|
3035 | let dayCnt = 0;
|
3036 | let i;
|
3037 | if (this.props.weekends === false) {
|
3038 | hiddenDays.push(0, 6);
|
3039 | }
|
3040 | for (i = 0; i < 7; i += 1) {
|
3041 | if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
|
3042 | dayCnt += 1;
|
3043 | }
|
3044 | }
|
3045 | if (!dayCnt) {
|
3046 | throw new Error('invalid hiddenDays');
|
3047 | }
|
3048 | this.isHiddenDayHash = isHiddenDayHash;
|
3049 | }
|
3050 |
|
3051 |
|
3052 | trimHiddenDays(range) {
|
3053 | let { start, end } = range;
|
3054 | if (start) {
|
3055 | start = this.skipHiddenDays(start);
|
3056 | }
|
3057 | if (end) {
|
3058 | end = this.skipHiddenDays(end, -1, true);
|
3059 | }
|
3060 | if (start == null || end == null || start < end) {
|
3061 | return { start, end };
|
3062 | }
|
3063 | return null;
|
3064 | }
|
3065 |
|
3066 |
|
3067 | isHiddenDay(day) {
|
3068 | if (day instanceof Date) {
|
3069 | day = day.getUTCDay();
|
3070 | }
|
3071 | return this.isHiddenDayHash[day];
|
3072 | }
|
3073 |
|
3074 |
|
3075 |
|
3076 |
|
3077 |
|
3078 | skipHiddenDays(date, inc = 1, isExclusive = false) {
|
3079 | while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
|
3080 | date = addDays(date, inc);
|
3081 | }
|
3082 | return date;
|
3083 | }
|
3084 | }
|
3085 |
|
3086 | function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
|
3087 | return {
|
3088 | instanceId: guid(),
|
3089 | defId,
|
3090 | range,
|
3091 | forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
|
3092 | forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo,
|
3093 | };
|
3094 | }
|
3095 |
|
3096 | function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
|
3097 | for (let i = 0; i < recurringTypes.length; i += 1) {
|
3098 | let parsed = recurringTypes[i].parse(refined, dateEnv);
|
3099 | if (parsed) {
|
3100 | let { allDay } = refined;
|
3101 | if (allDay == null) {
|
3102 | allDay = defaultAllDay;
|
3103 | if (allDay == null) {
|
3104 | allDay = parsed.allDayGuess;
|
3105 | if (allDay == null) {
|
3106 | allDay = false;
|
3107 | }
|
3108 | }
|
3109 | }
|
3110 | return {
|
3111 | allDay,
|
3112 | duration: parsed.duration,
|
3113 | typeData: parsed.typeData,
|
3114 | typeId: i,
|
3115 | };
|
3116 | }
|
3117 | }
|
3118 | return null;
|
3119 | }
|
3120 | function expandRecurring(eventStore, framingRange, context) {
|
3121 | let { dateEnv, pluginHooks, options } = context;
|
3122 | let { defs, instances } = eventStore;
|
3123 |
|
3124 |
|
3125 | instances = filterHash(instances, (instance) => !defs[instance.defId].recurringDef);
|
3126 | for (let defId in defs) {
|
3127 | let def = defs[defId];
|
3128 | if (def.recurringDef) {
|
3129 | let { duration } = def.recurringDef;
|
3130 | if (!duration) {
|
3131 | duration = def.allDay ?
|
3132 | options.defaultAllDayEventDuration :
|
3133 | options.defaultTimedEventDuration;
|
3134 | }
|
3135 | let starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
|
3136 | for (let start of starts) {
|
3137 | let instance = createEventInstance(defId, {
|
3138 | start,
|
3139 | end: dateEnv.add(start, duration),
|
3140 | });
|
3141 | instances[instance.instanceId] = instance;
|
3142 | }
|
3143 | }
|
3144 | }
|
3145 | return { defs, instances };
|
3146 | }
|
3147 |
|
3148 |
|
3149 |
|
3150 | function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
|
3151 | let typeDef = recurringTypes[eventDef.recurringDef.typeId];
|
3152 | let markers = typeDef.expand(eventDef.recurringDef.typeData, {
|
3153 | start: dateEnv.subtract(framingRange.start, duration),
|
3154 | end: framingRange.end,
|
3155 | }, dateEnv);
|
3156 |
|
3157 | if (eventDef.allDay) {
|
3158 | markers = markers.map(startOfDay);
|
3159 | }
|
3160 | return markers;
|
3161 | }
|
3162 |
|
3163 | const EVENT_NON_DATE_REFINERS = {
|
3164 | id: String,
|
3165 | groupId: String,
|
3166 | title: String,
|
3167 | url: String,
|
3168 | interactive: Boolean,
|
3169 | };
|
3170 | const EVENT_DATE_REFINERS = {
|
3171 | start: identity,
|
3172 | end: identity,
|
3173 | date: identity,
|
3174 | allDay: Boolean,
|
3175 | };
|
3176 | const EVENT_REFINERS = Object.assign(Object.assign(Object.assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });
|
3177 | function parseEvent(raw, eventSource, context, allowOpenRange, refiners = buildEventRefiners(context), defIdMap, instanceIdMap) {
|
3178 | let { refined, extra } = refineEventDef(raw, context, refiners);
|
3179 | let defaultAllDay = computeIsDefaultAllDay(eventSource, context);
|
3180 | let recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
|
3181 | if (recurringRes) {
|
3182 | let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context, defIdMap);
|
3183 | def.recurringDef = {
|
3184 | typeId: recurringRes.typeId,
|
3185 | typeData: recurringRes.typeData,
|
3186 | duration: recurringRes.duration,
|
3187 | };
|
3188 | return { def, instance: null };
|
3189 | }
|
3190 | let singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
|
3191 | if (singleRes) {
|
3192 | let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context, defIdMap);
|
3193 | let instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
|
3194 | if (instanceIdMap && def.publicId && instanceIdMap[def.publicId]) {
|
3195 | instance.instanceId = instanceIdMap[def.publicId];
|
3196 | }
|
3197 | return { def, instance };
|
3198 | }
|
3199 | return null;
|
3200 | }
|
3201 | function refineEventDef(raw, context, refiners = buildEventRefiners(context)) {
|
3202 | return refineProps(raw, refiners);
|
3203 | }
|
3204 | function buildEventRefiners(context) {
|
3205 | return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
|
3206 | }
|
3207 |
|
3208 |
|
3209 |
|
3210 |
|
3211 | function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context, defIdMap) {
|
3212 | let def = {
|
3213 | title: refined.title || '',
|
3214 | groupId: refined.groupId || '',
|
3215 | publicId: refined.id || '',
|
3216 | url: refined.url || '',
|
3217 | recurringDef: null,
|
3218 | defId: ((defIdMap && refined.id) ? defIdMap[refined.id] : '') || guid(),
|
3219 | sourceId,
|
3220 | allDay,
|
3221 | hasEnd,
|
3222 | interactive: refined.interactive,
|
3223 | ui: createEventUi(refined, context),
|
3224 | extendedProps: Object.assign(Object.assign({}, (refined.extendedProps || {})), extra),
|
3225 | };
|
3226 | for (let memberAdder of context.pluginHooks.eventDefMemberAdders) {
|
3227 | Object.assign(def, memberAdder(refined));
|
3228 | }
|
3229 |
|
3230 | Object.freeze(def.ui.classNames);
|
3231 | Object.freeze(def.extendedProps);
|
3232 | return def;
|
3233 | }
|
3234 | function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
|
3235 | let { allDay } = refined;
|
3236 | let startMeta;
|
3237 | let startMarker = null;
|
3238 | let hasEnd = false;
|
3239 | let endMeta;
|
3240 | let endMarker = null;
|
3241 | let startInput = refined.start != null ? refined.start : refined.date;
|
3242 | startMeta = context.dateEnv.createMarkerMeta(startInput);
|
3243 | if (startMeta) {
|
3244 | startMarker = startMeta.marker;
|
3245 | }
|
3246 | else if (!allowOpenRange) {
|
3247 | return null;
|
3248 | }
|
3249 | if (refined.end != null) {
|
3250 | endMeta = context.dateEnv.createMarkerMeta(refined.end);
|
3251 | }
|
3252 | if (allDay == null) {
|
3253 | if (defaultAllDay != null) {
|
3254 | allDay = defaultAllDay;
|
3255 | }
|
3256 | else {
|
3257 |
|
3258 | allDay = (!startMeta || startMeta.isTimeUnspecified) &&
|
3259 | (!endMeta || endMeta.isTimeUnspecified);
|
3260 | }
|
3261 | }
|
3262 | if (allDay && startMarker) {
|
3263 | startMarker = startOfDay(startMarker);
|
3264 | }
|
3265 | if (endMeta) {
|
3266 | endMarker = endMeta.marker;
|
3267 | if (allDay) {
|
3268 | endMarker = startOfDay(endMarker);
|
3269 | }
|
3270 | if (startMarker && endMarker <= startMarker) {
|
3271 | endMarker = null;
|
3272 | }
|
3273 | }
|
3274 | if (endMarker) {
|
3275 | hasEnd = true;
|
3276 | }
|
3277 | else if (!allowOpenRange) {
|
3278 | hasEnd = context.options.forceEventDuration || false;
|
3279 | endMarker = context.dateEnv.add(startMarker, allDay ?
|
3280 | context.options.defaultAllDayEventDuration :
|
3281 | context.options.defaultTimedEventDuration);
|
3282 | }
|
3283 | return {
|
3284 | allDay,
|
3285 | hasEnd,
|
3286 | range: { start: startMarker, end: endMarker },
|
3287 | forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
|
3288 | forcedEndTzo: endMeta ? endMeta.forcedTzo : null,
|
3289 | };
|
3290 | }
|
3291 | function computeIsDefaultAllDay(eventSource, context) {
|
3292 | let res = null;
|
3293 | if (eventSource) {
|
3294 | res = eventSource.defaultAllDay;
|
3295 | }
|
3296 | if (res == null) {
|
3297 | res = context.options.defaultAllDay;
|
3298 | }
|
3299 | return res;
|
3300 | }
|
3301 |
|
3302 | function parseEvents(rawEvents, eventSource, context, allowOpenRange, defIdMap, instanceIdMap) {
|
3303 | let eventStore = createEmptyEventStore();
|
3304 | let eventRefiners = buildEventRefiners(context);
|
3305 | for (let rawEvent of rawEvents) {
|
3306 | let tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners, defIdMap, instanceIdMap);
|
3307 | if (tuple) {
|
3308 | eventTupleToStore(tuple, eventStore);
|
3309 | }
|
3310 | }
|
3311 | return eventStore;
|
3312 | }
|
3313 | function eventTupleToStore(tuple, eventStore = createEmptyEventStore()) {
|
3314 | eventStore.defs[tuple.def.defId] = tuple.def;
|
3315 | if (tuple.instance) {
|
3316 | eventStore.instances[tuple.instance.instanceId] = tuple.instance;
|
3317 | }
|
3318 | return eventStore;
|
3319 | }
|
3320 |
|
3321 |
|
3322 |
|
3323 | function getRelevantEvents(eventStore, instanceId) {
|
3324 | let instance = eventStore.instances[instanceId];
|
3325 | if (instance) {
|
3326 | let def = eventStore.defs[instance.defId];
|
3327 |
|
3328 | let newStore = filterEventStoreDefs(eventStore, (lookDef) => isEventDefsGrouped(def, lookDef));
|
3329 |
|
3330 |
|
3331 | newStore.defs[def.defId] = def;
|
3332 | newStore.instances[instance.instanceId] = instance;
|
3333 | return newStore;
|
3334 | }
|
3335 | return createEmptyEventStore();
|
3336 | }
|
3337 | function isEventDefsGrouped(def0, def1) {
|
3338 | return Boolean(def0.groupId && def0.groupId === def1.groupId);
|
3339 | }
|
3340 | function createEmptyEventStore() {
|
3341 | return { defs: {}, instances: {} };
|
3342 | }
|
3343 | function mergeEventStores(store0, store1) {
|
3344 | return {
|
3345 | defs: Object.assign(Object.assign({}, store0.defs), store1.defs),
|
3346 | instances: Object.assign(Object.assign({}, store0.instances), store1.instances),
|
3347 | };
|
3348 | }
|
3349 | function filterEventStoreDefs(eventStore, filterFunc) {
|
3350 | let defs = filterHash(eventStore.defs, filterFunc);
|
3351 | let instances = filterHash(eventStore.instances, (instance) => (defs[instance.defId]
|
3352 | ));
|
3353 | return { defs, instances };
|
3354 | }
|
3355 | function excludeSubEventStore(master, sub) {
|
3356 | let { defs, instances } = master;
|
3357 | let filteredDefs = {};
|
3358 | let filteredInstances = {};
|
3359 | for (let defId in defs) {
|
3360 | if (!sub.defs[defId]) {
|
3361 | filteredDefs[defId] = defs[defId];
|
3362 | }
|
3363 | }
|
3364 | for (let instanceId in instances) {
|
3365 | if (!sub.instances[instanceId] &&
|
3366 | filteredDefs[instances[instanceId].defId]
|
3367 | ) {
|
3368 | filteredInstances[instanceId] = instances[instanceId];
|
3369 | }
|
3370 | }
|
3371 | return {
|
3372 | defs: filteredDefs,
|
3373 | instances: filteredInstances,
|
3374 | };
|
3375 | }
|
3376 |
|
3377 | function normalizeConstraint(input, context) {
|
3378 | if (Array.isArray(input)) {
|
3379 | return parseEvents(input, null, context, true);
|
3380 | }
|
3381 | if (typeof input === 'object' && input) {
|
3382 | return parseEvents([input], null, context, true);
|
3383 | }
|
3384 | if (input != null) {
|
3385 | return String(input);
|
3386 | }
|
3387 | return null;
|
3388 | }
|
3389 |
|
3390 | function parseClassNames(raw) {
|
3391 | if (Array.isArray(raw)) {
|
3392 | return raw;
|
3393 | }
|
3394 | if (typeof raw === 'string') {
|
3395 | return raw.split(/\s+/);
|
3396 | }
|
3397 | return [];
|
3398 | }
|
3399 |
|
3400 |
|
3401 |
|
3402 |
|
3403 | const EVENT_UI_REFINERS = {
|
3404 | display: String,
|
3405 | editable: Boolean,
|
3406 | startEditable: Boolean,
|
3407 | durationEditable: Boolean,
|
3408 | constraint: identity,
|
3409 | overlap: identity,
|
3410 | allow: identity,
|
3411 | className: parseClassNames,
|
3412 | classNames: parseClassNames,
|
3413 | color: String,
|
3414 | backgroundColor: String,
|
3415 | borderColor: String,
|
3416 | textColor: String,
|
3417 | };
|
3418 | const EMPTY_EVENT_UI = {
|
3419 | display: null,
|
3420 | startEditable: null,
|
3421 | durationEditable: null,
|
3422 | constraints: [],
|
3423 | overlap: null,
|
3424 | allows: [],
|
3425 | backgroundColor: '',
|
3426 | borderColor: '',
|
3427 | textColor: '',
|
3428 | classNames: [],
|
3429 | };
|
3430 | function createEventUi(refined, context) {
|
3431 | let constraint = normalizeConstraint(refined.constraint, context);
|
3432 | return {
|
3433 | display: refined.display || null,
|
3434 | startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
|
3435 | durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
|
3436 | constraints: constraint != null ? [constraint] : [],
|
3437 | overlap: refined.overlap != null ? refined.overlap : null,
|
3438 | allows: refined.allow != null ? [refined.allow] : [],
|
3439 | backgroundColor: refined.backgroundColor || refined.color || '',
|
3440 | borderColor: refined.borderColor || refined.color || '',
|
3441 | textColor: refined.textColor || '',
|
3442 | classNames: (refined.className || []).concat(refined.classNames || []),
|
3443 | };
|
3444 | }
|
3445 |
|
3446 | function combineEventUis(uis) {
|
3447 | return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
|
3448 | }
|
3449 | function combineTwoEventUis(item0, item1) {
|
3450 | return {
|
3451 | display: item1.display != null ? item1.display : item0.display,
|
3452 | startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
|
3453 | durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
|
3454 | constraints: item0.constraints.concat(item1.constraints),
|
3455 | overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
|
3456 | allows: item0.allows.concat(item1.allows),
|
3457 | backgroundColor: item1.backgroundColor || item0.backgroundColor,
|
3458 | borderColor: item1.borderColor || item0.borderColor,
|
3459 | textColor: item1.textColor || item0.textColor,
|
3460 | classNames: item0.classNames.concat(item1.classNames),
|
3461 | };
|
3462 | }
|
3463 |
|
3464 | const EVENT_SOURCE_REFINERS = {
|
3465 | id: String,
|
3466 | defaultAllDay: Boolean,
|
3467 | url: String,
|
3468 | format: String,
|
3469 | events: identity,
|
3470 | eventDataTransform: identity,
|
3471 |
|
3472 | success: identity,
|
3473 | failure: identity,
|
3474 | };
|
3475 | function parseEventSource(raw, context, refiners = buildEventSourceRefiners(context)) {
|
3476 | let rawObj;
|
3477 | if (typeof raw === 'string') {
|
3478 | rawObj = { url: raw };
|
3479 | }
|
3480 | else if (typeof raw === 'function' || Array.isArray(raw)) {
|
3481 | rawObj = { events: raw };
|
3482 | }
|
3483 | else if (typeof raw === 'object' && raw) {
|
3484 | rawObj = raw;
|
3485 | }
|
3486 | if (rawObj) {
|
3487 | let { refined, extra } = refineProps(rawObj, refiners);
|
3488 | let metaRes = buildEventSourceMeta(refined, context);
|
3489 | if (metaRes) {
|
3490 | return {
|
3491 | _raw: raw,
|
3492 | isFetching: false,
|
3493 | latestFetchId: '',
|
3494 | fetchRange: null,
|
3495 | defaultAllDay: refined.defaultAllDay,
|
3496 | eventDataTransform: refined.eventDataTransform,
|
3497 | success: refined.success,
|
3498 | failure: refined.failure,
|
3499 | publicId: refined.id || '',
|
3500 | sourceId: guid(),
|
3501 | sourceDefId: metaRes.sourceDefId,
|
3502 | meta: metaRes.meta,
|
3503 | ui: createEventUi(refined, context),
|
3504 | extendedProps: extra,
|
3505 | };
|
3506 | }
|
3507 | }
|
3508 | return null;
|
3509 | }
|
3510 | function buildEventSourceRefiners(context) {
|
3511 | return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners);
|
3512 | }
|
3513 | function buildEventSourceMeta(raw, context) {
|
3514 | let defs = context.pluginHooks.eventSourceDefs;
|
3515 | for (let i = defs.length - 1; i >= 0; i -= 1) {
|
3516 | let def = defs[i];
|
3517 | let meta = def.parseMeta(raw);
|
3518 | if (meta) {
|
3519 | return { sourceDefId: i, meta };
|
3520 | }
|
3521 | }
|
3522 | return null;
|
3523 | }
|
3524 |
|
3525 | function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
|
3526 | switch (action.type) {
|
3527 | case 'RECEIVE_EVENTS':
|
3528 | return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
|
3529 | case 'RESET_RAW_EVENTS':
|
3530 | return resetRawEvents(eventStore, eventSources[action.sourceId], action.rawEvents, dateProfile.activeRange, context);
|
3531 | case 'ADD_EVENTS':
|
3532 | return addEvent(eventStore, action.eventStore,
|
3533 | dateProfile ? dateProfile.activeRange : null, context);
|
3534 | case 'RESET_EVENTS':
|
3535 | return action.eventStore;
|
3536 | case 'MERGE_EVENTS':
|
3537 | return mergeEventStores(eventStore, action.eventStore);
|
3538 | case 'PREV':
|
3539 | case 'NEXT':
|
3540 | case 'CHANGE_DATE':
|
3541 | case 'CHANGE_VIEW_TYPE':
|
3542 | if (dateProfile) {
|
3543 | return expandRecurring(eventStore, dateProfile.activeRange, context);
|
3544 | }
|
3545 | return eventStore;
|
3546 | case 'REMOVE_EVENTS':
|
3547 | return excludeSubEventStore(eventStore, action.eventStore);
|
3548 | case 'REMOVE_EVENT_SOURCE':
|
3549 | return excludeEventsBySourceId(eventStore, action.sourceId);
|
3550 | case 'REMOVE_ALL_EVENT_SOURCES':
|
3551 | return filterEventStoreDefs(eventStore, (eventDef) => (!eventDef.sourceId
|
3552 | ));
|
3553 | case 'REMOVE_ALL_EVENTS':
|
3554 | return createEmptyEventStore();
|
3555 | default:
|
3556 | return eventStore;
|
3557 | }
|
3558 | }
|
3559 | function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
|
3560 | if (eventSource &&
|
3561 | fetchId === eventSource.latestFetchId
|
3562 | ) {
|
3563 | let subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
|
3564 | if (fetchRange) {
|
3565 | subset = expandRecurring(subset, fetchRange, context);
|
3566 | }
|
3567 | return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
|
3568 | }
|
3569 | return eventStore;
|
3570 | }
|
3571 | function resetRawEvents(existingEventStore, eventSource, rawEvents, activeRange, context) {
|
3572 | const { defIdMap, instanceIdMap } = buildPublicIdMaps(existingEventStore);
|
3573 | let newEventStore = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context, false, defIdMap, instanceIdMap);
|
3574 | return expandRecurring(newEventStore, activeRange, context);
|
3575 | }
|
3576 | function transformRawEvents(rawEvents, eventSource, context) {
|
3577 | let calEachTransform = context.options.eventDataTransform;
|
3578 | let sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
|
3579 | if (sourceEachTransform) {
|
3580 | rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
|
3581 | }
|
3582 | if (calEachTransform) {
|
3583 | rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
|
3584 | }
|
3585 | return rawEvents;
|
3586 | }
|
3587 | function transformEachRawEvent(rawEvents, func) {
|
3588 | let refinedEvents;
|
3589 | if (!func) {
|
3590 | refinedEvents = rawEvents;
|
3591 | }
|
3592 | else {
|
3593 | refinedEvents = [];
|
3594 | for (let rawEvent of rawEvents) {
|
3595 | let refinedEvent = func(rawEvent);
|
3596 | if (refinedEvent) {
|
3597 | refinedEvents.push(refinedEvent);
|
3598 | }
|
3599 | else if (refinedEvent == null) {
|
3600 | refinedEvents.push(rawEvent);
|
3601 | }
|
3602 | }
|
3603 | }
|
3604 | return refinedEvents;
|
3605 | }
|
3606 | function addEvent(eventStore, subset, expandRange, context) {
|
3607 | if (expandRange) {
|
3608 | subset = expandRecurring(subset, expandRange, context);
|
3609 | }
|
3610 | return mergeEventStores(eventStore, subset);
|
3611 | }
|
3612 | function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
|
3613 | let { defs } = eventStore;
|
3614 | let instances = mapHash(eventStore.instances, (instance) => {
|
3615 | let def = defs[instance.defId];
|
3616 | if (def.allDay) {
|
3617 | return instance;
|
3618 | }
|
3619 | return Object.assign(Object.assign({}, instance), { range: {
|
3620 | start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
|
3621 | end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)),
|
3622 | }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });
|
3623 | });
|
3624 | return { defs, instances };
|
3625 | }
|
3626 | function excludeEventsBySourceId(eventStore, sourceId) {
|
3627 | return filterEventStoreDefs(eventStore, (eventDef) => eventDef.sourceId !== sourceId);
|
3628 | }
|
3629 |
|
3630 | function excludeInstances(eventStore, removals) {
|
3631 | return {
|
3632 | defs: eventStore.defs,
|
3633 | instances: filterHash(eventStore.instances, (instance) => !removals[instance.instanceId]),
|
3634 | };
|
3635 | }
|
3636 | function buildPublicIdMaps(eventStore) {
|
3637 | const { defs, instances } = eventStore;
|
3638 | const defIdMap = {};
|
3639 | const instanceIdMap = {};
|
3640 | for (let defId in defs) {
|
3641 | const def = defs[defId];
|
3642 | const { publicId } = def;
|
3643 | if (publicId) {
|
3644 | defIdMap[publicId] = defId;
|
3645 | }
|
3646 | }
|
3647 | for (let instanceId in instances) {
|
3648 | const instance = instances[instanceId];
|
3649 | const def = defs[instance.defId];
|
3650 | const { publicId } = def;
|
3651 | if (publicId) {
|
3652 | instanceIdMap[publicId] = instanceId;
|
3653 | }
|
3654 | }
|
3655 | return { defIdMap, instanceIdMap };
|
3656 | }
|
3657 |
|
3658 | class Emitter {
|
3659 | constructor() {
|
3660 | this.handlers = {};
|
3661 | this.thisContext = null;
|
3662 | }
|
3663 | setThisContext(thisContext) {
|
3664 | this.thisContext = thisContext;
|
3665 | }
|
3666 | setOptions(options) {
|
3667 | this.options = options;
|
3668 | }
|
3669 | on(type, handler) {
|
3670 | addToHash(this.handlers, type, handler);
|
3671 | }
|
3672 | off(type, handler) {
|
3673 | removeFromHash(this.handlers, type, handler);
|
3674 | }
|
3675 | trigger(type, ...args) {
|
3676 | let attachedHandlers = this.handlers[type] || [];
|
3677 | let optionHandler = this.options && this.options[type];
|
3678 | let handlers = [].concat(optionHandler || [], attachedHandlers);
|
3679 | for (let handler of handlers) {
|
3680 | handler.apply(this.thisContext, args);
|
3681 | }
|
3682 | }
|
3683 | hasHandlers(type) {
|
3684 | return Boolean((this.handlers[type] && this.handlers[type].length) ||
|
3685 | (this.options && this.options[type]));
|
3686 | }
|
3687 | }
|
3688 | function addToHash(hash, type, handler) {
|
3689 | (hash[type] || (hash[type] = []))
|
3690 | .push(handler);
|
3691 | }
|
3692 | function removeFromHash(hash, type, handler) {
|
3693 | if (handler) {
|
3694 | if (hash[type]) {
|
3695 | hash[type] = hash[type].filter((func) => func !== handler);
|
3696 | }
|
3697 | }
|
3698 | else {
|
3699 | delete hash[type];
|
3700 | }
|
3701 | }
|
3702 |
|
3703 | const DEF_DEFAULTS = {
|
3704 | startTime: '09:00',
|
3705 | endTime: '17:00',
|
3706 | daysOfWeek: [1, 2, 3, 4, 5],
|
3707 | display: 'inverse-background',
|
3708 | classNames: 'fc-non-business',
|
3709 | groupId: '_businessHours',
|
3710 | };
|
3711 |
|
3712 |
|
3713 |
|
3714 | function parseBusinessHours(input, context) {
|
3715 | return parseEvents(refineInputs(input), null, context);
|
3716 | }
|
3717 | function refineInputs(input) {
|
3718 | let rawDefs;
|
3719 | if (input === true) {
|
3720 | rawDefs = [{}];
|
3721 | }
|
3722 | else if (Array.isArray(input)) {
|
3723 |
|
3724 | rawDefs = input.filter((rawDef) => rawDef.daysOfWeek);
|
3725 | }
|
3726 | else if (typeof input === 'object' && input) {
|
3727 | rawDefs = [input];
|
3728 | }
|
3729 | else {
|
3730 | rawDefs = [];
|
3731 | }
|
3732 | rawDefs = rawDefs.map((rawDef) => (Object.assign(Object.assign({}, DEF_DEFAULTS), rawDef)));
|
3733 | return rawDefs;
|
3734 | }
|
3735 |
|
3736 | function triggerDateSelect(selection, pev, context) {
|
3737 | context.emitter.trigger('select', Object.assign(Object.assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));
|
3738 | }
|
3739 | function triggerDateUnselect(pev, context) {
|
3740 | context.emitter.trigger('unselect', {
|
3741 | jsEvent: pev ? pev.origEvent : null,
|
3742 | view: context.viewApi || context.calendarApi.view,
|
3743 | });
|
3744 | }
|
3745 | function buildDateSpanApiWithContext(dateSpan, context) {
|
3746 | let props = {};
|
3747 | for (let transform of context.pluginHooks.dateSpanTransforms) {
|
3748 | Object.assign(props, transform(dateSpan, context));
|
3749 | }
|
3750 | Object.assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
|
3751 | return props;
|
3752 | }
|
3753 |
|
3754 |
|
3755 | function getDefaultEventEnd(allDay, marker, context) {
|
3756 | let { dateEnv, options } = context;
|
3757 | let end = marker;
|
3758 | if (allDay) {
|
3759 | end = startOfDay(end);
|
3760 | end = dateEnv.add(end, options.defaultAllDayEventDuration);
|
3761 | }
|
3762 | else {
|
3763 | end = dateEnv.add(end, options.defaultTimedEventDuration);
|
3764 | }
|
3765 | return end;
|
3766 | }
|
3767 |
|
3768 |
|
3769 | function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
|
3770 | let eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
|
3771 | let dest = createEmptyEventStore();
|
3772 | for (let defId in eventStore.defs) {
|
3773 | let def = eventStore.defs[defId];
|
3774 | dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
|
3775 | }
|
3776 | for (let instanceId in eventStore.instances) {
|
3777 | let instance = eventStore.instances[instanceId];
|
3778 | let def = dest.defs[instance.defId];
|
3779 | dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
|
3780 | }
|
3781 | return dest;
|
3782 | }
|
3783 | function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
|
3784 | let standardProps = mutation.standardProps || {};
|
3785 |
|
3786 |
|
3787 |
|
3788 | if (standardProps.hasEnd == null &&
|
3789 | eventConfig.durationEditable &&
|
3790 | (mutation.startDelta || mutation.endDelta)) {
|
3791 | standardProps.hasEnd = true;
|
3792 | }
|
3793 | let copy = Object.assign(Object.assign(Object.assign({}, eventDef), standardProps), { ui: Object.assign(Object.assign({}, eventDef.ui), standardProps.ui) });
|
3794 | if (mutation.extendedProps) {
|
3795 | copy.extendedProps = Object.assign(Object.assign({}, copy.extendedProps), mutation.extendedProps);
|
3796 | }
|
3797 | for (let applier of context.pluginHooks.eventDefMutationAppliers) {
|
3798 | applier(copy, mutation, context);
|
3799 | }
|
3800 | if (!copy.hasEnd && context.options.forceEventDuration) {
|
3801 | copy.hasEnd = true;
|
3802 | }
|
3803 | return copy;
|
3804 | }
|
3805 | function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef
|
3806 | eventConfig, mutation, context) {
|
3807 | let { dateEnv } = context;
|
3808 | let forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
|
3809 | let clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
|
3810 | let copy = Object.assign({}, eventInstance);
|
3811 | if (forceAllDay) {
|
3812 | copy.range = computeAlignedDayRange(copy.range);
|
3813 | }
|
3814 | if (mutation.datesDelta && eventConfig.startEditable) {
|
3815 | copy.range = {
|
3816 | start: dateEnv.add(copy.range.start, mutation.datesDelta),
|
3817 | end: dateEnv.add(copy.range.end, mutation.datesDelta),
|
3818 | };
|
3819 | }
|
3820 | if (mutation.startDelta && eventConfig.durationEditable) {
|
3821 | copy.range = {
|
3822 | start: dateEnv.add(copy.range.start, mutation.startDelta),
|
3823 | end: copy.range.end,
|
3824 | };
|
3825 | }
|
3826 | if (mutation.endDelta && eventConfig.durationEditable) {
|
3827 | copy.range = {
|
3828 | start: copy.range.start,
|
3829 | end: dateEnv.add(copy.range.end, mutation.endDelta),
|
3830 | };
|
3831 | }
|
3832 | if (clearEnd) {
|
3833 | copy.range = {
|
3834 | start: copy.range.start,
|
3835 | end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context),
|
3836 | };
|
3837 | }
|
3838 |
|
3839 |
|
3840 | if (eventDef.allDay) {
|
3841 | copy.range = {
|
3842 | start: startOfDay(copy.range.start),
|
3843 | end: startOfDay(copy.range.end),
|
3844 | };
|
3845 | }
|
3846 |
|
3847 | if (copy.range.end < copy.range.start) {
|
3848 | copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
|
3849 | }
|
3850 | return copy;
|
3851 | }
|
3852 |
|
3853 | class EventSourceImpl {
|
3854 | constructor(context, internalEventSource) {
|
3855 | this.context = context;
|
3856 | this.internalEventSource = internalEventSource;
|
3857 | }
|
3858 | remove() {
|
3859 | this.context.dispatch({
|
3860 | type: 'REMOVE_EVENT_SOURCE',
|
3861 | sourceId: this.internalEventSource.sourceId,
|
3862 | });
|
3863 | }
|
3864 | refetch() {
|
3865 | this.context.dispatch({
|
3866 | type: 'FETCH_EVENT_SOURCES',
|
3867 | sourceIds: [this.internalEventSource.sourceId],
|
3868 | isRefetch: true,
|
3869 | });
|
3870 | }
|
3871 | get id() {
|
3872 | return this.internalEventSource.publicId;
|
3873 | }
|
3874 | get url() {
|
3875 | return this.internalEventSource.meta.url;
|
3876 | }
|
3877 | get format() {
|
3878 | return this.internalEventSource.meta.format;
|
3879 | }
|
3880 | }
|
3881 |
|
3882 | class EventImpl {
|
3883 |
|
3884 |
|
3885 | constructor(context, def, instance) {
|
3886 | this._context = context;
|
3887 | this._def = def;
|
3888 | this._instance = instance || null;
|
3889 | }
|
3890 | |
3891 |
|
3892 |
|
3893 | setProp(name, val) {
|
3894 | if (name in EVENT_DATE_REFINERS) {
|
3895 | console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.');
|
3896 |
|
3897 | }
|
3898 | else if (name === 'id') {
|
3899 | val = EVENT_NON_DATE_REFINERS[name](val);
|
3900 | this.mutate({
|
3901 | standardProps: { publicId: val },
|
3902 | });
|
3903 | }
|
3904 | else if (name in EVENT_NON_DATE_REFINERS) {
|
3905 | val = EVENT_NON_DATE_REFINERS[name](val);
|
3906 | this.mutate({
|
3907 | standardProps: { [name]: val },
|
3908 | });
|
3909 | }
|
3910 | else if (name in EVENT_UI_REFINERS) {
|
3911 | let ui = EVENT_UI_REFINERS[name](val);
|
3912 | if (name === 'color') {
|
3913 | ui = { backgroundColor: val, borderColor: val };
|
3914 | }
|
3915 | else if (name === 'editable') {
|
3916 | ui = { startEditable: val, durationEditable: val };
|
3917 | }
|
3918 | else {
|
3919 | ui = { [name]: val };
|
3920 | }
|
3921 | this.mutate({
|
3922 | standardProps: { ui },
|
3923 | });
|
3924 | }
|
3925 | else {
|
3926 | console.warn(`Could not set prop '${name}'. Use setExtendedProp instead.`);
|
3927 | }
|
3928 | }
|
3929 | setExtendedProp(name, val) {
|
3930 | this.mutate({
|
3931 | extendedProps: { [name]: val },
|
3932 | });
|
3933 | }
|
3934 | setStart(startInput, options = {}) {
|
3935 | let { dateEnv } = this._context;
|
3936 | let start = dateEnv.createMarker(startInput);
|
3937 | if (start && this._instance) {
|
3938 | let instanceRange = this._instance.range;
|
3939 | let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
|
3940 | if (options.maintainDuration) {
|
3941 | this.mutate({ datesDelta: startDelta });
|
3942 | }
|
3943 | else {
|
3944 | this.mutate({ startDelta });
|
3945 | }
|
3946 | }
|
3947 | }
|
3948 | setEnd(endInput, options = {}) {
|
3949 | let { dateEnv } = this._context;
|
3950 | let end;
|
3951 | if (endInput != null) {
|
3952 | end = dateEnv.createMarker(endInput);
|
3953 | if (!end) {
|
3954 | return;
|
3955 | }
|
3956 | }
|
3957 | if (this._instance) {
|
3958 | if (end) {
|
3959 | let endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
|
3960 | this.mutate({ endDelta });
|
3961 | }
|
3962 | else {
|
3963 | this.mutate({ standardProps: { hasEnd: false } });
|
3964 | }
|
3965 | }
|
3966 | }
|
3967 | setDates(startInput, endInput, options = {}) {
|
3968 | let { dateEnv } = this._context;
|
3969 | let standardProps = { allDay: options.allDay };
|
3970 | let start = dateEnv.createMarker(startInput);
|
3971 | let end;
|
3972 | if (!start) {
|
3973 | return;
|
3974 | }
|
3975 | if (endInput != null) {
|
3976 | end = dateEnv.createMarker(endInput);
|
3977 | if (!end) {
|
3978 | return;
|
3979 | }
|
3980 | }
|
3981 | if (this._instance) {
|
3982 | let instanceRange = this._instance.range;
|
3983 |
|
3984 |
|
3985 | if (options.allDay === true) {
|
3986 | instanceRange = computeAlignedDayRange(instanceRange);
|
3987 | }
|
3988 | let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
|
3989 | if (end) {
|
3990 | let endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
|
3991 | if (durationsEqual(startDelta, endDelta)) {
|
3992 | this.mutate({ datesDelta: startDelta, standardProps });
|
3993 | }
|
3994 | else {
|
3995 | this.mutate({ startDelta, endDelta, standardProps });
|
3996 | }
|
3997 | }
|
3998 | else {
|
3999 | standardProps.hasEnd = false;
|
4000 | this.mutate({ datesDelta: startDelta, standardProps });
|
4001 | }
|
4002 | }
|
4003 | }
|
4004 | moveStart(deltaInput) {
|
4005 | let delta = createDuration(deltaInput);
|
4006 | if (delta) {
|
4007 | this.mutate({ startDelta: delta });
|
4008 | }
|
4009 | }
|
4010 | moveEnd(deltaInput) {
|
4011 | let delta = createDuration(deltaInput);
|
4012 | if (delta) {
|
4013 | this.mutate({ endDelta: delta });
|
4014 | }
|
4015 | }
|
4016 | moveDates(deltaInput) {
|
4017 | let delta = createDuration(deltaInput);
|
4018 | if (delta) {
|
4019 | this.mutate({ datesDelta: delta });
|
4020 | }
|
4021 | }
|
4022 | setAllDay(allDay, options = {}) {
|
4023 | let standardProps = { allDay };
|
4024 | let { maintainDuration } = options;
|
4025 | if (maintainDuration == null) {
|
4026 | maintainDuration = this._context.options.allDayMaintainDuration;
|
4027 | }
|
4028 | if (this._def.allDay !== allDay) {
|
4029 | standardProps.hasEnd = maintainDuration;
|
4030 | }
|
4031 | this.mutate({ standardProps });
|
4032 | }
|
4033 | formatRange(formatInput) {
|
4034 | let { dateEnv } = this._context;
|
4035 | let instance = this._instance;
|
4036 | let formatter = createFormatter(formatInput);
|
4037 | if (this._def.hasEnd) {
|
4038 | return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
|
4039 | forcedStartTzo: instance.forcedStartTzo,
|
4040 | forcedEndTzo: instance.forcedEndTzo,
|
4041 | });
|
4042 | }
|
4043 | return dateEnv.format(instance.range.start, formatter, {
|
4044 | forcedTzo: instance.forcedStartTzo,
|
4045 | });
|
4046 | }
|
4047 | mutate(mutation) {
|
4048 | let instance = this._instance;
|
4049 | if (instance) {
|
4050 | let def = this._def;
|
4051 | let context = this._context;
|
4052 | let { eventStore } = context.getCurrentData();
|
4053 | let relevantEvents = getRelevantEvents(eventStore, instance.instanceId);
|
4054 | let eventConfigBase = {
|
4055 | '': {
|
4056 | display: '',
|
4057 | startEditable: true,
|
4058 | durationEditable: true,
|
4059 | constraints: [],
|
4060 | overlap: null,
|
4061 | allows: [],
|
4062 | backgroundColor: '',
|
4063 | borderColor: '',
|
4064 | textColor: '',
|
4065 | classNames: [],
|
4066 | },
|
4067 | };
|
4068 | relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context);
|
4069 | let oldEvent = new EventImpl(context, def, instance);
|
4070 | this._def = relevantEvents.defs[def.defId];
|
4071 | this._instance = relevantEvents.instances[instance.instanceId];
|
4072 | context.dispatch({
|
4073 | type: 'MERGE_EVENTS',
|
4074 | eventStore: relevantEvents,
|
4075 | });
|
4076 | context.emitter.trigger('eventChange', {
|
4077 | oldEvent,
|
4078 | event: this,
|
4079 | relatedEvents: buildEventApis(relevantEvents, context, instance),
|
4080 | revert() {
|
4081 | context.dispatch({
|
4082 | type: 'RESET_EVENTS',
|
4083 | eventStore,
|
4084 | });
|
4085 | },
|
4086 | });
|
4087 | }
|
4088 | }
|
4089 | remove() {
|
4090 | let context = this._context;
|
4091 | let asStore = eventApiToStore(this);
|
4092 | context.dispatch({
|
4093 | type: 'REMOVE_EVENTS',
|
4094 | eventStore: asStore,
|
4095 | });
|
4096 | context.emitter.trigger('eventRemove', {
|
4097 | event: this,
|
4098 | relatedEvents: [],
|
4099 | revert() {
|
4100 | context.dispatch({
|
4101 | type: 'MERGE_EVENTS',
|
4102 | eventStore: asStore,
|
4103 | });
|
4104 | },
|
4105 | });
|
4106 | }
|
4107 | get source() {
|
4108 | let { sourceId } = this._def;
|
4109 | if (sourceId) {
|
4110 | return new EventSourceImpl(this._context, this._context.getCurrentData().eventSources[sourceId]);
|
4111 | }
|
4112 | return null;
|
4113 | }
|
4114 | get start() {
|
4115 | return this._instance ?
|
4116 | this._context.dateEnv.toDate(this._instance.range.start) :
|
4117 | null;
|
4118 | }
|
4119 | get end() {
|
4120 | return (this._instance && this._def.hasEnd) ?
|
4121 | this._context.dateEnv.toDate(this._instance.range.end) :
|
4122 | null;
|
4123 | }
|
4124 | get startStr() {
|
4125 | let instance = this._instance;
|
4126 | if (instance) {
|
4127 | return this._context.dateEnv.formatIso(instance.range.start, {
|
4128 | omitTime: this._def.allDay,
|
4129 | forcedTzo: instance.forcedStartTzo,
|
4130 | });
|
4131 | }
|
4132 | return '';
|
4133 | }
|
4134 | get endStr() {
|
4135 | let instance = this._instance;
|
4136 | if (instance && this._def.hasEnd) {
|
4137 | return this._context.dateEnv.formatIso(instance.range.end, {
|
4138 | omitTime: this._def.allDay,
|
4139 | forcedTzo: instance.forcedEndTzo,
|
4140 | });
|
4141 | }
|
4142 | return '';
|
4143 | }
|
4144 |
|
4145 |
|
4146 | get id() { return this._def.publicId; }
|
4147 | get groupId() { return this._def.groupId; }
|
4148 | get allDay() { return this._def.allDay; }
|
4149 | get title() { return this._def.title; }
|
4150 | get url() { return this._def.url; }
|
4151 | get display() { return this._def.ui.display || 'auto'; }
|
4152 | get startEditable() { return this._def.ui.startEditable; }
|
4153 | get durationEditable() { return this._def.ui.durationEditable; }
|
4154 | get constraint() { return this._def.ui.constraints[0] || null; }
|
4155 | get overlap() { return this._def.ui.overlap; }
|
4156 | get allow() { return this._def.ui.allows[0] || null; }
|
4157 | get backgroundColor() { return this._def.ui.backgroundColor; }
|
4158 | get borderColor() { return this._def.ui.borderColor; }
|
4159 | get textColor() { return this._def.ui.textColor; }
|
4160 |
|
4161 | get classNames() { return this._def.ui.classNames; }
|
4162 | get extendedProps() { return this._def.extendedProps; }
|
4163 | toPlainObject(settings = {}) {
|
4164 | let def = this._def;
|
4165 | let { ui } = def;
|
4166 | let { startStr, endStr } = this;
|
4167 | let res = {
|
4168 | allDay: def.allDay,
|
4169 | };
|
4170 | if (def.title) {
|
4171 | res.title = def.title;
|
4172 | }
|
4173 | if (startStr) {
|
4174 | res.start = startStr;
|
4175 | }
|
4176 | if (endStr) {
|
4177 | res.end = endStr;
|
4178 | }
|
4179 | if (def.publicId) {
|
4180 | res.id = def.publicId;
|
4181 | }
|
4182 | if (def.groupId) {
|
4183 | res.groupId = def.groupId;
|
4184 | }
|
4185 | if (def.url) {
|
4186 | res.url = def.url;
|
4187 | }
|
4188 | if (ui.display && ui.display !== 'auto') {
|
4189 | res.display = ui.display;
|
4190 | }
|
4191 |
|
4192 |
|
4193 | if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
|
4194 | res.color = ui.backgroundColor;
|
4195 | }
|
4196 | else {
|
4197 | if (ui.backgroundColor) {
|
4198 | res.backgroundColor = ui.backgroundColor;
|
4199 | }
|
4200 | if (ui.borderColor) {
|
4201 | res.borderColor = ui.borderColor;
|
4202 | }
|
4203 | }
|
4204 | if (ui.textColor) {
|
4205 | res.textColor = ui.textColor;
|
4206 | }
|
4207 | if (ui.classNames.length) {
|
4208 | res.classNames = ui.classNames;
|
4209 | }
|
4210 | if (Object.keys(def.extendedProps).length) {
|
4211 | if (settings.collapseExtendedProps) {
|
4212 | Object.assign(res, def.extendedProps);
|
4213 | }
|
4214 | else {
|
4215 | res.extendedProps = def.extendedProps;
|
4216 | }
|
4217 | }
|
4218 | return res;
|
4219 | }
|
4220 | toJSON() {
|
4221 | return this.toPlainObject();
|
4222 | }
|
4223 | }
|
4224 | function eventApiToStore(eventApi) {
|
4225 | let def = eventApi._def;
|
4226 | let instance = eventApi._instance;
|
4227 | return {
|
4228 | defs: { [def.defId]: def },
|
4229 | instances: instance
|
4230 | ? { [instance.instanceId]: instance }
|
4231 | : {},
|
4232 | };
|
4233 | }
|
4234 | function buildEventApis(eventStore, context, excludeInstance) {
|
4235 | let { defs, instances } = eventStore;
|
4236 | let eventApis = [];
|
4237 | let excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
|
4238 | for (let id in instances) {
|
4239 | let instance = instances[id];
|
4240 | let def = defs[instance.defId];
|
4241 | if (instance.instanceId !== excludeInstanceId) {
|
4242 | eventApis.push(new EventImpl(context, def, instance));
|
4243 | }
|
4244 | }
|
4245 | return eventApis;
|
4246 | }
|
4247 |
|
4248 |
|
4249 |
|
4250 |
|
4251 | function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
|
4252 | let inverseBgByGroupId = {};
|
4253 | let inverseBgByDefId = {};
|
4254 | let defByGroupId = {};
|
4255 | let bgRanges = [];
|
4256 | let fgRanges = [];
|
4257 | let eventUis = compileEventUis(eventStore.defs, eventUiBases);
|
4258 | for (let defId in eventStore.defs) {
|
4259 | let def = eventStore.defs[defId];
|
4260 | let ui = eventUis[def.defId];
|
4261 | if (ui.display === 'inverse-background') {
|
4262 | if (def.groupId) {
|
4263 | inverseBgByGroupId[def.groupId] = [];
|
4264 | if (!defByGroupId[def.groupId]) {
|
4265 | defByGroupId[def.groupId] = def;
|
4266 | }
|
4267 | }
|
4268 | else {
|
4269 | inverseBgByDefId[defId] = [];
|
4270 | }
|
4271 | }
|
4272 | }
|
4273 | for (let instanceId in eventStore.instances) {
|
4274 | let instance = eventStore.instances[instanceId];
|
4275 | let def = eventStore.defs[instance.defId];
|
4276 | let ui = eventUis[def.defId];
|
4277 | let origRange = instance.range;
|
4278 | let normalRange = (!def.allDay && nextDayThreshold) ?
|
4279 | computeVisibleDayRange(origRange, nextDayThreshold) :
|
4280 | origRange;
|
4281 | let slicedRange = intersectRanges(normalRange, framingRange);
|
4282 | if (slicedRange) {
|
4283 | if (ui.display === 'inverse-background') {
|
4284 | if (def.groupId) {
|
4285 | inverseBgByGroupId[def.groupId].push(slicedRange);
|
4286 | }
|
4287 | else {
|
4288 | inverseBgByDefId[instance.defId].push(slicedRange);
|
4289 | }
|
4290 | }
|
4291 | else if (ui.display !== 'none') {
|
4292 | (ui.display === 'background' ? bgRanges : fgRanges).push({
|
4293 | def,
|
4294 | ui,
|
4295 | instance,
|
4296 | range: slicedRange,
|
4297 | isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
|
4298 | isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(),
|
4299 | });
|
4300 | }
|
4301 | }
|
4302 | }
|
4303 | for (let groupId in inverseBgByGroupId) {
|
4304 | let ranges = inverseBgByGroupId[groupId];
|
4305 | let invertedRanges = invertRanges(ranges, framingRange);
|
4306 | for (let invertedRange of invertedRanges) {
|
4307 | let def = defByGroupId[groupId];
|
4308 | let ui = eventUis[def.defId];
|
4309 | bgRanges.push({
|
4310 | def,
|
4311 | ui,
|
4312 | instance: null,
|
4313 | range: invertedRange,
|
4314 | isStart: false,
|
4315 | isEnd: false,
|
4316 | });
|
4317 | }
|
4318 | }
|
4319 | for (let defId in inverseBgByDefId) {
|
4320 | let ranges = inverseBgByDefId[defId];
|
4321 | let invertedRanges = invertRanges(ranges, framingRange);
|
4322 | for (let invertedRange of invertedRanges) {
|
4323 | bgRanges.push({
|
4324 | def: eventStore.defs[defId],
|
4325 | ui: eventUis[defId],
|
4326 | instance: null,
|
4327 | range: invertedRange,
|
4328 | isStart: false,
|
4329 | isEnd: false,
|
4330 | });
|
4331 | }
|
4332 | }
|
4333 | return { bg: bgRanges, fg: fgRanges };
|
4334 | }
|
4335 | function hasBgRendering(def) {
|
4336 | return def.ui.display === 'background' || def.ui.display === 'inverse-background';
|
4337 | }
|
4338 | function setElSeg(el, seg) {
|
4339 | el.fcSeg = seg;
|
4340 | }
|
4341 | function getElSeg(el) {
|
4342 | return el.fcSeg ||
|
4343 | el.parentNode.fcSeg ||
|
4344 | null;
|
4345 | }
|
4346 |
|
4347 | function compileEventUis(eventDefs, eventUiBases) {
|
4348 | return mapHash(eventDefs, (eventDef) => compileEventUi(eventDef, eventUiBases));
|
4349 | }
|
4350 | function compileEventUi(eventDef, eventUiBases) {
|
4351 | let uis = [];
|
4352 | if (eventUiBases['']) {
|
4353 | uis.push(eventUiBases['']);
|
4354 | }
|
4355 | if (eventUiBases[eventDef.defId]) {
|
4356 | uis.push(eventUiBases[eventDef.defId]);
|
4357 | }
|
4358 | uis.push(eventDef.ui);
|
4359 | return combineEventUis(uis);
|
4360 | }
|
4361 | function sortEventSegs(segs, eventOrderSpecs) {
|
4362 | let objs = segs.map(buildSegCompareObj);
|
4363 | objs.sort((obj0, obj1) => compareByFieldSpecs(obj0, obj1, eventOrderSpecs));
|
4364 | return objs.map((c) => c._seg);
|
4365 | }
|
4366 |
|
4367 | function buildSegCompareObj(seg) {
|
4368 | let { eventRange } = seg;
|
4369 | let eventDef = eventRange.def;
|
4370 | let range = eventRange.instance ? eventRange.instance.range : eventRange.range;
|
4371 | let start = range.start ? range.start.valueOf() : 0;
|
4372 | let end = range.end ? range.end.valueOf() : 0;
|
4373 | return Object.assign(Object.assign(Object.assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start,
|
4374 | end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg });
|
4375 | }
|
4376 | function computeSegDraggable(seg, context) {
|
4377 | let { pluginHooks } = context;
|
4378 | let transformers = pluginHooks.isDraggableTransformers;
|
4379 | let { def, ui } = seg.eventRange;
|
4380 | let val = ui.startEditable;
|
4381 | for (let transformer of transformers) {
|
4382 | val = transformer(val, def, ui, context);
|
4383 | }
|
4384 | return val;
|
4385 | }
|
4386 | function computeSegStartResizable(seg, context) {
|
4387 | return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
|
4388 | }
|
4389 | function computeSegEndResizable(seg, context) {
|
4390 | return seg.isEnd && seg.eventRange.ui.durationEditable;
|
4391 | }
|
4392 | function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true
|
4393 | defaultDisplayEventEnd, // defaults to true
|
4394 | startOverride, endOverride) {
|
4395 | let { dateEnv, options } = context;
|
4396 | let { displayEventTime, displayEventEnd } = options;
|
4397 | let eventDef = seg.eventRange.def;
|
4398 | let eventInstance = seg.eventRange.instance;
|
4399 | if (displayEventTime == null) {
|
4400 | displayEventTime = defaultDisplayEventTime !== false;
|
4401 | }
|
4402 | if (displayEventEnd == null) {
|
4403 | displayEventEnd = defaultDisplayEventEnd !== false;
|
4404 | }
|
4405 | let wholeEventStart = eventInstance.range.start;
|
4406 | let wholeEventEnd = eventInstance.range.end;
|
4407 | let segStart = startOverride || seg.start || seg.eventRange.range.start;
|
4408 | let segEnd = endOverride || seg.end || seg.eventRange.range.end;
|
4409 | let isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf();
|
4410 | let isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf();
|
4411 | if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) {
|
4412 | segStart = isStartDay ? wholeEventStart : segStart;
|
4413 | segEnd = isEndDay ? wholeEventEnd : segEnd;
|
4414 | if (displayEventEnd && eventDef.hasEnd) {
|
4415 | return dateEnv.formatRange(segStart, segEnd, timeFormat, {
|
4416 | forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
|
4417 | forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo,
|
4418 | });
|
4419 | }
|
4420 | return dateEnv.format(segStart, timeFormat, {
|
4421 | forcedTzo: startOverride ? null : eventInstance.forcedStartTzo,
|
4422 | });
|
4423 | }
|
4424 | return '';
|
4425 | }
|
4426 | function getSegMeta(seg, todayRange, nowDate) {
|
4427 | let segRange = seg.eventRange.range;
|
4428 | return {
|
4429 | isPast: segRange.end <= (nowDate || todayRange.start),
|
4430 | isFuture: segRange.start >= (nowDate || todayRange.end),
|
4431 | isToday: todayRange && rangeContainsMarker(todayRange, segRange.start),
|
4432 | };
|
4433 | }
|
4434 | function getEventClassNames(props) {
|
4435 | let classNames = ['fc-event'];
|
4436 | if (props.isMirror) {
|
4437 | classNames.push('fc-event-mirror');
|
4438 | }
|
4439 | if (props.isDraggable) {
|
4440 | classNames.push('fc-event-draggable');
|
4441 | }
|
4442 | if (props.isStartResizable || props.isEndResizable) {
|
4443 | classNames.push('fc-event-resizable');
|
4444 | }
|
4445 | if (props.isDragging) {
|
4446 | classNames.push('fc-event-dragging');
|
4447 | }
|
4448 | if (props.isResizing) {
|
4449 | classNames.push('fc-event-resizing');
|
4450 | }
|
4451 | if (props.isSelected) {
|
4452 | classNames.push('fc-event-selected');
|
4453 | }
|
4454 | if (props.isStart) {
|
4455 | classNames.push('fc-event-start');
|
4456 | }
|
4457 | if (props.isEnd) {
|
4458 | classNames.push('fc-event-end');
|
4459 | }
|
4460 | if (props.isPast) {
|
4461 | classNames.push('fc-event-past');
|
4462 | }
|
4463 | if (props.isToday) {
|
4464 | classNames.push('fc-event-today');
|
4465 | }
|
4466 | if (props.isFuture) {
|
4467 | classNames.push('fc-event-future');
|
4468 | }
|
4469 | return classNames;
|
4470 | }
|
4471 | function buildEventRangeKey(eventRange) {
|
4472 | return eventRange.instance
|
4473 | ? eventRange.instance.instanceId
|
4474 | : `${eventRange.def.defId}:${eventRange.range.start.toISOString()}`;
|
4475 |
|
4476 | }
|
4477 | function getSegAnchorAttrs(seg, context) {
|
4478 | let { def, instance } = seg.eventRange;
|
4479 | let { url } = def;
|
4480 | if (url) {
|
4481 | return { href: url };
|
4482 | }
|
4483 | let { emitter, options } = context;
|
4484 | let { eventInteractive } = options;
|
4485 | if (eventInteractive == null) {
|
4486 | eventInteractive = def.interactive;
|
4487 | if (eventInteractive == null) {
|
4488 | eventInteractive = Boolean(emitter.hasHandlers('eventClick'));
|
4489 | }
|
4490 | }
|
4491 |
|
4492 | if (eventInteractive) {
|
4493 |
|
4494 | return createAriaKeyboardAttrs((ev) => {
|
4495 | emitter.trigger('eventClick', {
|
4496 | el: ev.target,
|
4497 | event: new EventImpl(context, def, instance),
|
4498 | jsEvent: ev,
|
4499 | view: context.viewApi,
|
4500 | });
|
4501 | });
|
4502 | }
|
4503 | return {};
|
4504 | }
|
4505 |
|
4506 | const STANDARD_PROPS = {
|
4507 | start: identity,
|
4508 | end: identity,
|
4509 | allDay: Boolean,
|
4510 | };
|
4511 | function parseDateSpan(raw, dateEnv, defaultDuration) {
|
4512 | let span = parseOpenDateSpan(raw, dateEnv);
|
4513 | let { range } = span;
|
4514 | if (!range.start) {
|
4515 | return null;
|
4516 | }
|
4517 | if (!range.end) {
|
4518 | if (defaultDuration == null) {
|
4519 | return null;
|
4520 | }
|
4521 | range.end = dateEnv.add(range.start, defaultDuration);
|
4522 | }
|
4523 | return span;
|
4524 | }
|
4525 |
|
4526 |
|
4527 |
|
4528 |
|
4529 | function parseOpenDateSpan(raw, dateEnv) {
|
4530 | let { refined: standardProps, extra } = refineProps(raw, STANDARD_PROPS);
|
4531 | let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
|
4532 | let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
|
4533 | let { allDay } = standardProps;
|
4534 | if (allDay == null) {
|
4535 | allDay = (startMeta && startMeta.isTimeUnspecified) &&
|
4536 | (!endMeta || endMeta.isTimeUnspecified);
|
4537 | }
|
4538 | return Object.assign({ range: {
|
4539 | start: startMeta ? startMeta.marker : null,
|
4540 | end: endMeta ? endMeta.marker : null,
|
4541 | }, allDay }, extra);
|
4542 | }
|
4543 | function isDateSpansEqual(span0, span1) {
|
4544 | return rangesEqual(span0.range, span1.range) &&
|
4545 | span0.allDay === span1.allDay &&
|
4546 | isSpanPropsEqual(span0, span1);
|
4547 | }
|
4548 |
|
4549 | function isSpanPropsEqual(span0, span1) {
|
4550 | for (let propName in span1) {
|
4551 | if (propName !== 'range' && propName !== 'allDay') {
|
4552 | if (span0[propName] !== span1[propName]) {
|
4553 | return false;
|
4554 | }
|
4555 | }
|
4556 | }
|
4557 |
|
4558 |
|
4559 | for (let propName in span0) {
|
4560 | if (!(propName in span1)) {
|
4561 | return false;
|
4562 | }
|
4563 | }
|
4564 | return true;
|
4565 | }
|
4566 | function buildDateSpanApi(span, dateEnv) {
|
4567 | return Object.assign(Object.assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });
|
4568 | }
|
4569 | function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
|
4570 | return Object.assign(Object.assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });
|
4571 | }
|
4572 | function buildRangeApi(range, dateEnv, omitTime) {
|
4573 | return {
|
4574 | start: dateEnv.toDate(range.start),
|
4575 | end: dateEnv.toDate(range.end),
|
4576 | startStr: dateEnv.formatIso(range.start, { omitTime }),
|
4577 | endStr: dateEnv.formatIso(range.end, { omitTime }),
|
4578 | };
|
4579 | }
|
4580 | function fabricateEventRange(dateSpan, eventUiBases, context) {
|
4581 | let res = refineEventDef({ editable: false }, context);
|
4582 | let def = parseEventDef(res.refined, res.extra, '',
|
4583 | dateSpan.allDay, true,
|
4584 | context);
|
4585 | return {
|
4586 | def,
|
4587 | ui: compileEventUi(def, eventUiBases),
|
4588 | instance: createEventInstance(def.defId, dateSpan.range),
|
4589 | range: dateSpan.range,
|
4590 | isStart: true,
|
4591 | isEnd: true,
|
4592 | };
|
4593 | }
|
4594 |
|
4595 |
|
4596 |
|
4597 |
|
4598 |
|
4599 |
|
4600 |
|
4601 | function unpromisify(func, normalizedSuccessCallback, normalizedFailureCallback) {
|
4602 |
|
4603 |
|
4604 | let isResolved = false;
|
4605 | let wrappedSuccess = function (res) {
|
4606 | if (!isResolved) {
|
4607 | isResolved = true;
|
4608 | normalizedSuccessCallback(res);
|
4609 | }
|
4610 | };
|
4611 | let wrappedFailure = function (error) {
|
4612 | if (!isResolved) {
|
4613 | isResolved = true;
|
4614 | normalizedFailureCallback(error);
|
4615 | }
|
4616 | };
|
4617 | let res = func(wrappedSuccess, wrappedFailure);
|
4618 | if (res && typeof res.then === 'function') {
|
4619 | res.then(wrappedSuccess, wrappedFailure);
|
4620 | }
|
4621 | }
|
4622 |
|
4623 | class JsonRequestError extends Error {
|
4624 | constructor(message, response) {
|
4625 | super(message);
|
4626 | this.response = response;
|
4627 | }
|
4628 | }
|
4629 | function requestJson(method, url, params) {
|
4630 | method = method.toUpperCase();
|
4631 | const fetchOptions = {
|
4632 | method,
|
4633 | };
|
4634 | if (method === 'GET') {
|
4635 | url += (url.indexOf('?') === -1 ? '?' : '&') +
|
4636 | new URLSearchParams(params);
|
4637 | }
|
4638 | else {
|
4639 | fetchOptions.body = new URLSearchParams(params);
|
4640 | fetchOptions.headers = {
|
4641 | 'Content-Type': 'application/x-www-form-urlencoded',
|
4642 | };
|
4643 | }
|
4644 | return fetch(url, fetchOptions).then((fetchRes) => {
|
4645 | if (fetchRes.ok) {
|
4646 | return fetchRes.json().then((parsedResponse) => {
|
4647 | return [parsedResponse, fetchRes];
|
4648 | }, () => {
|
4649 | throw new JsonRequestError('Failure parsing JSON', fetchRes);
|
4650 | });
|
4651 | }
|
4652 | else {
|
4653 | throw new JsonRequestError('Request failed', fetchRes);
|
4654 | }
|
4655 | });
|
4656 | }
|
4657 |
|
4658 | let canVGrowWithinCell;
|
4659 | function getCanVGrowWithinCell() {
|
4660 | if (canVGrowWithinCell == null) {
|
4661 | canVGrowWithinCell = computeCanVGrowWithinCell();
|
4662 | }
|
4663 | return canVGrowWithinCell;
|
4664 | }
|
4665 | function computeCanVGrowWithinCell() {
|
4666 |
|
4667 |
|
4668 | if (typeof document === 'undefined') {
|
4669 | return true;
|
4670 | }
|
4671 | let el = document.createElement('div');
|
4672 | el.style.position = 'absolute';
|
4673 | el.style.top = '0px';
|
4674 | el.style.left = '0px';
|
4675 | el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
|
4676 | el.querySelector('table').style.height = '100px';
|
4677 | el.querySelector('div').style.height = '100%';
|
4678 | document.body.appendChild(el);
|
4679 | let div = el.querySelector('div');
|
4680 | let possible = div.offsetHeight > 0;
|
4681 | document.body.removeChild(el);
|
4682 | return possible;
|
4683 | }
|
4684 |
|
4685 | class CalendarRoot extends BaseComponent {
|
4686 | constructor() {
|
4687 | super(...arguments);
|
4688 | this.state = {
|
4689 | forPrint: false,
|
4690 | };
|
4691 | this.handleBeforePrint = () => {
|
4692 | flushSync(() => {
|
4693 | this.setState({ forPrint: true });
|
4694 | });
|
4695 | };
|
4696 | this.handleAfterPrint = () => {
|
4697 | flushSync(() => {
|
4698 | this.setState({ forPrint: false });
|
4699 | });
|
4700 | };
|
4701 | }
|
4702 | render() {
|
4703 | let { props } = this;
|
4704 | let { options } = props;
|
4705 | let { forPrint } = this.state;
|
4706 | let isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
|
4707 | let height = (!isHeightAuto && options.height != null) ? options.height : '';
|
4708 | let classNames = [
|
4709 | 'fc',
|
4710 | forPrint ? 'fc-media-print' : 'fc-media-screen',
|
4711 | `fc-direction-${options.direction}`,
|
4712 | props.theme.getClass('root'),
|
4713 | ];
|
4714 | if (!getCanVGrowWithinCell()) {
|
4715 | classNames.push('fc-liquid-hack');
|
4716 | }
|
4717 | return props.children(classNames, height, isHeightAuto, forPrint);
|
4718 | }
|
4719 | componentDidMount() {
|
4720 | let { emitter } = this.props;
|
4721 | emitter.on('_beforeprint', this.handleBeforePrint);
|
4722 | emitter.on('_afterprint', this.handleAfterPrint);
|
4723 | }
|
4724 | componentWillUnmount() {
|
4725 | let { emitter } = this.props;
|
4726 | emitter.off('_beforeprint', this.handleBeforePrint);
|
4727 | emitter.off('_afterprint', this.handleAfterPrint);
|
4728 | }
|
4729 | }
|
4730 |
|
4731 | class Interaction {
|
4732 | constructor(settings) {
|
4733 | this.component = settings.component;
|
4734 | this.isHitComboAllowed = settings.isHitComboAllowed || null;
|
4735 | }
|
4736 | destroy() {
|
4737 | }
|
4738 | }
|
4739 | function parseInteractionSettings(component, input) {
|
4740 | return {
|
4741 | component,
|
4742 | el: input.el,
|
4743 | useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,
|
4744 | isHitComboAllowed: input.isHitComboAllowed || null,
|
4745 | };
|
4746 | }
|
4747 | function interactionSettingsToStore(settings) {
|
4748 | return {
|
4749 | [settings.component.uid]: settings,
|
4750 | };
|
4751 | }
|
4752 |
|
4753 | const interactionSettingsStore = {};
|
4754 |
|
4755 | class CalendarImpl {
|
4756 | getCurrentData() {
|
4757 | return this.currentDataManager.getCurrentData();
|
4758 | }
|
4759 | dispatch(action) {
|
4760 | this.currentDataManager.dispatch(action);
|
4761 | }
|
4762 | get view() { return this.getCurrentData().viewApi; }
|
4763 | batchRendering(callback) {
|
4764 | callback();
|
4765 | }
|
4766 | updateSize() {
|
4767 | this.trigger('_resize', true);
|
4768 | }
|
4769 |
|
4770 |
|
4771 | setOption(name, val) {
|
4772 | this.dispatch({
|
4773 | type: 'SET_OPTION',
|
4774 | optionName: name,
|
4775 | rawOptionValue: val,
|
4776 | });
|
4777 | }
|
4778 | getOption(name) {
|
4779 | return this.currentDataManager.currentCalendarOptionsInput[name];
|
4780 | }
|
4781 | getAvailableLocaleCodes() {
|
4782 | return Object.keys(this.getCurrentData().availableRawLocales);
|
4783 | }
|
4784 |
|
4785 |
|
4786 | on(handlerName, handler) {
|
4787 | let { currentDataManager } = this;
|
4788 | if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
|
4789 | currentDataManager.emitter.on(handlerName, handler);
|
4790 | }
|
4791 | else {
|
4792 | console.warn(`Unknown listener name '${handlerName}'`);
|
4793 | }
|
4794 | }
|
4795 | off(handlerName, handler) {
|
4796 | this.currentDataManager.emitter.off(handlerName, handler);
|
4797 | }
|
4798 |
|
4799 | trigger(handlerName, ...args) {
|
4800 | this.currentDataManager.emitter.trigger(handlerName, ...args);
|
4801 | }
|
4802 |
|
4803 |
|
4804 | changeView(viewType, dateOrRange) {
|
4805 | this.batchRendering(() => {
|
4806 | this.unselect();
|
4807 | if (dateOrRange) {
|
4808 | if (dateOrRange.start && dateOrRange.end) {
|
4809 | this.dispatch({
|
4810 | type: 'CHANGE_VIEW_TYPE',
|
4811 | viewType,
|
4812 | });
|
4813 | this.dispatch({
|
4814 | type: 'SET_OPTION',
|
4815 | optionName: 'visibleRange',
|
4816 | rawOptionValue: dateOrRange,
|
4817 | });
|
4818 | }
|
4819 | else {
|
4820 | let { dateEnv } = this.getCurrentData();
|
4821 | this.dispatch({
|
4822 | type: 'CHANGE_VIEW_TYPE',
|
4823 | viewType,
|
4824 | dateMarker: dateEnv.createMarker(dateOrRange),
|
4825 | });
|
4826 | }
|
4827 | }
|
4828 | else {
|
4829 | this.dispatch({
|
4830 | type: 'CHANGE_VIEW_TYPE',
|
4831 | viewType,
|
4832 | });
|
4833 | }
|
4834 | });
|
4835 | }
|
4836 |
|
4837 |
|
4838 |
|
4839 | zoomTo(dateMarker, viewType) {
|
4840 | let state = this.getCurrentData();
|
4841 | let spec;
|
4842 | viewType = viewType || 'day';
|
4843 | spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
|
4844 | this.unselect();
|
4845 | if (spec) {
|
4846 | this.dispatch({
|
4847 | type: 'CHANGE_VIEW_TYPE',
|
4848 | viewType: spec.type,
|
4849 | dateMarker,
|
4850 | });
|
4851 | }
|
4852 | else {
|
4853 | this.dispatch({
|
4854 | type: 'CHANGE_DATE',
|
4855 | dateMarker,
|
4856 | });
|
4857 | }
|
4858 | }
|
4859 |
|
4860 |
|
4861 | getUnitViewSpec(unit) {
|
4862 | let { viewSpecs, toolbarConfig } = this.getCurrentData();
|
4863 | let viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []);
|
4864 | let i;
|
4865 | let spec;
|
4866 | for (let viewType in viewSpecs) {
|
4867 | viewTypes.push(viewType);
|
4868 | }
|
4869 | for (i = 0; i < viewTypes.length; i += 1) {
|
4870 | spec = viewSpecs[viewTypes[i]];
|
4871 | if (spec) {
|
4872 | if (spec.singleUnit === unit) {
|
4873 | return spec;
|
4874 | }
|
4875 | }
|
4876 | }
|
4877 | return null;
|
4878 | }
|
4879 |
|
4880 |
|
4881 | prev() {
|
4882 | this.unselect();
|
4883 | this.dispatch({ type: 'PREV' });
|
4884 | }
|
4885 | next() {
|
4886 | this.unselect();
|
4887 | this.dispatch({ type: 'NEXT' });
|
4888 | }
|
4889 | prevYear() {
|
4890 | let state = this.getCurrentData();
|
4891 | this.unselect();
|
4892 | this.dispatch({
|
4893 | type: 'CHANGE_DATE',
|
4894 | dateMarker: state.dateEnv.addYears(state.currentDate, -1),
|
4895 | });
|
4896 | }
|
4897 | nextYear() {
|
4898 | let state = this.getCurrentData();
|
4899 | this.unselect();
|
4900 | this.dispatch({
|
4901 | type: 'CHANGE_DATE',
|
4902 | dateMarker: state.dateEnv.addYears(state.currentDate, 1),
|
4903 | });
|
4904 | }
|
4905 | today() {
|
4906 | let state = this.getCurrentData();
|
4907 | this.unselect();
|
4908 | this.dispatch({
|
4909 | type: 'CHANGE_DATE',
|
4910 | dateMarker: getNow(state.calendarOptions.now, state.dateEnv),
|
4911 | });
|
4912 | }
|
4913 | gotoDate(zonedDateInput) {
|
4914 | let state = this.getCurrentData();
|
4915 | this.unselect();
|
4916 | this.dispatch({
|
4917 | type: 'CHANGE_DATE',
|
4918 | dateMarker: state.dateEnv.createMarker(zonedDateInput),
|
4919 | });
|
4920 | }
|
4921 | incrementDate(deltaInput) {
|
4922 | let state = this.getCurrentData();
|
4923 | let delta = createDuration(deltaInput);
|
4924 | if (delta) {
|
4925 | this.unselect();
|
4926 | this.dispatch({
|
4927 | type: 'CHANGE_DATE',
|
4928 | dateMarker: state.dateEnv.add(state.currentDate, delta),
|
4929 | });
|
4930 | }
|
4931 | }
|
4932 | getDate() {
|
4933 | let state = this.getCurrentData();
|
4934 | return state.dateEnv.toDate(state.currentDate);
|
4935 | }
|
4936 |
|
4937 |
|
4938 | formatDate(d, formatter) {
|
4939 | let { dateEnv } = this.getCurrentData();
|
4940 | return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
|
4941 | }
|
4942 |
|
4943 | formatRange(d0, d1, settings) {
|
4944 | let { dateEnv } = this.getCurrentData();
|
4945 | return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
|
4946 | }
|
4947 | formatIso(d, omitTime) {
|
4948 | let { dateEnv } = this.getCurrentData();
|
4949 | return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime });
|
4950 | }
|
4951 |
|
4952 |
|
4953 | select(dateOrObj, endDate) {
|
4954 | let selectionInput;
|
4955 | if (endDate == null) {
|
4956 | if (dateOrObj.start != null) {
|
4957 | selectionInput = dateOrObj;
|
4958 | }
|
4959 | else {
|
4960 | selectionInput = {
|
4961 | start: dateOrObj,
|
4962 | end: null,
|
4963 | };
|
4964 | }
|
4965 | }
|
4966 | else {
|
4967 | selectionInput = {
|
4968 | start: dateOrObj,
|
4969 | end: endDate,
|
4970 | };
|
4971 | }
|
4972 | let state = this.getCurrentData();
|
4973 | let selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }));
|
4974 | if (selection) {
|
4975 | this.dispatch({ type: 'SELECT_DATES', selection });
|
4976 | triggerDateSelect(selection, null, state);
|
4977 | }
|
4978 | }
|
4979 | unselect(pev) {
|
4980 | let state = this.getCurrentData();
|
4981 | if (state.dateSelection) {
|
4982 | this.dispatch({ type: 'UNSELECT_DATES' });
|
4983 | triggerDateUnselect(pev, state);
|
4984 | }
|
4985 | }
|
4986 |
|
4987 |
|
4988 | addEvent(eventInput, sourceInput) {
|
4989 | if (eventInput instanceof EventImpl) {
|
4990 | let def = eventInput._def;
|
4991 | let instance = eventInput._instance;
|
4992 | let currentData = this.getCurrentData();
|
4993 |
|
4994 | if (!currentData.eventStore.defs[def.defId]) {
|
4995 | this.dispatch({
|
4996 | type: 'ADD_EVENTS',
|
4997 | eventStore: eventTupleToStore({ def, instance }),
|
4998 | });
|
4999 | this.triggerEventAdd(eventInput);
|
5000 | }
|
5001 | return eventInput;
|
5002 | }
|
5003 | let state = this.getCurrentData();
|
5004 | let eventSource;
|
5005 | if (sourceInput instanceof EventSourceImpl) {
|
5006 | eventSource = sourceInput.internalEventSource;
|
5007 | }
|
5008 | else if (typeof sourceInput === 'boolean') {
|
5009 | if (sourceInput) {
|
5010 | [eventSource] = hashValuesToArray(state.eventSources);
|
5011 | }
|
5012 | }
|
5013 | else if (sourceInput != null) {
|
5014 | let sourceApi = this.getEventSourceById(sourceInput);
|
5015 | if (!sourceApi) {
|
5016 | console.warn(`Could not find an event source with ID "${sourceInput}"`);
|
5017 | return null;
|
5018 | }
|
5019 | eventSource = sourceApi.internalEventSource;
|
5020 | }
|
5021 | let tuple = parseEvent(eventInput, eventSource, state, false);
|
5022 | if (tuple) {
|
5023 | let newEventApi = new EventImpl(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
|
5024 | this.dispatch({
|
5025 | type: 'ADD_EVENTS',
|
5026 | eventStore: eventTupleToStore(tuple),
|
5027 | });
|
5028 | this.triggerEventAdd(newEventApi);
|
5029 | return newEventApi;
|
5030 | }
|
5031 | return null;
|
5032 | }
|
5033 | triggerEventAdd(eventApi) {
|
5034 | let { emitter } = this.getCurrentData();
|
5035 | emitter.trigger('eventAdd', {
|
5036 | event: eventApi,
|
5037 | relatedEvents: [],
|
5038 | revert: () => {
|
5039 | this.dispatch({
|
5040 | type: 'REMOVE_EVENTS',
|
5041 | eventStore: eventApiToStore(eventApi),
|
5042 | });
|
5043 | },
|
5044 | });
|
5045 | }
|
5046 |
|
5047 | getEventById(id) {
|
5048 | let state = this.getCurrentData();
|
5049 | let { defs, instances } = state.eventStore;
|
5050 | id = String(id);
|
5051 | for (let defId in defs) {
|
5052 | let def = defs[defId];
|
5053 | if (def.publicId === id) {
|
5054 | if (def.recurringDef) {
|
5055 | return new EventImpl(state, def, null);
|
5056 | }
|
5057 | for (let instanceId in instances) {
|
5058 | let instance = instances[instanceId];
|
5059 | if (instance.defId === def.defId) {
|
5060 | return new EventImpl(state, def, instance);
|
5061 | }
|
5062 | }
|
5063 | }
|
5064 | }
|
5065 | return null;
|
5066 | }
|
5067 | getEvents() {
|
5068 | let currentData = this.getCurrentData();
|
5069 | return buildEventApis(currentData.eventStore, currentData);
|
5070 | }
|
5071 | removeAllEvents() {
|
5072 | this.dispatch({ type: 'REMOVE_ALL_EVENTS' });
|
5073 | }
|
5074 |
|
5075 |
|
5076 | getEventSources() {
|
5077 | let state = this.getCurrentData();
|
5078 | let sourceHash = state.eventSources;
|
5079 | let sourceApis = [];
|
5080 | for (let internalId in sourceHash) {
|
5081 | sourceApis.push(new EventSourceImpl(state, sourceHash[internalId]));
|
5082 | }
|
5083 | return sourceApis;
|
5084 | }
|
5085 | getEventSourceById(id) {
|
5086 | let state = this.getCurrentData();
|
5087 | let sourceHash = state.eventSources;
|
5088 | id = String(id);
|
5089 | for (let sourceId in sourceHash) {
|
5090 | if (sourceHash[sourceId].publicId === id) {
|
5091 | return new EventSourceImpl(state, sourceHash[sourceId]);
|
5092 | }
|
5093 | }
|
5094 | return null;
|
5095 | }
|
5096 | addEventSource(sourceInput) {
|
5097 | let state = this.getCurrentData();
|
5098 | if (sourceInput instanceof EventSourceImpl) {
|
5099 |
|
5100 | if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
|
5101 | this.dispatch({
|
5102 | type: 'ADD_EVENT_SOURCES',
|
5103 | sources: [sourceInput.internalEventSource],
|
5104 | });
|
5105 | }
|
5106 | return sourceInput;
|
5107 | }
|
5108 | let eventSource = parseEventSource(sourceInput, state);
|
5109 | if (eventSource) {
|
5110 | this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });
|
5111 | return new EventSourceImpl(state, eventSource);
|
5112 | }
|
5113 | return null;
|
5114 | }
|
5115 | removeAllEventSources() {
|
5116 | this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });
|
5117 | }
|
5118 | refetchEvents() {
|
5119 | this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true });
|
5120 | }
|
5121 |
|
5122 |
|
5123 | scrollToTime(timeInput) {
|
5124 | let time = createDuration(timeInput);
|
5125 | if (time) {
|
5126 | this.trigger('_scrollRequest', { time });
|
5127 | }
|
5128 | }
|
5129 | }
|
5130 |
|
5131 | function pointInsideRect(point, rect) {
|
5132 | return point.left >= rect.left &&
|
5133 | point.left < rect.right &&
|
5134 | point.top >= rect.top &&
|
5135 | point.top < rect.bottom;
|
5136 | }
|
5137 |
|
5138 | function intersectRects(rect1, rect2) {
|
5139 | let res = {
|
5140 | left: Math.max(rect1.left, rect2.left),
|
5141 | right: Math.min(rect1.right, rect2.right),
|
5142 | top: Math.max(rect1.top, rect2.top),
|
5143 | bottom: Math.min(rect1.bottom, rect2.bottom),
|
5144 | };
|
5145 | if (res.left < res.right && res.top < res.bottom) {
|
5146 | return res;
|
5147 | }
|
5148 | return false;
|
5149 | }
|
5150 | function translateRect(rect, deltaX, deltaY) {
|
5151 | return {
|
5152 | left: rect.left + deltaX,
|
5153 | right: rect.right + deltaX,
|
5154 | top: rect.top + deltaY,
|
5155 | bottom: rect.bottom + deltaY,
|
5156 | };
|
5157 | }
|
5158 |
|
5159 | function constrainPoint(point, rect) {
|
5160 | return {
|
5161 | left: Math.min(Math.max(point.left, rect.left), rect.right),
|
5162 | top: Math.min(Math.max(point.top, rect.top), rect.bottom),
|
5163 | };
|
5164 | }
|
5165 |
|
5166 | function getRectCenter(rect) {
|
5167 | return {
|
5168 | left: (rect.left + rect.right) / 2,
|
5169 | top: (rect.top + rect.bottom) / 2,
|
5170 | };
|
5171 | }
|
5172 |
|
5173 | function diffPoints(point1, point2) {
|
5174 | return {
|
5175 | left: point1.left - point2.left,
|
5176 | top: point1.top - point2.top,
|
5177 | };
|
5178 | }
|
5179 |
|
5180 | const EMPTY_EVENT_STORE = createEmptyEventStore();
|
5181 | class Splitter {
|
5182 | constructor() {
|
5183 | this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
|
5184 | this.splitDateSelection = memoize(this._splitDateSpan);
|
5185 | this.splitEventStore = memoize(this._splitEventStore);
|
5186 | this.splitIndividualUi = memoize(this._splitIndividualUi);
|
5187 | this.splitEventDrag = memoize(this._splitInteraction);
|
5188 | this.splitEventResize = memoize(this._splitInteraction);
|
5189 | this.eventUiBuilders = {};
|
5190 | }
|
5191 | splitProps(props) {
|
5192 | let keyInfos = this.getKeyInfo(props);
|
5193 | let defKeys = this.getKeysForEventDefs(props.eventStore);
|
5194 | let dateSelections = this.splitDateSelection(props.dateSelection);
|
5195 | let individualUi = this.splitIndividualUi(props.eventUiBases, defKeys);
|
5196 | let eventStores = this.splitEventStore(props.eventStore, defKeys);
|
5197 | let eventDrags = this.splitEventDrag(props.eventDrag);
|
5198 | let eventResizes = this.splitEventResize(props.eventResize);
|
5199 | let splitProps = {};
|
5200 | this.eventUiBuilders = mapHash(keyInfos, (info, key) => this.eventUiBuilders[key] || memoize(buildEventUiForKey));
|
5201 | for (let key in keyInfos) {
|
5202 | let keyInfo = keyInfos[key];
|
5203 | let eventStore = eventStores[key] || EMPTY_EVENT_STORE;
|
5204 | let buildEventUi = this.eventUiBuilders[key];
|
5205 | splitProps[key] = {
|
5206 | businessHours: keyInfo.businessHours || props.businessHours,
|
5207 | dateSelection: dateSelections[key] || null,
|
5208 | eventStore,
|
5209 | eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
|
5210 | eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
|
5211 | eventDrag: eventDrags[key] || null,
|
5212 | eventResize: eventResizes[key] || null,
|
5213 | };
|
5214 | }
|
5215 | return splitProps;
|
5216 | }
|
5217 | _splitDateSpan(dateSpan) {
|
5218 | let dateSpans = {};
|
5219 | if (dateSpan) {
|
5220 | let keys = this.getKeysForDateSpan(dateSpan);
|
5221 | for (let key of keys) {
|
5222 | dateSpans[key] = dateSpan;
|
5223 | }
|
5224 | }
|
5225 | return dateSpans;
|
5226 | }
|
5227 | _getKeysForEventDefs(eventStore) {
|
5228 | return mapHash(eventStore.defs, (eventDef) => this.getKeysForEventDef(eventDef));
|
5229 | }
|
5230 | _splitEventStore(eventStore, defKeys) {
|
5231 | let { defs, instances } = eventStore;
|
5232 | let splitStores = {};
|
5233 | for (let defId in defs) {
|
5234 | for (let key of defKeys[defId]) {
|
5235 | if (!splitStores[key]) {
|
5236 | splitStores[key] = createEmptyEventStore();
|
5237 | }
|
5238 | splitStores[key].defs[defId] = defs[defId];
|
5239 | }
|
5240 | }
|
5241 | for (let instanceId in instances) {
|
5242 | let instance = instances[instanceId];
|
5243 | for (let key of defKeys[instance.defId]) {
|
5244 | if (splitStores[key]) {
|
5245 | splitStores[key].instances[instanceId] = instance;
|
5246 | }
|
5247 | }
|
5248 | }
|
5249 | return splitStores;
|
5250 | }
|
5251 | _splitIndividualUi(eventUiBases, defKeys) {
|
5252 | let splitHashes = {};
|
5253 | for (let defId in eventUiBases) {
|
5254 | if (defId) {
|
5255 | for (let key of defKeys[defId]) {
|
5256 | if (!splitHashes[key]) {
|
5257 | splitHashes[key] = {};
|
5258 | }
|
5259 | splitHashes[key][defId] = eventUiBases[defId];
|
5260 | }
|
5261 | }
|
5262 | }
|
5263 | return splitHashes;
|
5264 | }
|
5265 | _splitInteraction(interaction) {
|
5266 | let splitStates = {};
|
5267 | if (interaction) {
|
5268 | let affectedStores = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents));
|
5269 |
|
5270 | let mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
|
5271 | let mutatedStores = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
|
5272 | let populate = (key) => {
|
5273 | if (!splitStates[key]) {
|
5274 | splitStates[key] = {
|
5275 | affectedEvents: affectedStores[key] || EMPTY_EVENT_STORE,
|
5276 | mutatedEvents: mutatedStores[key] || EMPTY_EVENT_STORE,
|
5277 | isEvent: interaction.isEvent,
|
5278 | };
|
5279 | }
|
5280 | };
|
5281 | for (let key in affectedStores) {
|
5282 | populate(key);
|
5283 | }
|
5284 | for (let key in mutatedStores) {
|
5285 | populate(key);
|
5286 | }
|
5287 | }
|
5288 | return splitStates;
|
5289 | }
|
5290 | }
|
5291 | function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
|
5292 | let baseParts = [];
|
5293 | if (allUi) {
|
5294 | baseParts.push(allUi);
|
5295 | }
|
5296 | if (eventUiForKey) {
|
5297 | baseParts.push(eventUiForKey);
|
5298 | }
|
5299 | let stuff = {
|
5300 | '': combineEventUis(baseParts),
|
5301 | };
|
5302 | if (individualUi) {
|
5303 | Object.assign(stuff, individualUi);
|
5304 | }
|
5305 | return stuff;
|
5306 | }
|
5307 |
|
5308 | function getDateMeta(date, todayRange, nowDate, dateProfile) {
|
5309 | return {
|
5310 | dow: date.getUTCDay(),
|
5311 | isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),
|
5312 | isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
|
5313 | isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
|
5314 | isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),
|
5315 | isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false),
|
5316 | };
|
5317 | }
|
5318 | function getDayClassNames(meta, theme) {
|
5319 | let classNames = [
|
5320 | 'fc-day',
|
5321 | `fc-day-${DAY_IDS[meta.dow]}`,
|
5322 | ];
|
5323 | if (meta.isDisabled) {
|
5324 | classNames.push('fc-day-disabled');
|
5325 | }
|
5326 | else {
|
5327 | if (meta.isToday) {
|
5328 | classNames.push('fc-day-today');
|
5329 | classNames.push(theme.getClass('today'));
|
5330 | }
|
5331 | if (meta.isPast) {
|
5332 | classNames.push('fc-day-past');
|
5333 | }
|
5334 | if (meta.isFuture) {
|
5335 | classNames.push('fc-day-future');
|
5336 | }
|
5337 | if (meta.isOther) {
|
5338 | classNames.push('fc-day-other');
|
5339 | }
|
5340 | }
|
5341 | return classNames;
|
5342 | }
|
5343 | function getSlotClassNames(meta, theme) {
|
5344 | let classNames = [
|
5345 | 'fc-slot',
|
5346 | `fc-slot-${DAY_IDS[meta.dow]}`,
|
5347 | ];
|
5348 | if (meta.isDisabled) {
|
5349 | classNames.push('fc-slot-disabled');
|
5350 | }
|
5351 | else {
|
5352 | if (meta.isToday) {
|
5353 | classNames.push('fc-slot-today');
|
5354 | classNames.push(theme.getClass('today'));
|
5355 | }
|
5356 | if (meta.isPast) {
|
5357 | classNames.push('fc-slot-past');
|
5358 | }
|
5359 | if (meta.isFuture) {
|
5360 | classNames.push('fc-slot-future');
|
5361 | }
|
5362 | }
|
5363 | return classNames;
|
5364 | }
|
5365 |
|
5366 | const DAY_FORMAT = createFormatter({ year: 'numeric', month: 'long', day: 'numeric' });
|
5367 | const WEEK_FORMAT = createFormatter({ week: 'long' });
|
5368 | function buildNavLinkAttrs(context, dateMarker, viewType = 'day', isTabbable = true) {
|
5369 | const { dateEnv, options, calendarApi } = context;
|
5370 | let dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT);
|
5371 | if (options.navLinks) {
|
5372 | let zonedDate = dateEnv.toDate(dateMarker);
|
5373 | const handleInteraction = (ev) => {
|
5374 | let customAction = viewType === 'day' ? options.navLinkDayClick :
|
5375 | viewType === 'week' ? options.navLinkWeekClick : null;
|
5376 | if (typeof customAction === 'function') {
|
5377 | customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
|
5378 | }
|
5379 | else {
|
5380 | if (typeof customAction === 'string') {
|
5381 | viewType = customAction;
|
5382 | }
|
5383 | calendarApi.zoomTo(dateMarker, viewType);
|
5384 | }
|
5385 | };
|
5386 | return Object.assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), 'data-navlink': '' }, (isTabbable
|
5387 | ? createAriaClickAttrs(handleInteraction)
|
5388 | : { onClick: handleInteraction }));
|
5389 | }
|
5390 | return { 'aria-label': dateStr };
|
5391 | }
|
5392 |
|
5393 | let _isRtlScrollbarOnLeft = null;
|
5394 | function getIsRtlScrollbarOnLeft() {
|
5395 | if (_isRtlScrollbarOnLeft === null) {
|
5396 | _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
|
5397 | }
|
5398 | return _isRtlScrollbarOnLeft;
|
5399 | }
|
5400 | function computeIsRtlScrollbarOnLeft() {
|
5401 | let outerEl = document.createElement('div');
|
5402 | applyStyle(outerEl, {
|
5403 | position: 'absolute',
|
5404 | top: -1000,
|
5405 | left: 0,
|
5406 | border: 0,
|
5407 | padding: 0,
|
5408 | overflow: 'scroll',
|
5409 | direction: 'rtl',
|
5410 | });
|
5411 | outerEl.innerHTML = '<div></div>';
|
5412 | document.body.appendChild(outerEl);
|
5413 | let innerEl = outerEl.firstChild;
|
5414 | let res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
|
5415 | removeElement(outerEl);
|
5416 | return res;
|
5417 | }
|
5418 |
|
5419 | let _scrollbarWidths;
|
5420 | function getScrollbarWidths() {
|
5421 | if (!_scrollbarWidths) {
|
5422 | _scrollbarWidths = computeScrollbarWidths();
|
5423 | }
|
5424 | return _scrollbarWidths;
|
5425 | }
|
5426 | function computeScrollbarWidths() {
|
5427 | let el = document.createElement('div');
|
5428 | el.style.overflow = 'scroll';
|
5429 | el.style.position = 'absolute';
|
5430 | el.style.top = '-9999px';
|
5431 | el.style.left = '-9999px';
|
5432 | document.body.appendChild(el);
|
5433 | let res = computeScrollbarWidthsForEl(el);
|
5434 | document.body.removeChild(el);
|
5435 | return res;
|
5436 | }
|
5437 |
|
5438 | function computeScrollbarWidthsForEl(el) {
|
5439 | return {
|
5440 | x: el.offsetHeight - el.clientHeight,
|
5441 | y: el.offsetWidth - el.clientWidth,
|
5442 | };
|
5443 | }
|
5444 |
|
5445 | function computeEdges(el, getPadding = false) {
|
5446 | let computedStyle = window.getComputedStyle(el);
|
5447 | let borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
|
5448 | let borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
|
5449 | let borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
|
5450 | let borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
|
5451 | let badScrollbarWidths = computeScrollbarWidthsForEl(el);
|
5452 | let scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
|
5453 | let scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
|
5454 | let res = {
|
5455 | borderLeft,
|
5456 | borderRight,
|
5457 | borderTop,
|
5458 | borderBottom,
|
5459 | scrollbarBottom,
|
5460 | scrollbarLeft: 0,
|
5461 | scrollbarRight: 0,
|
5462 | };
|
5463 | if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') {
|
5464 | res.scrollbarLeft = scrollbarLeftRight;
|
5465 | }
|
5466 | else {
|
5467 | res.scrollbarRight = scrollbarLeftRight;
|
5468 | }
|
5469 | if (getPadding) {
|
5470 | res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
|
5471 | res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
|
5472 | res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
|
5473 | res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
|
5474 | }
|
5475 | return res;
|
5476 | }
|
5477 | function computeInnerRect(el, goWithinPadding = false, doFromWindowViewport) {
|
5478 | let outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
|
5479 | let edges = computeEdges(el, goWithinPadding);
|
5480 | let res = {
|
5481 | left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
|
5482 | right: outerRect.right - edges.borderRight - edges.scrollbarRight,
|
5483 | top: outerRect.top + edges.borderTop,
|
5484 | bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,
|
5485 | };
|
5486 | if (goWithinPadding) {
|
5487 | res.left += edges.paddingLeft;
|
5488 | res.right -= edges.paddingRight;
|
5489 | res.top += edges.paddingTop;
|
5490 | res.bottom -= edges.paddingBottom;
|
5491 | }
|
5492 | return res;
|
5493 | }
|
5494 | function computeRect(el) {
|
5495 | let rect = el.getBoundingClientRect();
|
5496 | return {
|
5497 | left: rect.left + window.scrollX,
|
5498 | top: rect.top + window.scrollY,
|
5499 | right: rect.right + window.scrollX,
|
5500 | bottom: rect.bottom + window.scrollY,
|
5501 | };
|
5502 | }
|
5503 | function computeClippedClientRect(el) {
|
5504 | let clippingParents = getClippingParents(el);
|
5505 | let rect = el.getBoundingClientRect();
|
5506 | for (let clippingParent of clippingParents) {
|
5507 | let intersection = intersectRects(rect, clippingParent.getBoundingClientRect());
|
5508 | if (intersection) {
|
5509 | rect = intersection;
|
5510 | }
|
5511 | else {
|
5512 | return null;
|
5513 | }
|
5514 | }
|
5515 | return rect;
|
5516 | }
|
5517 |
|
5518 | function getClippingParents(el) {
|
5519 | let parents = [];
|
5520 | while (el instanceof HTMLElement) {
|
5521 | let computedStyle = window.getComputedStyle(el);
|
5522 | if (computedStyle.position === 'fixed') {
|
5523 | break;
|
5524 | }
|
5525 | if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
|
5526 | parents.push(el);
|
5527 | }
|
5528 | el = el.parentNode;
|
5529 | }
|
5530 | return parents;
|
5531 | }
|
5532 |
|
5533 |
|
5534 |
|
5535 |
|
5536 |
|
5537 |
|
5538 | class PositionCache {
|
5539 | constructor(originEl, els, isHorizontal, isVertical) {
|
5540 | this.els = els;
|
5541 | let originClientRect = this.originClientRect = originEl.getBoundingClientRect();
|
5542 | if (isHorizontal) {
|
5543 | this.buildElHorizontals(originClientRect.left);
|
5544 | }
|
5545 | if (isVertical) {
|
5546 | this.buildElVerticals(originClientRect.top);
|
5547 | }
|
5548 | }
|
5549 |
|
5550 | buildElHorizontals(originClientLeft) {
|
5551 | let lefts = [];
|
5552 | let rights = [];
|
5553 | for (let el of this.els) {
|
5554 | let rect = el.getBoundingClientRect();
|
5555 | lefts.push(rect.left - originClientLeft);
|
5556 | rights.push(rect.right - originClientLeft);
|
5557 | }
|
5558 | this.lefts = lefts;
|
5559 | this.rights = rights;
|
5560 | }
|
5561 |
|
5562 | buildElVerticals(originClientTop) {
|
5563 | let tops = [];
|
5564 | let bottoms = [];
|
5565 | for (let el of this.els) {
|
5566 | let rect = el.getBoundingClientRect();
|
5567 | tops.push(rect.top - originClientTop);
|
5568 | bottoms.push(rect.bottom - originClientTop);
|
5569 | }
|
5570 | this.tops = tops;
|
5571 | this.bottoms = bottoms;
|
5572 | }
|
5573 |
|
5574 |
|
5575 | leftToIndex(leftPosition) {
|
5576 | let { lefts, rights } = this;
|
5577 | let len = lefts.length;
|
5578 | let i;
|
5579 | for (i = 0; i < len; i += 1) {
|
5580 | if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
|
5581 | return i;
|
5582 | }
|
5583 | }
|
5584 | return undefined;
|
5585 | }
|
5586 |
|
5587 |
|
5588 | topToIndex(topPosition) {
|
5589 | let { tops, bottoms } = this;
|
5590 | let len = tops.length;
|
5591 | let i;
|
5592 | for (i = 0; i < len; i += 1) {
|
5593 | if (topPosition >= tops[i] && topPosition < bottoms[i]) {
|
5594 | return i;
|
5595 | }
|
5596 | }
|
5597 | return undefined;
|
5598 | }
|
5599 |
|
5600 | getWidth(leftIndex) {
|
5601 | return this.rights[leftIndex] - this.lefts[leftIndex];
|
5602 | }
|
5603 |
|
5604 | getHeight(topIndex) {
|
5605 | return this.bottoms[topIndex] - this.tops[topIndex];
|
5606 | }
|
5607 | similarTo(otherCache) {
|
5608 | return similarNumArrays(this.tops || [], otherCache.tops || []) &&
|
5609 | similarNumArrays(this.bottoms || [], otherCache.bottoms || []) &&
|
5610 | similarNumArrays(this.lefts || [], otherCache.lefts || []) &&
|
5611 | similarNumArrays(this.rights || [], otherCache.rights || []);
|
5612 | }
|
5613 | }
|
5614 | function similarNumArrays(a, b) {
|
5615 | const len = a.length;
|
5616 | if (len !== b.length) {
|
5617 | return false;
|
5618 | }
|
5619 | for (let i = 0; i < len; i++) {
|
5620 | if (Math.round(a[i]) !== Math.round(b[i])) {
|
5621 | return false;
|
5622 | }
|
5623 | }
|
5624 | return true;
|
5625 | }
|
5626 |
|
5627 |
|
5628 |
|
5629 |
|
5630 |
|
5631 |
|
5632 |
|
5633 | class ScrollController {
|
5634 | getMaxScrollTop() {
|
5635 | return this.getScrollHeight() - this.getClientHeight();
|
5636 | }
|
5637 | getMaxScrollLeft() {
|
5638 | return this.getScrollWidth() - this.getClientWidth();
|
5639 | }
|
5640 | canScrollVertically() {
|
5641 | return this.getMaxScrollTop() > 0;
|
5642 | }
|
5643 | canScrollHorizontally() {
|
5644 | return this.getMaxScrollLeft() > 0;
|
5645 | }
|
5646 | canScrollUp() {
|
5647 | return this.getScrollTop() > 0;
|
5648 | }
|
5649 | canScrollDown() {
|
5650 | return this.getScrollTop() < this.getMaxScrollTop();
|
5651 | }
|
5652 | canScrollLeft() {
|
5653 | return this.getScrollLeft() > 0;
|
5654 | }
|
5655 | canScrollRight() {
|
5656 | return this.getScrollLeft() < this.getMaxScrollLeft();
|
5657 | }
|
5658 | }
|
5659 | class ElementScrollController extends ScrollController {
|
5660 | constructor(el) {
|
5661 | super();
|
5662 | this.el = el;
|
5663 | }
|
5664 | getScrollTop() {
|
5665 | return this.el.scrollTop;
|
5666 | }
|
5667 | getScrollLeft() {
|
5668 | return this.el.scrollLeft;
|
5669 | }
|
5670 | setScrollTop(top) {
|
5671 | this.el.scrollTop = top;
|
5672 | }
|
5673 | setScrollLeft(left) {
|
5674 | this.el.scrollLeft = left;
|
5675 | }
|
5676 | getScrollWidth() {
|
5677 | return this.el.scrollWidth;
|
5678 | }
|
5679 | getScrollHeight() {
|
5680 | return this.el.scrollHeight;
|
5681 | }
|
5682 | getClientHeight() {
|
5683 | return this.el.clientHeight;
|
5684 | }
|
5685 | getClientWidth() {
|
5686 | return this.el.clientWidth;
|
5687 | }
|
5688 | }
|
5689 | class WindowScrollController extends ScrollController {
|
5690 | getScrollTop() {
|
5691 | return window.scrollY;
|
5692 | }
|
5693 | getScrollLeft() {
|
5694 | return window.scrollX;
|
5695 | }
|
5696 | setScrollTop(n) {
|
5697 | window.scroll(window.scrollX, n);
|
5698 | }
|
5699 | setScrollLeft(n) {
|
5700 | window.scroll(n, window.scrollY);
|
5701 | }
|
5702 | getScrollWidth() {
|
5703 | return document.documentElement.scrollWidth;
|
5704 | }
|
5705 | getScrollHeight() {
|
5706 | return document.documentElement.scrollHeight;
|
5707 | }
|
5708 | getClientHeight() {
|
5709 | return document.documentElement.clientHeight;
|
5710 | }
|
5711 | getClientWidth() {
|
5712 | return document.documentElement.clientWidth;
|
5713 | }
|
5714 | }
|
5715 |
|
5716 |
|
5717 |
|
5718 |
|
5719 |
|
5720 |
|
5721 |
|
5722 |
|
5723 | class DateComponent extends BaseComponent {
|
5724 | constructor() {
|
5725 | super(...arguments);
|
5726 | this.uid = guid();
|
5727 | }
|
5728 |
|
5729 |
|
5730 | prepareHits() {
|
5731 | }
|
5732 | queryHit(positionLeft, positionTop, elWidth, elHeight) {
|
5733 | return null;
|
5734 | }
|
5735 |
|
5736 |
|
5737 | isValidSegDownEl(el) {
|
5738 | return !this.props.eventDrag &&
|
5739 | !this.props.eventResize &&
|
5740 | !elementClosest(el, '.fc-event-mirror');
|
5741 | }
|
5742 | isValidDateDownEl(el) {
|
5743 | return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&
|
5744 | !elementClosest(el, '.fc-more-link') &&
|
5745 | !elementClosest(el, 'a[data-navlink]') &&
|
5746 | !elementClosest(el, '.fc-popover');
|
5747 | }
|
5748 | }
|
5749 |
|
5750 | class NamedTimeZoneImpl {
|
5751 | constructor(timeZoneName) {
|
5752 | this.timeZoneName = timeZoneName;
|
5753 | }
|
5754 | }
|
5755 |
|
5756 | class SegHierarchy {
|
5757 | constructor(getEntryThickness = (entry) => {
|
5758 |
|
5759 | return entry.thickness || 1;
|
5760 | }) {
|
5761 | this.getEntryThickness = getEntryThickness;
|
5762 |
|
5763 | this.strictOrder = false;
|
5764 | this.allowReslicing = false;
|
5765 | this.maxCoord = -1;
|
5766 | this.maxStackCnt = -1;
|
5767 | this.levelCoords = [];
|
5768 | this.entriesByLevel = [];
|
5769 | this.stackCnts = {};
|
5770 | }
|
5771 | addSegs(inputs) {
|
5772 | let hiddenEntries = [];
|
5773 | for (let input of inputs) {
|
5774 | this.insertEntry(input, hiddenEntries);
|
5775 | }
|
5776 | return hiddenEntries;
|
5777 | }
|
5778 | insertEntry(entry, hiddenEntries) {
|
5779 | let insertion = this.findInsertion(entry);
|
5780 | if (this.isInsertionValid(insertion, entry)) {
|
5781 | this.insertEntryAt(entry, insertion);
|
5782 | }
|
5783 | else {
|
5784 | this.handleInvalidInsertion(insertion, entry, hiddenEntries);
|
5785 | }
|
5786 | }
|
5787 | isInsertionValid(insertion, entry) {
|
5788 | return (this.maxCoord === -1 || insertion.levelCoord + this.getEntryThickness(entry) <= this.maxCoord) &&
|
5789 | (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt);
|
5790 | }
|
5791 | handleInvalidInsertion(insertion, entry, hiddenEntries) {
|
5792 | if (this.allowReslicing && insertion.touchingEntry) {
|
5793 | const hiddenEntry = Object.assign(Object.assign({}, entry), { span: intersectSpans(entry.span, insertion.touchingEntry.span) });
|
5794 | hiddenEntries.push(hiddenEntry);
|
5795 | this.splitEntry(entry, insertion.touchingEntry, hiddenEntries);
|
5796 | }
|
5797 | else {
|
5798 | hiddenEntries.push(entry);
|
5799 | }
|
5800 | }
|
5801 | |
5802 |
|
5803 |
|
5804 | splitEntry(entry, barrier, hiddenEntries) {
|
5805 | let entrySpan = entry.span;
|
5806 | let barrierSpan = barrier.span;
|
5807 | if (entrySpan.start < barrierSpan.start) {
|
5808 | this.insertEntry({
|
5809 | index: entry.index,
|
5810 | thickness: entry.thickness,
|
5811 | span: { start: entrySpan.start, end: barrierSpan.start },
|
5812 | }, hiddenEntries);
|
5813 | }
|
5814 | if (entrySpan.end > barrierSpan.end) {
|
5815 | this.insertEntry({
|
5816 | index: entry.index,
|
5817 | thickness: entry.thickness,
|
5818 | span: { start: barrierSpan.end, end: entrySpan.end },
|
5819 | }, hiddenEntries);
|
5820 | }
|
5821 | }
|
5822 | insertEntryAt(entry, insertion) {
|
5823 | let { entriesByLevel, levelCoords } = this;
|
5824 | if (insertion.lateral === -1) {
|
5825 |
|
5826 | insertAt(levelCoords, insertion.level, insertion.levelCoord);
|
5827 | insertAt(entriesByLevel, insertion.level, [entry]);
|
5828 | }
|
5829 | else {
|
5830 |
|
5831 | insertAt(entriesByLevel[insertion.level], insertion.lateral, entry);
|
5832 | }
|
5833 | this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt;
|
5834 | }
|
5835 | |
5836 |
|
5837 |
|
5838 | findInsertion(newEntry) {
|
5839 | let { levelCoords, entriesByLevel, strictOrder, stackCnts } = this;
|
5840 | let levelCnt = levelCoords.length;
|
5841 | let candidateCoord = 0;
|
5842 | let touchingLevel = -1;
|
5843 | let touchingLateral = -1;
|
5844 | let touchingEntry = null;
|
5845 | let stackCnt = 0;
|
5846 | for (let trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) {
|
5847 | const trackingCoord = levelCoords[trackingLevel];
|
5848 |
|
5849 |
|
5850 | if (!strictOrder && trackingCoord >= candidateCoord + this.getEntryThickness(newEntry)) {
|
5851 | break;
|
5852 | }
|
5853 | let trackingEntries = entriesByLevel[trackingLevel];
|
5854 | let trackingEntry;
|
5855 | let searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd);
|
5856 | let lateralIndex = searchRes[0] + searchRes[1];
|
5857 | while (
|
5858 | (trackingEntry = trackingEntries[lateralIndex]) &&
|
5859 | trackingEntry.span.start < newEntry.span.end
|
5860 | ) {
|
5861 | let trackingEntryBottom = trackingCoord + this.getEntryThickness(trackingEntry);
|
5862 |
|
5863 | if (trackingEntryBottom > candidateCoord) {
|
5864 | candidateCoord = trackingEntryBottom;
|
5865 | touchingEntry = trackingEntry;
|
5866 | touchingLevel = trackingLevel;
|
5867 | touchingLateral = lateralIndex;
|
5868 | }
|
5869 |
|
5870 | if (trackingEntryBottom === candidateCoord) {
|
5871 |
|
5872 | stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1);
|
5873 | }
|
5874 | lateralIndex += 1;
|
5875 | }
|
5876 | }
|
5877 |
|
5878 | let destLevel = 0;
|
5879 | if (touchingEntry) {
|
5880 | destLevel = touchingLevel + 1;
|
5881 | while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) {
|
5882 | destLevel += 1;
|
5883 | }
|
5884 | }
|
5885 |
|
5886 | let destLateral = -1;
|
5887 | if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) {
|
5888 | destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0];
|
5889 | }
|
5890 | return {
|
5891 | touchingLevel,
|
5892 | touchingLateral,
|
5893 | touchingEntry,
|
5894 | stackCnt,
|
5895 | levelCoord: candidateCoord,
|
5896 | level: destLevel,
|
5897 | lateral: destLateral,
|
5898 | };
|
5899 | }
|
5900 |
|
5901 | toRects() {
|
5902 | let { entriesByLevel, levelCoords } = this;
|
5903 | let levelCnt = entriesByLevel.length;
|
5904 | let rects = [];
|
5905 | for (let level = 0; level < levelCnt; level += 1) {
|
5906 | let entries = entriesByLevel[level];
|
5907 | let levelCoord = levelCoords[level];
|
5908 | for (let entry of entries) {
|
5909 | rects.push(Object.assign(Object.assign({}, entry), { thickness: this.getEntryThickness(entry), levelCoord }));
|
5910 | }
|
5911 | }
|
5912 | return rects;
|
5913 | }
|
5914 | }
|
5915 | function getEntrySpanEnd(entry) {
|
5916 | return entry.span.end;
|
5917 | }
|
5918 | function buildEntryKey(entry) {
|
5919 | return entry.index + ':' + entry.span.start;
|
5920 | }
|
5921 |
|
5922 | function groupIntersectingEntries(entries) {
|
5923 | let merges = [];
|
5924 | for (let entry of entries) {
|
5925 | let filteredMerges = [];
|
5926 | let hungryMerge = {
|
5927 | span: entry.span,
|
5928 | entries: [entry],
|
5929 | };
|
5930 | for (let merge of merges) {
|
5931 | if (intersectSpans(merge.span, hungryMerge.span)) {
|
5932 | hungryMerge = {
|
5933 | entries: merge.entries.concat(hungryMerge.entries),
|
5934 | span: joinSpans(merge.span, hungryMerge.span),
|
5935 | };
|
5936 | }
|
5937 | else {
|
5938 | filteredMerges.push(merge);
|
5939 | }
|
5940 | }
|
5941 | filteredMerges.push(hungryMerge);
|
5942 | merges = filteredMerges;
|
5943 | }
|
5944 | return merges;
|
5945 | }
|
5946 | function joinSpans(span0, span1) {
|
5947 | return {
|
5948 | start: Math.min(span0.start, span1.start),
|
5949 | end: Math.max(span0.end, span1.end),
|
5950 | };
|
5951 | }
|
5952 | function intersectSpans(span0, span1) {
|
5953 | let start = Math.max(span0.start, span1.start);
|
5954 | let end = Math.min(span0.end, span1.end);
|
5955 | if (start < end) {
|
5956 | return { start, end };
|
5957 | }
|
5958 | return null;
|
5959 | }
|
5960 |
|
5961 |
|
5962 | function insertAt(arr, index, item) {
|
5963 | arr.splice(index, 0, item);
|
5964 | }
|
5965 | function binarySearch(a, searchVal, getItemVal) {
|
5966 | let startIndex = 0;
|
5967 | let endIndex = a.length;
|
5968 | if (!endIndex || searchVal < getItemVal(a[startIndex])) {
|
5969 | return [0, 0];
|
5970 | }
|
5971 | if (searchVal > getItemVal(a[endIndex - 1])) {
|
5972 | return [endIndex, 0];
|
5973 | }
|
5974 | while (startIndex < endIndex) {
|
5975 | let middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
|
5976 | let middleVal = getItemVal(a[middleIndex]);
|
5977 | if (searchVal < middleVal) {
|
5978 | endIndex = middleIndex;
|
5979 | }
|
5980 | else if (searchVal > middleVal) {
|
5981 | startIndex = middleIndex + 1;
|
5982 | }
|
5983 | else {
|
5984 | return [middleIndex, 1];
|
5985 | }
|
5986 | }
|
5987 | return [startIndex, 0];
|
5988 | }
|
5989 |
|
5990 |
|
5991 |
|
5992 |
|
5993 |
|
5994 |
|
5995 |
|
5996 |
|
5997 |
|
5998 |
|
5999 |
|
6000 |
|
6001 |
|
6002 |
|
6003 | class ElementDragging {
|
6004 | constructor(el, selector) {
|
6005 | this.emitter = new Emitter();
|
6006 | }
|
6007 | destroy() {
|
6008 | }
|
6009 | setMirrorIsVisible(bool) {
|
6010 |
|
6011 | }
|
6012 | setMirrorNeedsRevert(bool) {
|
6013 |
|
6014 | }
|
6015 | setAutoScrollEnabled(bool) {
|
6016 |
|
6017 | }
|
6018 | }
|
6019 |
|
6020 |
|
6021 |
|
6022 | const config = {};
|
6023 |
|
6024 |
|
6025 |
|
6026 |
|
6027 |
|
6028 | const DRAG_META_REFINERS = {
|
6029 | startTime: createDuration,
|
6030 | duration: createDuration,
|
6031 | create: Boolean,
|
6032 | sourceId: String,
|
6033 | };
|
6034 | function parseDragMeta(raw) {
|
6035 | let { refined, extra } = refineProps(raw, DRAG_META_REFINERS);
|
6036 | return {
|
6037 | startTime: refined.startTime || null,
|
6038 | duration: refined.duration || null,
|
6039 | create: refined.create != null ? refined.create : true,
|
6040 | sourceId: refined.sourceId,
|
6041 | leftoverProps: extra,
|
6042 | };
|
6043 | }
|
6044 |
|
6045 |
|
6046 | function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
|
6047 |
|
6048 |
|
6049 | if (!datesRepDistinctDays || dayCnt > 10) {
|
6050 | return createFormatter({ weekday: 'short' });
|
6051 | }
|
6052 | if (dayCnt > 1) {
|
6053 | return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true });
|
6054 | }
|
6055 | return createFormatter({ weekday: 'long' });
|
6056 | }
|
6057 |
|
6058 | const CLASS_NAME = 'fc-col-header-cell';
|
6059 | function renderInner$1(renderProps) {
|
6060 | return renderProps.text;
|
6061 | }
|
6062 |
|
6063 |
|
6064 | class TableDateCell extends BaseComponent {
|
6065 | render() {
|
6066 | let { dateEnv, options, theme, viewApi } = this.context;
|
6067 | let { props } = this;
|
6068 | let { date, dateProfile } = props;
|
6069 | let dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
|
6070 | let classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
|
6071 | let text = dateEnv.format(date, props.dayHeaderFormat);
|
6072 |
|
6073 | let navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1)
|
6074 | ? buildNavLinkAttrs(this.context, date)
|
6075 | : {};
|
6076 | let renderProps = Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraRenderProps), { text }), dayMeta);
|
6077 | return (createElement(ContentContainer, { elTag: "th", elClasses: classNames, elAttrs: Object.assign({ role: 'columnheader', colSpan: props.colSpan, 'data-date': !dayMeta.isDisabled ? formatDayString(date) : undefined }, props.extraDataAttrs), renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContainer) => (createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement(InnerContainer, { elTag: "a", elAttrs: navLinkAttrs, elClasses: [
|
6078 | 'fc-col-header-cell-cushion',
|
6079 | props.isSticky && 'fc-sticky',
|
6080 | ] }))))));
|
6081 | }
|
6082 | }
|
6083 |
|
6084 | const WEEKDAY_FORMAT = createFormatter({ weekday: 'long' });
|
6085 | class TableDowCell extends BaseComponent {
|
6086 | render() {
|
6087 | let { props } = this;
|
6088 | let { dateEnv, theme, viewApi, options } = this.context;
|
6089 | let date = addDays(new Date(259200000), props.dow);
|
6090 | let dateMeta = {
|
6091 | dow: props.dow,
|
6092 | isDisabled: false,
|
6093 | isFuture: false,
|
6094 | isPast: false,
|
6095 | isToday: false,
|
6096 | isOther: false,
|
6097 | };
|
6098 | let text = dateEnv.format(date, props.dayHeaderFormat);
|
6099 | let renderProps = Object.assign(Object.assign(Object.assign(Object.assign({
|
6100 | date }, dateMeta), { view: viewApi }), props.extraRenderProps), { text });
|
6101 | return (createElement(ContentContainer, { elTag: "th", elClasses: [
|
6102 | CLASS_NAME,
|
6103 | ...getDayClassNames(dateMeta, theme),
|
6104 | ...(props.extraClassNames || []),
|
6105 | ], elAttrs: Object.assign({ role: 'columnheader', colSpan: props.colSpan }, props.extraDataAttrs), renderProps: renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContent) => (createElement("div", { className: "fc-scrollgrid-sync-inner" },
|
6106 | createElement(InnerContent, { elTag: "a", elClasses: [
|
6107 | 'fc-col-header-cell-cushion',
|
6108 | props.isSticky && 'fc-sticky',
|
6109 | ], elAttrs: {
|
6110 | 'aria-label': dateEnv.format(date, WEEKDAY_FORMAT),
|
6111 | } })))));
|
6112 | }
|
6113 | }
|
6114 |
|
6115 | class NowTimer extends Component {
|
6116 | constructor(props, context) {
|
6117 | super(props, context);
|
6118 | this.initialNowDate = getNow(context.options.now, context.dateEnv);
|
6119 | this.initialNowQueriedMs = new Date().valueOf();
|
6120 | this.state = this.computeTiming().currentState;
|
6121 | }
|
6122 | render() {
|
6123 | let { props, state } = this;
|
6124 | return props.children(state.nowDate, state.todayRange);
|
6125 | }
|
6126 | componentDidMount() {
|
6127 | this.setTimeout();
|
6128 | }
|
6129 | componentDidUpdate(prevProps) {
|
6130 | if (prevProps.unit !== this.props.unit) {
|
6131 | this.clearTimeout();
|
6132 | this.setTimeout();
|
6133 | }
|
6134 | }
|
6135 | componentWillUnmount() {
|
6136 | this.clearTimeout();
|
6137 | }
|
6138 | computeTiming() {
|
6139 | let { props, context } = this;
|
6140 | let unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);
|
6141 | let currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);
|
6142 | let nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));
|
6143 | let waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
|
6144 |
|
6145 |
|
6146 | waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
|
6147 | return {
|
6148 | currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },
|
6149 | nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },
|
6150 | waitMs,
|
6151 | };
|
6152 | }
|
6153 | setTimeout() {
|
6154 | let { nextState, waitMs } = this.computeTiming();
|
6155 | this.timeoutId = setTimeout(() => {
|
6156 | this.setState(nextState, () => {
|
6157 | this.setTimeout();
|
6158 | });
|
6159 | }, waitMs);
|
6160 | }
|
6161 | clearTimeout() {
|
6162 | if (this.timeoutId) {
|
6163 | clearTimeout(this.timeoutId);
|
6164 | }
|
6165 | }
|
6166 | }
|
6167 | NowTimer.contextType = ViewContextType;
|
6168 | function buildDayRange(date) {
|
6169 | let start = startOfDay(date);
|
6170 | let end = addDays(start, 1);
|
6171 | return { start, end };
|
6172 | }
|
6173 |
|
6174 | class DayHeader extends BaseComponent {
|
6175 | constructor() {
|
6176 | super(...arguments);
|
6177 | this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
|
6178 | }
|
6179 | render() {
|
6180 | let { context } = this;
|
6181 | let { dates, dateProfile, datesRepDistinctDays, renderIntro } = this.props;
|
6182 | let dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
|
6183 | return (createElement(NowTimer, { unit: "day" }, (nowDate, todayRange) => (createElement("tr", { role: "row" },
|
6184 | renderIntro && renderIntro('day'),
|
6185 | dates.map((date) => (datesRepDistinctDays ? (createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : (createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))))))));
|
6186 | }
|
6187 | }
|
6188 | function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
|
6189 | return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
|
6190 | }
|
6191 |
|
6192 | class DaySeriesModel {
|
6193 | constructor(range, dateProfileGenerator) {
|
6194 | let date = range.start;
|
6195 | let { end } = range;
|
6196 | let indices = [];
|
6197 | let dates = [];
|
6198 | let dayIndex = -1;
|
6199 | while (date < end) {
|
6200 | if (dateProfileGenerator.isHiddenDay(date)) {
|
6201 | indices.push(dayIndex + 0.5);
|
6202 | }
|
6203 | else {
|
6204 | dayIndex += 1;
|
6205 | indices.push(dayIndex);
|
6206 | dates.push(date);
|
6207 | }
|
6208 | date = addDays(date, 1);
|
6209 | }
|
6210 | this.dates = dates;
|
6211 | this.indices = indices;
|
6212 | this.cnt = dates.length;
|
6213 | }
|
6214 | sliceRange(range) {
|
6215 | let firstIndex = this.getDateDayIndex(range.start);
|
6216 | let lastIndex = this.getDateDayIndex(addDays(range.end, -1));
|
6217 | let clippedFirstIndex = Math.max(0, firstIndex);
|
6218 | let clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
|
6219 |
|
6220 | clippedFirstIndex = Math.ceil(clippedFirstIndex);
|
6221 | clippedLastIndex = Math.floor(clippedLastIndex);
|
6222 | if (clippedFirstIndex <= clippedLastIndex) {
|
6223 | return {
|
6224 | firstIndex: clippedFirstIndex,
|
6225 | lastIndex: clippedLastIndex,
|
6226 | isStart: firstIndex === clippedFirstIndex,
|
6227 | isEnd: lastIndex === clippedLastIndex,
|
6228 | };
|
6229 | }
|
6230 | return null;
|
6231 | }
|
6232 |
|
6233 |
|
6234 |
|
6235 |
|
6236 |
|
6237 | getDateDayIndex(date) {
|
6238 | let { indices } = this;
|
6239 | let dayOffset = Math.floor(diffDays(this.dates[0], date));
|
6240 | if (dayOffset < 0) {
|
6241 | return indices[0] - 1;
|
6242 | }
|
6243 | if (dayOffset >= indices.length) {
|
6244 | return indices[indices.length - 1] + 1;
|
6245 | }
|
6246 | return indices[dayOffset];
|
6247 | }
|
6248 | }
|
6249 |
|
6250 | class DayTableModel {
|
6251 | constructor(daySeries, breakOnWeeks) {
|
6252 | let { dates } = daySeries;
|
6253 | let daysPerRow;
|
6254 | let firstDay;
|
6255 | let rowCnt;
|
6256 | if (breakOnWeeks) {
|
6257 |
|
6258 | firstDay = dates[0].getUTCDay();
|
6259 | for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {
|
6260 | if (dates[daysPerRow].getUTCDay() === firstDay) {
|
6261 | break;
|
6262 | }
|
6263 | }
|
6264 | rowCnt = Math.ceil(dates.length / daysPerRow);
|
6265 | }
|
6266 | else {
|
6267 | rowCnt = 1;
|
6268 | daysPerRow = dates.length;
|
6269 | }
|
6270 | this.rowCnt = rowCnt;
|
6271 | this.colCnt = daysPerRow;
|
6272 | this.daySeries = daySeries;
|
6273 | this.cells = this.buildCells();
|
6274 | this.headerDates = this.buildHeaderDates();
|
6275 | }
|
6276 | buildCells() {
|
6277 | let rows = [];
|
6278 | for (let row = 0; row < this.rowCnt; row += 1) {
|
6279 | let cells = [];
|
6280 | for (let col = 0; col < this.colCnt; col += 1) {
|
6281 | cells.push(this.buildCell(row, col));
|
6282 | }
|
6283 | rows.push(cells);
|
6284 | }
|
6285 | return rows;
|
6286 | }
|
6287 | buildCell(row, col) {
|
6288 | let date = this.daySeries.dates[row * this.colCnt + col];
|
6289 | return {
|
6290 | key: date.toISOString(),
|
6291 | date,
|
6292 | };
|
6293 | }
|
6294 | buildHeaderDates() {
|
6295 | let dates = [];
|
6296 | for (let col = 0; col < this.colCnt; col += 1) {
|
6297 | dates.push(this.cells[0][col].date);
|
6298 | }
|
6299 | return dates;
|
6300 | }
|
6301 | sliceRange(range) {
|
6302 | let { colCnt } = this;
|
6303 | let seriesSeg = this.daySeries.sliceRange(range);
|
6304 | let segs = [];
|
6305 | if (seriesSeg) {
|
6306 | let { firstIndex, lastIndex } = seriesSeg;
|
6307 | let index = firstIndex;
|
6308 | while (index <= lastIndex) {
|
6309 | let row = Math.floor(index / colCnt);
|
6310 | let nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
|
6311 | segs.push({
|
6312 | row,
|
6313 | firstCol: index % colCnt,
|
6314 | lastCol: (nextIndex - 1) % colCnt,
|
6315 | isStart: seriesSeg.isStart && index === firstIndex,
|
6316 | isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex,
|
6317 | });
|
6318 | index = nextIndex;
|
6319 | }
|
6320 | }
|
6321 | return segs;
|
6322 | }
|
6323 | }
|
6324 |
|
6325 | class Slicer {
|
6326 | constructor() {
|
6327 | this.sliceBusinessHours = memoize(this._sliceBusinessHours);
|
6328 | this.sliceDateSelection = memoize(this._sliceDateSpan);
|
6329 | this.sliceEventStore = memoize(this._sliceEventStore);
|
6330 | this.sliceEventDrag = memoize(this._sliceInteraction);
|
6331 | this.sliceEventResize = memoize(this._sliceInteraction);
|
6332 | this.forceDayIfListItem = false;
|
6333 | }
|
6334 | sliceProps(props, dateProfile, nextDayThreshold, context, ...extraArgs) {
|
6335 | let { eventUiBases } = props;
|
6336 | let eventSegs = this.sliceEventStore(props.eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs);
|
6337 | return {
|
6338 | dateSelectionSegs: this.sliceDateSelection(props.dateSelection, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs),
|
6339 | businessHourSegs: this.sliceBusinessHours(props.businessHours, dateProfile, nextDayThreshold, context, ...extraArgs),
|
6340 | fgEventSegs: eventSegs.fg,
|
6341 | bgEventSegs: eventSegs.bg,
|
6342 | eventDrag: this.sliceEventDrag(props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),
|
6343 | eventResize: this.sliceEventResize(props.eventResize, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),
|
6344 | eventSelection: props.eventSelection,
|
6345 | };
|
6346 | }
|
6347 | sliceNowDate(
|
6348 | date, dateProfile, nextDayThreshold, context, ...extraArgs) {
|
6349 | return this._sliceDateSpan({ range: { start: date, end: addMs(date, 1) }, allDay: false },
|
6350 | dateProfile, nextDayThreshold, {}, context, ...extraArgs);
|
6351 | }
|
6352 | _sliceBusinessHours(businessHours, dateProfile, nextDayThreshold, context, ...extraArgs) {
|
6353 | if (!businessHours) {
|
6354 | return [];
|
6355 | }
|
6356 | return this._sliceEventStore(expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), {}, dateProfile, nextDayThreshold, ...extraArgs).bg;
|
6357 | }
|
6358 | _sliceEventStore(eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {
|
6359 | if (eventStore) {
|
6360 | let rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
|
6361 | return {
|
6362 | bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
|
6363 | fg: this.sliceEventRanges(rangeRes.fg, extraArgs),
|
6364 | };
|
6365 | }
|
6366 | return { bg: [], fg: [] };
|
6367 | }
|
6368 | _sliceInteraction(interaction, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {
|
6369 | if (!interaction) {
|
6370 | return null;
|
6371 | }
|
6372 | let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
|
6373 | return {
|
6374 | segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
|
6375 | affectedInstances: interaction.affectedEvents.instances,
|
6376 | isEvent: interaction.isEvent,
|
6377 | };
|
6378 | }
|
6379 | _sliceDateSpan(dateSpan, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs) {
|
6380 | if (!dateSpan) {
|
6381 | return [];
|
6382 | }
|
6383 | let activeRange = computeActiveRange(dateProfile, Boolean(nextDayThreshold));
|
6384 | let activeDateSpanRange = intersectRanges(dateSpan.range, activeRange);
|
6385 | if (activeDateSpanRange) {
|
6386 | dateSpan = Object.assign(Object.assign({}, dateSpan), { range: activeDateSpanRange });
|
6387 | let eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
|
6388 | let segs = this.sliceRange(dateSpan.range, ...extraArgs);
|
6389 | for (let seg of segs) {
|
6390 | seg.eventRange = eventRange;
|
6391 | }
|
6392 | return segs;
|
6393 | }
|
6394 | return [];
|
6395 | }
|
6396 | |
6397 |
|
6398 |
|
6399 | sliceEventRanges(eventRanges, extraArgs) {
|
6400 | let segs = [];
|
6401 | for (let eventRange of eventRanges) {
|
6402 | segs.push(...this.sliceEventRange(eventRange, extraArgs));
|
6403 | }
|
6404 | return segs;
|
6405 | }
|
6406 | |
6407 |
|
6408 |
|
6409 | sliceEventRange(eventRange, extraArgs) {
|
6410 | let dateRange = eventRange.range;
|
6411 |
|
6412 | if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
|
6413 | dateRange = {
|
6414 | start: dateRange.start,
|
6415 | end: addDays(dateRange.start, 1),
|
6416 | };
|
6417 | }
|
6418 | let segs = this.sliceRange(dateRange, ...extraArgs);
|
6419 | for (let seg of segs) {
|
6420 | seg.eventRange = eventRange;
|
6421 | seg.isStart = eventRange.isStart && seg.isStart;
|
6422 | seg.isEnd = eventRange.isEnd && seg.isEnd;
|
6423 | }
|
6424 | return segs;
|
6425 | }
|
6426 | }
|
6427 |
|
6428 |
|
6429 |
|
6430 |
|
6431 |
|
6432 | function computeActiveRange(dateProfile, isComponentAllDay) {
|
6433 | let range = dateProfile.activeRange;
|
6434 | if (isComponentAllDay) {
|
6435 | return range;
|
6436 | }
|
6437 | return {
|
6438 | start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
|
6439 | end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5),
|
6440 | };
|
6441 | }
|
6442 |
|
6443 |
|
6444 |
|
6445 | function isInteractionValid(interaction, dateProfile, context) {
|
6446 | let { instances } = interaction.mutatedEvents;
|
6447 | for (let instanceId in instances) {
|
6448 | if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
|
6449 | return false;
|
6450 | }
|
6451 | }
|
6452 | return isNewPropsValid({ eventDrag: interaction }, context);
|
6453 | }
|
6454 | function isDateSelectionValid(dateSelection, dateProfile, context) {
|
6455 | if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) {
|
6456 | return false;
|
6457 | }
|
6458 | return isNewPropsValid({ dateSelection }, context);
|
6459 | }
|
6460 | function isNewPropsValid(newProps, context) {
|
6461 | let calendarState = context.getCurrentData();
|
6462 | let props = Object.assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);
|
6463 | return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
|
6464 | }
|
6465 | function isPropsValid(state, context, dateSpanMeta = {}, filterConfig) {
|
6466 | if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
|
6467 | return false;
|
6468 | }
|
6469 | if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
|
6470 | return false;
|
6471 | }
|
6472 | return true;
|
6473 | }
|
6474 |
|
6475 |
|
6476 | function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
|
6477 | let currentState = context.getCurrentData();
|
6478 | let interaction = state.eventDrag;
|
6479 | let subjectEventStore = interaction.mutatedEvents;
|
6480 | let subjectDefs = subjectEventStore.defs;
|
6481 | let subjectInstances = subjectEventStore.instances;
|
6482 | let subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?
|
6483 | state.eventUiBases :
|
6484 | { '': currentState.selectionConfig });
|
6485 | if (filterConfig) {
|
6486 | subjectConfigs = mapHash(subjectConfigs, filterConfig);
|
6487 | }
|
6488 |
|
6489 | let otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);
|
6490 | let otherDefs = otherEventStore.defs;
|
6491 | let otherInstances = otherEventStore.instances;
|
6492 | let otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
|
6493 | for (let subjectInstanceId in subjectInstances) {
|
6494 | let subjectInstance = subjectInstances[subjectInstanceId];
|
6495 | let subjectRange = subjectInstance.range;
|
6496 | let subjectConfig = subjectConfigs[subjectInstance.defId];
|
6497 | let subjectDef = subjectDefs[subjectInstance.defId];
|
6498 |
|
6499 | if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
|
6500 | return false;
|
6501 | }
|
6502 |
|
6503 | let { eventOverlap } = context.options;
|
6504 | let eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
|
6505 | for (let otherInstanceId in otherInstances) {
|
6506 | let otherInstance = otherInstances[otherInstanceId];
|
6507 |
|
6508 | if (rangesIntersect(subjectRange, otherInstance.range)) {
|
6509 | let otherOverlap = otherConfigs[otherInstance.defId].overlap;
|
6510 |
|
6511 | if (otherOverlap === false && interaction.isEvent) {
|
6512 | return false;
|
6513 | }
|
6514 | if (subjectConfig.overlap === false) {
|
6515 | return false;
|
6516 | }
|
6517 | if (eventOverlapFunc && !eventOverlapFunc(new EventImpl(context, otherDefs[otherInstance.defId], otherInstance),
|
6518 | new EventImpl(context, subjectDef, subjectInstance))) {
|
6519 | return false;
|
6520 | }
|
6521 | }
|
6522 | }
|
6523 |
|
6524 | let calendarEventStore = currentState.eventStore;
|
6525 | for (let subjectAllow of subjectConfig.allows) {
|
6526 | let subjectDateSpan = Object.assign(Object.assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });
|
6527 | let origDef = calendarEventStore.defs[subjectDef.defId];
|
6528 | let origInstance = calendarEventStore.instances[subjectInstanceId];
|
6529 | let eventApi;
|
6530 | if (origDef) {
|
6531 | eventApi = new EventImpl(context, origDef, origInstance);
|
6532 | }
|
6533 | else {
|
6534 | eventApi = new EventImpl(context, subjectDef);
|
6535 | }
|
6536 | if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
|
6537 | return false;
|
6538 | }
|
6539 | }
|
6540 | }
|
6541 | return true;
|
6542 | }
|
6543 |
|
6544 |
|
6545 | function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
|
6546 | let relevantEventStore = state.eventStore;
|
6547 | let relevantDefs = relevantEventStore.defs;
|
6548 | let relevantInstances = relevantEventStore.instances;
|
6549 | let selection = state.dateSelection;
|
6550 | let selectionRange = selection.range;
|
6551 | let { selectionConfig } = context.getCurrentData();
|
6552 | if (filterConfig) {
|
6553 | selectionConfig = filterConfig(selectionConfig);
|
6554 | }
|
6555 |
|
6556 | if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
|
6557 | return false;
|
6558 | }
|
6559 |
|
6560 | let { selectOverlap } = context.options;
|
6561 | let selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
|
6562 | for (let relevantInstanceId in relevantInstances) {
|
6563 | let relevantInstance = relevantInstances[relevantInstanceId];
|
6564 |
|
6565 | if (rangesIntersect(selectionRange, relevantInstance.range)) {
|
6566 | if (selectionConfig.overlap === false) {
|
6567 | return false;
|
6568 | }
|
6569 | if (selectOverlapFunc && !selectOverlapFunc(new EventImpl(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
|
6570 | return false;
|
6571 | }
|
6572 | }
|
6573 | }
|
6574 |
|
6575 | for (let selectionAllow of selectionConfig.allows) {
|
6576 | let fullDateSpan = Object.assign(Object.assign({}, dateSpanMeta), selection);
|
6577 | if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
|
6578 | return false;
|
6579 | }
|
6580 | }
|
6581 | return true;
|
6582 | }
|
6583 |
|
6584 |
|
6585 | function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
|
6586 | for (let constraint of constraints) {
|
6587 | if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
|
6588 | return false;
|
6589 | }
|
6590 | }
|
6591 | return true;
|
6592 | }
|
6593 | function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours
|
6594 | otherEventStore, // for if constraint is an even group ID
|
6595 | businessHoursUnexpanded, // for if constraint is 'businessHours'
|
6596 | context) {
|
6597 | if (constraint === 'businessHours') {
|
6598 | return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
|
6599 | }
|
6600 | if (typeof constraint === 'string') {
|
6601 | return eventStoreToRanges(filterEventStoreDefs(otherEventStore, (eventDef) => eventDef.groupId === constraint));
|
6602 | }
|
6603 | if (typeof constraint === 'object' && constraint) {
|
6604 | return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
|
6605 | }
|
6606 | return [];
|
6607 | }
|
6608 |
|
6609 | function eventStoreToRanges(eventStore) {
|
6610 | let { instances } = eventStore;
|
6611 | let ranges = [];
|
6612 | for (let instanceId in instances) {
|
6613 | ranges.push(instances[instanceId].range);
|
6614 | }
|
6615 | return ranges;
|
6616 | }
|
6617 |
|
6618 | function anyRangesContainRange(outerRanges, innerRange) {
|
6619 | for (let outerRange of outerRanges) {
|
6620 | if (rangeContainsRange(outerRange, innerRange)) {
|
6621 | return true;
|
6622 | }
|
6623 | }
|
6624 | return false;
|
6625 | }
|
6626 |
|
6627 | const VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
|
6628 | class Scroller extends BaseComponent {
|
6629 | constructor() {
|
6630 | super(...arguments);
|
6631 | this.handleEl = (el) => {
|
6632 | this.el = el;
|
6633 | setRef(this.props.elRef, el);
|
6634 | };
|
6635 | }
|
6636 | render() {
|
6637 | let { props } = this;
|
6638 | let { liquid, liquidIsAbsolute } = props;
|
6639 | let isAbsolute = liquid && liquidIsAbsolute;
|
6640 | let className = ['fc-scroller'];
|
6641 | if (liquid) {
|
6642 | if (liquidIsAbsolute) {
|
6643 | className.push('fc-scroller-liquid-absolute');
|
6644 | }
|
6645 | else {
|
6646 | className.push('fc-scroller-liquid');
|
6647 | }
|
6648 | }
|
6649 | return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: {
|
6650 | overflowX: props.overflowX,
|
6651 | overflowY: props.overflowY,
|
6652 | left: (isAbsolute && -(props.overcomeLeft || 0)) || '',
|
6653 | right: (isAbsolute && -(props.overcomeRight || 0)) || '',
|
6654 | bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',
|
6655 | marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',
|
6656 | marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',
|
6657 | marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',
|
6658 | maxHeight: props.maxHeight || '',
|
6659 | } }, props.children));
|
6660 | }
|
6661 | needsXScrolling() {
|
6662 | if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
|
6663 | return false;
|
6664 | }
|
6665 |
|
6666 |
|
6667 |
|
6668 | let { el } = this;
|
6669 | let realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
|
6670 | let { children } = el;
|
6671 | for (let i = 0; i < children.length; i += 1) {
|
6672 | let childEl = children[i];
|
6673 | if (childEl.getBoundingClientRect().width > realClientWidth) {
|
6674 | return true;
|
6675 | }
|
6676 | }
|
6677 | return false;
|
6678 | }
|
6679 | needsYScrolling() {
|
6680 | if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
|
6681 | return false;
|
6682 | }
|
6683 |
|
6684 |
|
6685 |
|
6686 | let { el } = this;
|
6687 | let realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
|
6688 | let { children } = el;
|
6689 | for (let i = 0; i < children.length; i += 1) {
|
6690 | let childEl = children[i];
|
6691 | if (childEl.getBoundingClientRect().height > realClientHeight) {
|
6692 | return true;
|
6693 | }
|
6694 | }
|
6695 | return false;
|
6696 | }
|
6697 | getXScrollbarWidth() {
|
6698 | if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
|
6699 | return 0;
|
6700 | }
|
6701 | return this.el.offsetHeight - this.el.clientHeight;
|
6702 | }
|
6703 | getYScrollbarWidth() {
|
6704 | if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
|
6705 | return 0;
|
6706 | }
|
6707 | return this.el.offsetWidth - this.el.clientWidth;
|
6708 | }
|
6709 | }
|
6710 |
|
6711 |
|
6712 |
|
6713 |
|
6714 |
|
6715 | class RefMap {
|
6716 | constructor(masterCallback) {
|
6717 | this.masterCallback = masterCallback;
|
6718 | this.currentMap = {};
|
6719 | this.depths = {};
|
6720 | this.callbackMap = {};
|
6721 | this.handleValue = (val, key) => {
|
6722 | let { depths, currentMap } = this;
|
6723 | let removed = false;
|
6724 | let added = false;
|
6725 | if (val !== null) {
|
6726 |
|
6727 | removed = (key in currentMap);
|
6728 | currentMap[key] = val;
|
6729 | depths[key] = (depths[key] || 0) + 1;
|
6730 | added = true;
|
6731 | }
|
6732 | else {
|
6733 | depths[key] -= 1;
|
6734 | if (!depths[key]) {
|
6735 | delete currentMap[key];
|
6736 | delete this.callbackMap[key];
|
6737 | removed = true;
|
6738 | }
|
6739 | }
|
6740 | if (this.masterCallback) {
|
6741 | if (removed) {
|
6742 | this.masterCallback(null, String(key));
|
6743 | }
|
6744 | if (added) {
|
6745 | this.masterCallback(val, String(key));
|
6746 | }
|
6747 | }
|
6748 | };
|
6749 | }
|
6750 | createRef(key) {
|
6751 | let refCallback = this.callbackMap[key];
|
6752 | if (!refCallback) {
|
6753 | refCallback = this.callbackMap[key] = (val) => {
|
6754 | this.handleValue(val, String(key));
|
6755 | };
|
6756 | }
|
6757 | return refCallback;
|
6758 | }
|
6759 |
|
6760 |
|
6761 |
|
6762 | collect(startIndex, endIndex, step) {
|
6763 | return collectFromHash(this.currentMap, startIndex, endIndex, step);
|
6764 | }
|
6765 | getAll() {
|
6766 | return hashValuesToArray(this.currentMap);
|
6767 | }
|
6768 | }
|
6769 |
|
6770 | function computeShrinkWidth(chunkEls) {
|
6771 | let shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
|
6772 | let largestWidth = 0;
|
6773 | for (let shrinkCell of shrinkCells) {
|
6774 | largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
|
6775 | }
|
6776 | return Math.ceil(largestWidth);
|
6777 | }
|
6778 | function getSectionHasLiquidHeight(props, sectionConfig) {
|
6779 | return props.liquid && sectionConfig.liquid;
|
6780 | }
|
6781 | function getAllowYScrolling(props, sectionConfig) {
|
6782 | return sectionConfig.maxHeight != null ||
|
6783 | getSectionHasLiquidHeight(props, sectionConfig);
|
6784 | }
|
6785 |
|
6786 | function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) {
|
6787 | let { expandRows } = arg;
|
6788 | let content = typeof chunkConfig.content === 'function' ?
|
6789 | chunkConfig.content(arg) :
|
6790 | createElement('table', {
|
6791 | role: 'presentation',
|
6792 | className: [
|
6793 | chunkConfig.tableClassName,
|
6794 | sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '',
|
6795 | ].join(' '),
|
6796 | style: {
|
6797 | minWidth: arg.tableMinWidth,
|
6798 | width: arg.clientWidth,
|
6799 | height: expandRows ? arg.clientHeight : '',
|
6800 | },
|
6801 | }, arg.tableColGroupNode, createElement(isHeader ? 'thead' : 'tbody', {
|
6802 | role: 'presentation',
|
6803 | }, typeof chunkConfig.rowContent === 'function'
|
6804 | ? chunkConfig.rowContent(arg)
|
6805 | : chunkConfig.rowContent));
|
6806 | return content;
|
6807 | }
|
6808 | function isColPropsEqual(cols0, cols1) {
|
6809 | return isArraysEqual(cols0, cols1, isPropsEqual);
|
6810 | }
|
6811 | function renderMicroColGroup(cols, shrinkWidth) {
|
6812 | let colNodes = [];
|
6813 | |
6814 |
|
6815 |
|
6816 |
|
6817 |
|
6818 | for (let colProps of cols) {
|
6819 | let span = colProps.span || 1;
|
6820 | for (let i = 0; i < span; i += 1) {
|
6821 | colNodes.push(createElement("col", { style: {
|
6822 | width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),
|
6823 | minWidth: colProps.minWidth || '',
|
6824 | } }));
|
6825 | }
|
6826 | }
|
6827 | return createElement('colgroup', {}, ...colNodes);
|
6828 | }
|
6829 | function sanitizeShrinkWidth(shrinkWidth) {
|
6830 | |
6831 |
|
6832 | return shrinkWidth == null ? 4 : shrinkWidth;
|
6833 | }
|
6834 | function hasShrinkWidth(cols) {
|
6835 | for (let col of cols) {
|
6836 | if (col.width === 'shrink') {
|
6837 | return true;
|
6838 | }
|
6839 | }
|
6840 | return false;
|
6841 | }
|
6842 | function getScrollGridClassNames(liquid, context) {
|
6843 | let classNames = [
|
6844 | 'fc-scrollgrid',
|
6845 | context.theme.getClass('table'),
|
6846 | ];
|
6847 | if (liquid) {
|
6848 | classNames.push('fc-scrollgrid-liquid');
|
6849 | }
|
6850 | return classNames;
|
6851 | }
|
6852 | function getSectionClassNames(sectionConfig, wholeTableVGrow) {
|
6853 | let classNames = [
|
6854 | 'fc-scrollgrid-section',
|
6855 | `fc-scrollgrid-section-${sectionConfig.type}`,
|
6856 | sectionConfig.className,
|
6857 | ];
|
6858 | if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
|
6859 | classNames.push('fc-scrollgrid-section-liquid');
|
6860 | }
|
6861 | if (sectionConfig.isSticky) {
|
6862 | classNames.push('fc-scrollgrid-section-sticky');
|
6863 | }
|
6864 | return classNames;
|
6865 | }
|
6866 | function renderScrollShim(arg) {
|
6867 | return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: {
|
6868 | width: arg.clientWidth,
|
6869 | minWidth: arg.tableMinWidth,
|
6870 | } }));
|
6871 | }
|
6872 | function getStickyHeaderDates(options) {
|
6873 | let { stickyHeaderDates } = options;
|
6874 | if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
|
6875 | stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
|
6876 | }
|
6877 | return stickyHeaderDates;
|
6878 | }
|
6879 | function getStickyFooterScrollbar(options) {
|
6880 | let { stickyFooterScrollbar } = options;
|
6881 | if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
|
6882 | stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
|
6883 | }
|
6884 | return stickyFooterScrollbar;
|
6885 | }
|
6886 |
|
6887 | class SimpleScrollGrid extends BaseComponent {
|
6888 | constructor() {
|
6889 | super(...arguments);
|
6890 | this.processCols = memoize((a) => a, isColPropsEqual);
|
6891 |
|
6892 | this.renderMicroColGroup = memoize(renderMicroColGroup);
|
6893 | this.scrollerRefs = new RefMap();
|
6894 | this.scrollerElRefs = new RefMap(this._handleScrollerEl.bind(this));
|
6895 | this.state = {
|
6896 | shrinkWidth: null,
|
6897 | forceYScrollbars: false,
|
6898 | scrollerClientWidths: {},
|
6899 | scrollerClientHeights: {},
|
6900 | };
|
6901 |
|
6902 | this.handleSizing = () => {
|
6903 | this.safeSetState(Object.assign({ shrinkWidth: this.computeShrinkWidth() }, this.computeScrollerDims()));
|
6904 | };
|
6905 | }
|
6906 | render() {
|
6907 | let { props, state, context } = this;
|
6908 | let sectionConfigs = props.sections || [];
|
6909 | let cols = this.processCols(props.cols);
|
6910 | let microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
|
6911 | let classNames = getScrollGridClassNames(props.liquid, context);
|
6912 | if (props.collapsibleWidth) {
|
6913 | classNames.push('fc-scrollgrid-collapsible');
|
6914 | }
|
6915 |
|
6916 | let configCnt = sectionConfigs.length;
|
6917 | let configI = 0;
|
6918 | let currentConfig;
|
6919 | let headSectionNodes = [];
|
6920 | let bodySectionNodes = [];
|
6921 | let footSectionNodes = [];
|
6922 | while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
|
6923 | headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
|
6924 | configI += 1;
|
6925 | }
|
6926 | while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
|
6927 | bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false));
|
6928 | configI += 1;
|
6929 | }
|
6930 | while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
|
6931 | footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
|
6932 | configI += 1;
|
6933 | }
|
6934 |
|
6935 |
|
6936 |
|
6937 |
|
6938 | let isBuggy = !getCanVGrowWithinCell();
|
6939 | const roleAttrs = { role: 'rowgroup' };
|
6940 | return createElement('table', {
|
6941 | role: 'grid',
|
6942 | className: classNames.join(' '),
|
6943 | style: { height: props.height },
|
6944 | }, Boolean(!isBuggy && headSectionNodes.length) && createElement('thead', roleAttrs, ...headSectionNodes), Boolean(!isBuggy && bodySectionNodes.length) && createElement('tbody', roleAttrs, ...bodySectionNodes), Boolean(!isBuggy && footSectionNodes.length) && createElement('tfoot', roleAttrs, ...footSectionNodes), isBuggy && createElement('tbody', roleAttrs, ...headSectionNodes, ...bodySectionNodes, ...footSectionNodes));
|
6945 | }
|
6946 | renderSection(sectionConfig, microColGroupNode, isHeader) {
|
6947 | if ('outerContent' in sectionConfig) {
|
6948 | return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
|
6949 | }
|
6950 | return (createElement("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader)));
|
6951 | }
|
6952 | renderChunkTd(sectionConfig, microColGroupNode, chunkConfig, isHeader) {
|
6953 | if ('outerContent' in chunkConfig) {
|
6954 | return chunkConfig.outerContent;
|
6955 | }
|
6956 | let { props } = this;
|
6957 | let { forceYScrollbars, scrollerClientWidths, scrollerClientHeights } = this.state;
|
6958 | let needsYScrolling = getAllowYScrolling(props, sectionConfig);
|
6959 | let isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
|
6960 |
|
6961 |
|
6962 | let overflowY = !props.liquid ? 'visible' :
|
6963 | forceYScrollbars ? 'scroll' :
|
6964 | !needsYScrolling ? 'hidden' :
|
6965 | 'auto';
|
6966 | let sectionKey = sectionConfig.key;
|
6967 | let content = renderChunkContent(sectionConfig, chunkConfig, {
|
6968 | tableColGroupNode: microColGroupNode,
|
6969 | tableMinWidth: '',
|
6970 | clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null,
|
6971 | clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,
|
6972 | expandRows: sectionConfig.expandRows,
|
6973 | syncRowHeights: false,
|
6974 | rowSyncHeights: [],
|
6975 | reportRowHeightChange: () => { },
|
6976 | }, isHeader);
|
6977 | return createElement(isHeader ? 'th' : 'td', {
|
6978 | ref: chunkConfig.elRef,
|
6979 | role: 'presentation',
|
6980 | }, createElement("div", { className: `fc-scroller-harness${isLiquid ? ' fc-scroller-harness-liquid' : ''}` },
|
6981 | createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' , maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute
|
6982 | : true }, content)));
|
6983 | }
|
6984 | _handleScrollerEl(scrollerEl, key) {
|
6985 | let section = getSectionByKey(this.props.sections, key);
|
6986 | if (section) {
|
6987 | setRef(section.chunk.scrollerElRef, scrollerEl);
|
6988 | }
|
6989 | }
|
6990 | componentDidMount() {
|
6991 | this.handleSizing();
|
6992 | this.context.addResizeHandler(this.handleSizing);
|
6993 | }
|
6994 | componentDidUpdate() {
|
6995 |
|
6996 | this.handleSizing();
|
6997 | }
|
6998 | componentWillUnmount() {
|
6999 | this.context.removeResizeHandler(this.handleSizing);
|
7000 | }
|
7001 | computeShrinkWidth() {
|
7002 | return hasShrinkWidth(this.props.cols)
|
7003 | ? computeShrinkWidth(this.scrollerElRefs.getAll())
|
7004 | : 0;
|
7005 | }
|
7006 | computeScrollerDims() {
|
7007 | let scrollbarWidth = getScrollbarWidths();
|
7008 | let { scrollerRefs, scrollerElRefs } = this;
|
7009 | let forceYScrollbars = false;
|
7010 | let scrollerClientWidths = {};
|
7011 | let scrollerClientHeights = {};
|
7012 | for (let sectionKey in scrollerRefs.currentMap) {
|
7013 | let scroller = scrollerRefs.currentMap[sectionKey];
|
7014 | if (scroller && scroller.needsYScrolling()) {
|
7015 | forceYScrollbars = true;
|
7016 | break;
|
7017 | }
|
7018 | }
|
7019 | for (let section of this.props.sections) {
|
7020 | let sectionKey = section.key;
|
7021 | let scrollerEl = scrollerElRefs.currentMap[sectionKey];
|
7022 | if (scrollerEl) {
|
7023 | let harnessEl = scrollerEl.parentNode;
|
7024 | scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars
|
7025 | ? scrollbarWidth.y
|
7026 | : 0));
|
7027 | scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);
|
7028 | }
|
7029 | }
|
7030 | return { forceYScrollbars, scrollerClientWidths, scrollerClientHeights };
|
7031 | }
|
7032 | }
|
7033 | SimpleScrollGrid.addStateEquality({
|
7034 | scrollerClientWidths: isPropsEqual,
|
7035 | scrollerClientHeights: isPropsEqual,
|
7036 | });
|
7037 | function getSectionByKey(sections, key) {
|
7038 | for (let section of sections) {
|
7039 | if (section.key === key) {
|
7040 | return section;
|
7041 | }
|
7042 | }
|
7043 | return null;
|
7044 | }
|
7045 |
|
7046 | class EventContainer extends BaseComponent {
|
7047 | constructor() {
|
7048 | super(...arguments);
|
7049 | this.handleEl = (el) => {
|
7050 | this.el = el;
|
7051 | if (el) {
|
7052 | setElSeg(el, this.props.seg);
|
7053 | }
|
7054 | };
|
7055 | }
|
7056 | render() {
|
7057 | const { props, context } = this;
|
7058 | const { options } = context;
|
7059 | const { seg } = props;
|
7060 | const { eventRange } = seg;
|
7061 | const { ui } = eventRange;
|
7062 | const renderProps = {
|
7063 | event: new EventImpl(context, eventRange.def, eventRange.instance),
|
7064 | view: context.viewApi,
|
7065 | timeText: props.timeText,
|
7066 | textColor: ui.textColor,
|
7067 | backgroundColor: ui.backgroundColor,
|
7068 | borderColor: ui.borderColor,
|
7069 | isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
|
7070 | isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
|
7071 | isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
|
7072 | isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
|
7073 | isStart: Boolean(seg.isStart),
|
7074 | isEnd: Boolean(seg.isEnd),
|
7075 | isPast: Boolean(props.isPast),
|
7076 | isFuture: Boolean(props.isFuture),
|
7077 | isToday: Boolean(props.isToday),
|
7078 | isSelected: Boolean(props.isSelected),
|
7079 | isDragging: Boolean(props.isDragging),
|
7080 | isResizing: Boolean(props.isResizing),
|
7081 | };
|
7082 | return (createElement(ContentContainer, Object.assign({}, props , { elRef: this.handleEl, elClasses: [
|
7083 | ...getEventClassNames(renderProps),
|
7084 | ...seg.eventRange.ui.classNames,
|
7085 | ...(props.elClasses || []),
|
7086 | ], renderProps: renderProps, generatorName: "eventContent", customGenerator: options.eventContent, defaultGenerator: props.defaultGenerator, classNameGenerator: options.eventClassNames, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount })));
|
7087 | }
|
7088 | componentDidUpdate(prevProps) {
|
7089 | if (this.el && this.props.seg !== prevProps.seg) {
|
7090 | setElSeg(this.el, this.props.seg);
|
7091 | }
|
7092 | }
|
7093 | }
|
7094 |
|
7095 |
|
7096 | class StandardEvent extends BaseComponent {
|
7097 | render() {
|
7098 | let { props, context } = this;
|
7099 | let { options } = context;
|
7100 | let { seg } = props;
|
7101 | let { ui } = seg.eventRange;
|
7102 | let timeFormat = options.eventTimeFormat || props.defaultTimeFormat;
|
7103 | let timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
|
7104 | return (createElement(EventContainer, Object.assign({}, props , { elTag: "a", elStyle: {
|
7105 | borderColor: ui.borderColor,
|
7106 | backgroundColor: ui.backgroundColor,
|
7107 | }, elAttrs: getSegAnchorAttrs(seg, context), defaultGenerator: renderInnerContent$1, timeText: timeText }), (InnerContent, eventContentArg) => (createElement(Fragment, null,
|
7108 | createElement(InnerContent, { elTag: "div", elClasses: ['fc-event-main'], elStyle: { color: eventContentArg.textColor } }),
|
7109 | Boolean(eventContentArg.isStartResizable) && (createElement("div", { className: "fc-event-resizer fc-event-resizer-start" })),
|
7110 | Boolean(eventContentArg.isEndResizable) && (createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))))));
|
7111 | }
|
7112 | }
|
7113 | function renderInnerContent$1(innerProps) {
|
7114 | return (createElement("div", { className: "fc-event-main-frame" },
|
7115 | innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)),
|
7116 | createElement("div", { className: "fc-event-title-container" },
|
7117 | createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))));
|
7118 | }
|
7119 |
|
7120 | const NowIndicatorContainer = (props) => (createElement(ViewContextType.Consumer, null, (context) => {
|
7121 | let { options } = context;
|
7122 | let renderProps = {
|
7123 | isAxis: props.isAxis,
|
7124 | date: context.dateEnv.toDate(props.date),
|
7125 | view: context.viewApi,
|
7126 | };
|
7127 | return (createElement(ContentContainer, Object.assign({}, props , { elTag: props.elTag || 'div', renderProps: renderProps, generatorName: "nowIndicatorContent", customGenerator: options.nowIndicatorContent, classNameGenerator: options.nowIndicatorClassNames, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount })));
|
7128 | }));
|
7129 |
|
7130 | const DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });
|
7131 | class DayCellContainer extends BaseComponent {
|
7132 | constructor() {
|
7133 | super(...arguments);
|
7134 | this.refineRenderProps = memoizeObjArg(refineRenderProps);
|
7135 | }
|
7136 | render() {
|
7137 | let { props, context } = this;
|
7138 | let { options } = context;
|
7139 | let renderProps = this.refineRenderProps({
|
7140 | date: props.date,
|
7141 | dateProfile: props.dateProfile,
|
7142 | todayRange: props.todayRange,
|
7143 | isMonthStart: props.isMonthStart || false,
|
7144 | showDayNumber: props.showDayNumber,
|
7145 | extraRenderProps: props.extraRenderProps,
|
7146 | viewApi: context.viewApi,
|
7147 | dateEnv: context.dateEnv,
|
7148 | monthStartFormat: options.monthStartFormat,
|
7149 | });
|
7150 | return (createElement(ContentContainer, Object.assign({}, props , { elClasses: [
|
7151 | ...getDayClassNames(renderProps, context.theme),
|
7152 | ...(props.elClasses || []),
|
7153 | ], elAttrs: Object.assign(Object.assign({}, props.elAttrs), (renderProps.isDisabled ? {} : { 'data-date': formatDayString(props.date) })), renderProps: renderProps, generatorName: "dayCellContent", customGenerator: options.dayCellContent, defaultGenerator: props.defaultGenerator, classNameGenerator:
|
7154 |
|
7155 | renderProps.isDisabled ? undefined : options.dayCellClassNames, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount })));
|
7156 | }
|
7157 | }
|
7158 | function hasCustomDayCellContent(options) {
|
7159 | return Boolean(options.dayCellContent || hasCustomRenderingHandler('dayCellContent', options));
|
7160 | }
|
7161 | function refineRenderProps(raw) {
|
7162 | let { date, dateEnv, dateProfile, isMonthStart } = raw;
|
7163 | let dayMeta = getDateMeta(date, raw.todayRange, null, dateProfile);
|
7164 | let dayNumberText = raw.showDayNumber ? (dateEnv.format(date, isMonthStart ? raw.monthStartFormat : DAY_NUM_FORMAT)) : '';
|
7165 | return Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { isMonthStart,
|
7166 | dayNumberText }), raw.extraRenderProps);
|
7167 | }
|
7168 |
|
7169 | class BgEvent extends BaseComponent {
|
7170 | render() {
|
7171 | let { props } = this;
|
7172 | let { seg } = props;
|
7173 | return (createElement(EventContainer, { elTag: "div", elClasses: ['fc-bg-event'], elStyle: { backgroundColor: seg.eventRange.ui.backgroundColor }, defaultGenerator: renderInnerContent, seg: seg, timeText: "", isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, disableDragging: true, disableResizing: true }));
|
7174 | }
|
7175 | }
|
7176 | function renderInnerContent(props) {
|
7177 | let { title } = props.event;
|
7178 | return title && (createElement("div", { className: "fc-event-title" }, props.event.title));
|
7179 | }
|
7180 | function renderFill(fillType) {
|
7181 | return (createElement("div", { className: `fc-${fillType}` }));
|
7182 | }
|
7183 |
|
7184 | const WeekNumberContainer = (props) => (createElement(ViewContextType.Consumer, null, (context) => {
|
7185 | let { dateEnv, options } = context;
|
7186 | let { date } = props;
|
7187 | let format = options.weekNumberFormat || props.defaultFormat;
|
7188 | let num = dateEnv.computeWeekNumber(date);
|
7189 | let text = dateEnv.format(date, format);
|
7190 | let renderProps = { num, text, date };
|
7191 | return (createElement(ContentContainer
|
7192 | , Object.assign({}, props , { renderProps: renderProps, generatorName: "weekNumberContent", customGenerator: options.weekNumberContent, defaultGenerator: renderInner, classNameGenerator: options.weekNumberClassNames, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount })));
|
7193 | }));
|
7194 | function renderInner(innerProps) {
|
7195 | return innerProps.text;
|
7196 | }
|
7197 |
|
7198 | const PADDING_FROM_VIEWPORT = 10;
|
7199 | class Popover extends BaseComponent {
|
7200 | constructor() {
|
7201 | super(...arguments);
|
7202 | this.state = {
|
7203 | titleId: getUniqueDomId(),
|
7204 | };
|
7205 | this.handleRootEl = (el) => {
|
7206 | this.rootEl = el;
|
7207 | if (this.props.elRef) {
|
7208 | setRef(this.props.elRef, el);
|
7209 | }
|
7210 | };
|
7211 |
|
7212 | this.handleDocumentMouseDown = (ev) => {
|
7213 |
|
7214 | const target = getEventTargetViaRoot(ev);
|
7215 | if (!this.rootEl.contains(target)) {
|
7216 | this.handleCloseClick();
|
7217 | }
|
7218 | };
|
7219 | this.handleDocumentKeyDown = (ev) => {
|
7220 | if (ev.key === 'Escape') {
|
7221 | this.handleCloseClick();
|
7222 | }
|
7223 | };
|
7224 | this.handleCloseClick = () => {
|
7225 | let { onClose } = this.props;
|
7226 | if (onClose) {
|
7227 | onClose();
|
7228 | }
|
7229 | };
|
7230 | }
|
7231 | render() {
|
7232 | let { theme, options } = this.context;
|
7233 | let { props, state } = this;
|
7234 | let classNames = [
|
7235 | 'fc-popover',
|
7236 | theme.getClass('popover'),
|
7237 | ].concat(props.extraClassNames || []);
|
7238 | return createPortal(createElement("div", Object.assign({}, props.extraAttrs, { id: props.id, className: classNames.join(' '), "aria-labelledby": state.titleId, ref: this.handleRootEl }),
|
7239 | createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },
|
7240 | createElement("span", { className: "fc-popover-title", id: state.titleId }, props.title),
|
7241 | createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })),
|
7242 | createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl);
|
7243 | }
|
7244 | componentDidMount() {
|
7245 | document.addEventListener('mousedown', this.handleDocumentMouseDown);
|
7246 | document.addEventListener('keydown', this.handleDocumentKeyDown);
|
7247 | this.updateSize();
|
7248 | }
|
7249 | componentWillUnmount() {
|
7250 | document.removeEventListener('mousedown', this.handleDocumentMouseDown);
|
7251 | document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
7252 | }
|
7253 | updateSize() {
|
7254 | let { isRtl } = this.context;
|
7255 | let { alignmentEl, alignGridTop } = this.props;
|
7256 | let { rootEl } = this;
|
7257 | let alignmentRect = computeClippedClientRect(alignmentEl);
|
7258 | if (alignmentRect) {
|
7259 | let popoverDims = rootEl.getBoundingClientRect();
|
7260 |
|
7261 | let popoverTop = alignGridTop
|
7262 | ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top
|
7263 | : alignmentRect.top;
|
7264 | let popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left;
|
7265 |
|
7266 | popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT);
|
7267 | popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width);
|
7268 | popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT);
|
7269 | let origin = rootEl.offsetParent.getBoundingClientRect();
|
7270 | applyStyle(rootEl, {
|
7271 | top: popoverTop - origin.top,
|
7272 | left: popoverLeft - origin.left,
|
7273 | });
|
7274 | }
|
7275 | }
|
7276 | }
|
7277 |
|
7278 | class MorePopover extends DateComponent {
|
7279 | constructor() {
|
7280 | super(...arguments);
|
7281 | this.handleRootEl = (rootEl) => {
|
7282 | this.rootEl = rootEl;
|
7283 | if (rootEl) {
|
7284 | this.context.registerInteractiveComponent(this, {
|
7285 | el: rootEl,
|
7286 | useEventCenter: false,
|
7287 | });
|
7288 | }
|
7289 | else {
|
7290 | this.context.unregisterInteractiveComponent(this);
|
7291 | }
|
7292 | };
|
7293 | }
|
7294 | render() {
|
7295 | let { options, dateEnv } = this.context;
|
7296 | let { props } = this;
|
7297 | let { startDate, todayRange, dateProfile } = props;
|
7298 | let title = dateEnv.format(startDate, options.dayPopoverFormat);
|
7299 | return (createElement(DayCellContainer, { elRef: this.handleRootEl, date: startDate, dateProfile: dateProfile, todayRange: todayRange }, (InnerContent, renderProps, elAttrs) => (createElement(Popover, { elRef: elAttrs.ref, id: props.id, title: title, extraClassNames: ['fc-more-popover'].concat(elAttrs.className || []), extraAttrs: elAttrs , parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose },
|
7300 | hasCustomDayCellContent(options) && (createElement(InnerContent, { elTag: "div", elClasses: ['fc-more-popover-misc'] })),
|
7301 | props.children))));
|
7302 | }
|
7303 | queryHit(positionLeft, positionTop, elWidth, elHeight) {
|
7304 | let { rootEl, props } = this;
|
7305 | if (positionLeft >= 0 && positionLeft < elWidth &&
|
7306 | positionTop >= 0 && positionTop < elHeight) {
|
7307 | return {
|
7308 | dateProfile: props.dateProfile,
|
7309 | dateSpan: Object.assign({ allDay: !props.forceTimed, range: {
|
7310 | start: props.startDate,
|
7311 | end: props.endDate,
|
7312 | } }, props.extraDateSpan),
|
7313 | dayEl: rootEl,
|
7314 | rect: {
|
7315 | left: 0,
|
7316 | top: 0,
|
7317 | right: elWidth,
|
7318 | bottom: elHeight,
|
7319 | },
|
7320 | layer: 1,
|
7321 | };
|
7322 | }
|
7323 | return null;
|
7324 | }
|
7325 | }
|
7326 |
|
7327 | class MoreLinkContainer extends BaseComponent {
|
7328 | constructor() {
|
7329 | super(...arguments);
|
7330 | this.state = {
|
7331 | isPopoverOpen: false,
|
7332 | popoverId: getUniqueDomId(),
|
7333 | };
|
7334 | this.handleLinkEl = (linkEl) => {
|
7335 | this.linkEl = linkEl;
|
7336 | if (this.props.elRef) {
|
7337 | setRef(this.props.elRef, linkEl);
|
7338 | }
|
7339 | };
|
7340 | this.handleClick = (ev) => {
|
7341 | let { props, context } = this;
|
7342 | let { moreLinkClick } = context.options;
|
7343 | let date = computeRange(props).start;
|
7344 | function buildPublicSeg(seg) {
|
7345 | let { def, instance, range } = seg.eventRange;
|
7346 | return {
|
7347 | event: new EventImpl(context, def, instance),
|
7348 | start: context.dateEnv.toDate(range.start),
|
7349 | end: context.dateEnv.toDate(range.end),
|
7350 | isStart: seg.isStart,
|
7351 | isEnd: seg.isEnd,
|
7352 | };
|
7353 | }
|
7354 | if (typeof moreLinkClick === 'function') {
|
7355 | moreLinkClick = moreLinkClick({
|
7356 | date,
|
7357 | allDay: Boolean(props.allDayDate),
|
7358 | allSegs: props.allSegs.map(buildPublicSeg),
|
7359 | hiddenSegs: props.hiddenSegs.map(buildPublicSeg),
|
7360 | jsEvent: ev,
|
7361 | view: context.viewApi,
|
7362 | });
|
7363 | }
|
7364 | if (!moreLinkClick || moreLinkClick === 'popover') {
|
7365 | this.setState({ isPopoverOpen: true });
|
7366 | }
|
7367 | else if (typeof moreLinkClick === 'string') {
|
7368 | context.calendarApi.zoomTo(date, moreLinkClick);
|
7369 | }
|
7370 | };
|
7371 | this.handlePopoverClose = () => {
|
7372 | this.setState({ isPopoverOpen: false });
|
7373 | };
|
7374 | }
|
7375 | render() {
|
7376 | let { props, state } = this;
|
7377 | return (createElement(ViewContextType.Consumer, null, (context) => {
|
7378 | let { viewApi, options, calendarApi } = context;
|
7379 | let { moreLinkText } = options;
|
7380 | let { moreCnt } = props;
|
7381 | let range = computeRange(props);
|
7382 | let text = typeof moreLinkText === 'function'
|
7383 | ? moreLinkText.call(calendarApi, moreCnt)
|
7384 | : `+${moreCnt} ${moreLinkText}`;
|
7385 | let hint = formatWithOrdinals(options.moreLinkHint, [moreCnt], text);
|
7386 | let renderProps = {
|
7387 | num: moreCnt,
|
7388 | shortText: `+${moreCnt}`,
|
7389 | text,
|
7390 | view: viewApi,
|
7391 | };
|
7392 | return (createElement(Fragment, null,
|
7393 | Boolean(props.moreCnt) && (createElement(ContentContainer, { elTag: props.elTag || 'a', elRef: this.handleLinkEl, elClasses: [
|
7394 | ...(props.elClasses || []),
|
7395 | 'fc-more-link',
|
7396 | ], elStyle: props.elStyle, elAttrs: Object.assign(Object.assign(Object.assign({}, props.elAttrs), createAriaClickAttrs(this.handleClick)), { title: hint, 'aria-expanded': state.isPopoverOpen, 'aria-controls': state.isPopoverOpen ? state.popoverId : '' }), renderProps: renderProps, generatorName: "moreLinkContent", customGenerator: options.moreLinkContent, defaultGenerator: props.defaultGenerator || renderMoreLinkInner, classNameGenerator: options.moreLinkClassNames, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, props.children)),
|
7397 | state.isPopoverOpen && (createElement(MorePopover, { id: state.popoverId, startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: this.parentEl, alignmentEl: props.alignmentElRef ?
|
7398 | props.alignmentElRef.current :
|
7399 | this.linkEl, alignGridTop: props.alignGridTop, forceTimed: props.forceTimed, onClose: this.handlePopoverClose }, props.popoverContent()))));
|
7400 | }));
|
7401 | }
|
7402 | componentDidMount() {
|
7403 | this.updateParentEl();
|
7404 | }
|
7405 | componentDidUpdate() {
|
7406 | this.updateParentEl();
|
7407 | }
|
7408 | updateParentEl() {
|
7409 | if (this.linkEl) {
|
7410 | this.parentEl = elementClosest(this.linkEl, '.fc-view-harness');
|
7411 | }
|
7412 | }
|
7413 | }
|
7414 | function renderMoreLinkInner(props) {
|
7415 | return props.text;
|
7416 | }
|
7417 | function computeRange(props) {
|
7418 | if (props.allDayDate) {
|
7419 | return {
|
7420 | start: props.allDayDate,
|
7421 | end: addDays(props.allDayDate, 1),
|
7422 | };
|
7423 | }
|
7424 | let { hiddenSegs } = props;
|
7425 | return {
|
7426 | start: computeEarliestSegStart(hiddenSegs),
|
7427 | end: computeLatestSegEnd(hiddenSegs),
|
7428 | };
|
7429 | }
|
7430 | function computeEarliestSegStart(segs) {
|
7431 | return segs.reduce(pickEarliestStart).eventRange.range.start;
|
7432 | }
|
7433 | function pickEarliestStart(seg0, seg1) {
|
7434 | return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1;
|
7435 | }
|
7436 | function computeLatestSegEnd(segs) {
|
7437 | return segs.reduce(pickLatestEnd).eventRange.range.end;
|
7438 | }
|
7439 | function pickLatestEnd(seg0, seg1) {
|
7440 | return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1;
|
7441 | }
|
7442 |
|
7443 | class Store {
|
7444 | constructor() {
|
7445 | this.handlers = [];
|
7446 | }
|
7447 | set(value) {
|
7448 | this.currentValue = value;
|
7449 | for (let handler of this.handlers) {
|
7450 | handler(value);
|
7451 | }
|
7452 | }
|
7453 | subscribe(handler) {
|
7454 | this.handlers.push(handler);
|
7455 | if (this.currentValue !== undefined) {
|
7456 | handler(this.currentValue);
|
7457 | }
|
7458 | }
|
7459 | }
|
7460 |
|
7461 |
|
7462 |
|
7463 |
|
7464 | class CustomRenderingStore extends Store {
|
7465 | constructor() {
|
7466 | super(...arguments);
|
7467 | this.map = new Map();
|
7468 | }
|
7469 |
|
7470 | handle(customRendering) {
|
7471 | const { map } = this;
|
7472 | let updated = false;
|
7473 | if (customRendering.isActive) {
|
7474 | map.set(customRendering.id, customRendering);
|
7475 | updated = true;
|
7476 | }
|
7477 | else if (map.has(customRendering.id)) {
|
7478 | map.delete(customRendering.id);
|
7479 | updated = true;
|
7480 | }
|
7481 | if (updated) {
|
7482 | this.set(map);
|
7483 | }
|
7484 | }
|
7485 | }
|
7486 |
|
7487 | export { elementClosest as $, memoizeObjArg as A, BaseComponent as B, ContentContainer as C, DelayedRunner as D, isPropsEqual as E, Emitter as F, getInitialDate as G, rangeContainsMarker as H, createEmptyEventStore as I, reduceCurrentDate as J, reduceEventStore as K, rezoneEventStoreDates as L, mergeRawOptions as M, BASE_OPTION_REFINERS as N, CALENDAR_LISTENER_REFINERS as O, CALENDAR_OPTION_REFINERS as P, COMPLEX_OPTION_COMPARATORS as Q, VIEW_OPTION_REFINERS as R, DateEnv as S, Theme as T, DateProfileGenerator as U, ViewContextType as V, createEventUi as W, parseBusinessHours as X, setRef as Y, Interaction as Z, getElSeg as _, mapHash as a, getSlotClassNames as a$, EventImpl as a0, listenBySelector as a1, listenToHoverBySelector as a2, PureComponent as a3, buildViewContext as a4, getUniqueDomId as a5, parseInteractionSettings as a6, interactionSettingsStore as a7, getNow as a8, CalendarImpl as a9, diffDates as aA, removeExact as aB, memoizeArraylike as aC, memoizeHashlike as aD, intersectRects as aE, pointInsideRect as aF, constrainPoint as aG, getRectCenter as aH, diffPoints as aI, translateRect as aJ, compareObjs as aK, collectFromHash as aL, findElements as aM, findDirectChildren as aN, removeElement as aO, applyStyle as aP, elementMatches as aQ, getEventTargetViaRoot as aR, parseClassNames as aS, getCanVGrowWithinCell as aT, mergeEventStores as aU, getRelevantEvents as aV, eventTupleToStore as aW, combineEventUis as aX, Splitter as aY, getDayClassNames as aZ, getDateMeta as a_, flushSync as aa, CalendarRoot as ab, RenderId as ac, ensureElHasStyles as ad, applyStyleProp as ae, sliceEventStore as af, JsonRequestError as ag, createContext as ah, refineProps as ai, createEventInstance as aj, parseEventDef as ak, refineEventDef as al, padStart as am, isInt as an, parseFieldSpecs as ao, compareByFieldSpecs as ap, flexibleCompare as aq, preventSelection as ar, allowSelection as as, preventContextMenu as at, allowContextMenu as au, compareNumbers as av, enableCursor as aw, disableCursor as ax, computeVisibleDayRange as ay, isMultiDayRange as az, buildViewClassNames as b, SimpleScrollGrid as b$, buildNavLinkAttrs as b0, preventDefault as b1, whenTransitionDone as b2, computeInnerRect as b3, computeEdges as b4, getClippingParents as b5, computeRect as b6, rangesEqual as b7, rangesIntersect as b8, rangeContainsRange as b9, SegHierarchy as bA, buildEntryKey as bB, getEntrySpanEnd as bC, binarySearch as bD, groupIntersectingEntries as bE, intersectSpans as bF, interactionSettingsToStore as bG, ElementDragging as bH, config as bI, parseDragMeta as bJ, DayHeader as bK, computeFallbackHeaderFormat as bL, TableDateCell as bM, TableDowCell as bN, DaySeriesModel as bO, hasBgRendering as bP, buildSegTimeText as bQ, sortEventSegs as bR, getSegMeta as bS, buildEventRangeKey as bT, getSegAnchorAttrs as bU, DayTableModel as bV, Slicer as bW, applyMutationToEventStore as bX, isPropsValid as bY, isInteractionValid as bZ, isDateSelectionValid as b_, PositionCache as ba, ScrollController as bb, ElementScrollController as bc, WindowScrollController as bd, DateComponent as be, isDateSpansEqual as bf, addMs as bg, addWeeks as bh, diffWeeks as bi, diffWholeWeeks as bj, diffDayAndTime as bk, diffDays as bl, isValidDate as bm, asCleanDays as bn, multiplyDuration as bo, addDurations as bp, asRoughMinutes as bq, asRoughSeconds as br, asRoughMs as bs, wholeDivideDurations as bt, formatIsoTimeString as bu, formatDayString as bv, buildIsoString as bw, formatIsoMonthStr as bx, NamedTimeZoneImpl as by, parse as bz, greatestDurationDenominator as c, hasShrinkWidth as c0, renderMicroColGroup as c1, getScrollGridClassNames as c2, getSectionClassNames as c3, getSectionHasLiquidHeight as c4, getAllowYScrolling as c5, renderChunkContent as c6, computeShrinkWidth as c7, sanitizeShrinkWidth as c8, isColPropsEqual as c9, renderScrollShim as ca, getStickyFooterScrollbar as cb, getStickyHeaderDates as cc, Scroller as cd, getScrollbarWidths as ce, RefMap as cf, getIsRtlScrollbarOnLeft as cg, NowTimer as ch, ScrollResponder as ci, StandardEvent as cj, NowIndicatorContainer as ck, DayCellContainer as cl, hasCustomDayCellContent as cm, EventContainer as cn, renderFill as co, BgEvent as cp, WeekNumberContainer as cq, MoreLinkContainer as cr, computeEarliestSegStart as cs, ViewContainer as ct, triggerDateSelect as cu, getDefaultEventEnd as cv, injectStyles as cw, buildElAttrs as cx, CustomRenderingStore as cy, createDuration as d, BASE_OPTION_DEFAULTS as e, arrayToHash as f, guid as g, filterHash as h, isArraysEqual as i, buildEventSourceRefiners as j, formatWithOrdinals as k, buildRangeApiWithTimeZone as l, mergeProps as m, identity as n, intersectRanges as o, parseEventSource as p, startOfDay as q, requestJson as r, subtractDurations as s, addDays as t, unpromisify as u, hashValuesToArray as v, buildEventApis as w, createFormatter as x, diffWholeDays as y, memoize as z };
|